当前位置: 首页 > news >正文

高级mask应用

高级mask应用

用mask做遮罩可以实现复杂的效果:

用来形成遮罩的图片:

原始图片:

如果你熟悉Photoshop,那这种效果绝对是你的菜,看代码你会秒懂......

//
//  RootViewController.m
//  ShapeMask
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "UIImage+ImageEffects.h"

@interface RootViewController ()

@property (nonatomic, strong) CALayer *movedMask;

@end

@implementation RootViewController

- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
    // 拖拽
    CGPoint translation = [recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                         recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    
    // 关闭CoreAnimation实时动画绘制(核心)
    [CATransaction setDisableActions:YES];
    _movedMask.position = recognizer.view.center;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blackColor];

    // 背景图片与mask图片
    UIImage *bgImage = [UIImage imageNamed:@"bg"];
    UIImage *image = [UIImage imageNamed:@"mask"];
    
    // 背景图片显示
    UIImageView *bgImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    bgImageView.image = [bgImage grayScale];
    [self.view addSubview:bgImageView];
    
    // 遮罩背景图片显示
    UIImageView *bgChangedImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    bgChangedImageView.image = bgImage;
    [self.view addSubview:bgChangedImageView];
    
    // 形成遮罩
    _movedMask          = [CALayer layer];
    _movedMask.frame    = (CGRect){CGPointZero, image.size};
    _movedMask.contents = (__bridge id)(image.CGImage);
    _movedMask.position = self.view.center;
    bgChangedImageView.layer.mask = _movedMask;
    
    // 拖拽的View
    UIView *dragView = [[UIView alloc] initWithFrame:(CGRect){CGPointZero, image.size}];
    dragView.center = self.view.center;
    [self.view addSubview:dragView];
    
    // 给dragView添加拖拽手势
    UIPanGestureRecognizer *recognizer = \
    [[UIPanGestureRecognizer alloc] initWithTarget:self
                                            action:@selector(handlePan:)];
    [dragView addGestureRecognizer:recognizer];
}

@end

要点:

你可以直接使用带透明像素的PNG图片来制作复杂的mask,相对于CAShapeLayer绘制路径来做mask,此种方式更简单暴力高效.

 

附录:

配合CAEmitterLayer使用,可以实现非常非常绚丽复杂的动画效果,绝对高大上:)

//
//  RootViewController.m
//  ShapeMask
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "UIImage+ImageEffects.h"

@interface RootViewController ()

@property (nonatomic, strong) CALayer *movedMask;

@end

@implementation RootViewController

- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
    // 拖拽
    CGPoint translation = [recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                         recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    
    // 关闭CoreAnimation实时动画绘制(核心)
    [CATransaction setDisableActions:YES];
    _movedMask.position = recognizer.view.center;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blackColor];

    // 创建粒子Layer
    CAEmitterLayer *snowEmitter = [CAEmitterLayer layer];
    
    // 粒子发射位置
    snowEmitter.emitterPosition = CGPointMake(120,0);
    
    // 发射源的尺寸大小
    snowEmitter.emitterSize = self.view.bounds.size;
    
    // 发射模式
    snowEmitter.emitterMode = kCAEmitterLayerSurface;
    
    // 发射源的形状
    snowEmitter.emitterShape = kCAEmitterLayerLine;
    
    // 创建雪花类型的粒子
    CAEmitterCell *snowflake = [CAEmitterCell emitterCell];
    
    // 粒子的名字
    snowflake.name = @"snow";
    
    // 粒子参数的速度乘数因子
    snowflake.birthRate = 20.0;
    snowflake.lifetime = 120.0;
    
    // 粒子速度
    snowflake.velocity =10.0;
    
    // 粒子的速度范围
    snowflake.velocityRange = 10;
    
    // 粒子y方向的加速度分量
    snowflake.yAcceleration = 2;
    
    // 周围发射角度
    snowflake.emissionRange = 0.5 * M_PI;
    
    // 子旋转角度范围
    snowflake.spinRange = 0.25 * M_PI;
    snowflake.contents = (id)[[UIImage imageNamed:@"snow"] CGImage];
    
    // 设置雪花形状的粒子的颜色
    snowflake.color = [[UIColor whiteColor] CGColor];
    
    snowflake.scaleRange = 0.6f;
    snowflake.scale = 0.7f;
    
    snowEmitter.shadowOpacity = 1.0;
    snowEmitter.shadowRadius = 0.0;
    snowEmitter.shadowOffset = CGSizeMake(0.0, 0.0);
    
    // 粒子边缘的颜色
    snowEmitter.shadowColor = [[UIColor whiteColor] CGColor];
    
    // 添加粒子
    snowEmitter.emitterCells = @[snowflake];
    
    // 将粒子Layer添加进图层中
    [self.view.layer addSublayer:snowEmitter];
    
    // 形成遮罩
    UIImage *image = [UIImage imageNamed:@"mask"];
    _movedMask          = [CALayer layer];
    _movedMask.frame    = (CGRect){CGPointZero, image.size};
    _movedMask.contents = (__bridge id)(image.CGImage);
    _movedMask.position = self.view.center;
    snowEmitter.mask = _movedMask;
    
    // 拖拽的View
    UIView *dragView = [[UIView alloc] initWithFrame:(CGRect){CGPointZero, image.size}];
    dragView.center = self.view.center;
    [self.view addSubview:dragView];
    
    // 给dragView添加拖拽手势
    UIPanGestureRecognizer *recognizer = \
    [[UIPanGestureRecognizer alloc] initWithTarget:self
                                            action:@selector(handlePan:)];
    [dragView addGestureRecognizer:recognizer];
}

@end

 

 

 

 

 

转载于:https://www.cnblogs.com/YouXianMing/p/3788270.html

相关文章:

  • 义隆单片机学习笔记之(四) 编程及烧录
  • ASP.NET MD5加密
  • topcoder SRM 618 DIV2 MovingRooksDiv2
  • 微信公众号自定义菜单与回车
  • 协议分析-迅雷镜象服务器下载
  • 一个硬件高手的设计经验分享
  • log4j 将日志记录到数据库
  • 如何用笔记本组建家庭点歌系统
  • 什么是大数据?
  • 动态注册BroadcastReceiver
  • ASP.NET怎么防止多次点击提交按钮重复提交
  • @html.ActionLink的几种参数格式
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息
  • HTML中Select的使用具体解释
  • 使用Spring整合javaMail发用邮件
  • 【391天】每日项目总结系列128(2018.03.03)
  • CAP 一致性协议及应用解析
  • CSS 三角实现
  • E-HPC支持多队列管理和自动伸缩
  • JavaScript-Array类型
  • js面向对象
  • oldjun 检测网站的经验
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Vue学习第二天
  • 电商搜索引擎的架构设计和性能优化
  • 给初学者:JavaScript 中数组操作注意点
  • 简单基于spring的redis配置(单机和集群模式)
  • 来,膜拜下android roadmap,强大的执行力
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • (3)选择元素——(17)练习(Exercises)
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (二)丶RabbitMQ的六大核心
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (简单) HDU 2612 Find a way,BFS。
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (转)平衡树
  • .bat文件调用java类的main方法
  • .net core 依赖注入的基本用发
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET简谈设计模式之(单件模式)
  • .net连接MySQL的方法
  • .net中生成excel后调整宽度
  • @Query中countQuery的介绍
  • @开发者,一文搞懂什么是 C# 计时器!
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术