github上又看到个不错的动画(https://github.com/rounak/RJImageLoader),如图:
所以就想来自己实现以下
不试不知道,这个动画还真不是看上去那么简单,我自己想了半天愣是没做出来,最后还是看了作者的代码,才知道怎么实现。
不过也从作者哪儿学了一招,就是layer.mask的用法。
自己实现的效果如图:
(前面的画圆的动画,这是一个CAShaperLayer修改其strokeEnd的动画,比较简单,就没有再写了)
 
 
 
这个动画说难也不难,其关键就在于对layer.mask的特性的运用,如果你不知道layer.mask的特性,那实现起来就相当困难了;相反,如果知道,那思路就豁然开朗了。
关键就是这个:
 
 /* A layer whose alpha channel is used as a mask to select between the
 * layer's background and the result of compositing the layer's
 * contents with its filtered background. Defaults to nil. When used as
 * a mask the layer's `compositingFilter' and `backgroundFilters'
 * properties are ignored. When setting the mask to a new layer, the
 * new layer must have a nil superlayer, otherwise the behavior is
 * undefined. Nested masks (mask layers with their own masks) are
 * unsupported. */
@property(strong) CALayer *mask;
 
mask属性,可以实现很多形状的遮罩,其基本效果是:
比如layerA是layerB的mask,即layerB.mask = layerA;
那么layerA上透明的部分,会被绘制成白色挡住layerB(貌似都是白色,不知道能不能弄成其他颜色);
layerA上不透明的部分,会被绘制成透明,显示出layerB的内容。
 

2015-09-07更新
之前理解错误,mask不是遮罩,不是add到layer上的另一个layer,而是控制layer本身渲染的一个layer。
效果是:比如imageLayer有一个maskLayer作为mask(注意maskLayer可以不跟imageLayer大小一样),
那maskLayer透明的地方,imageLayer就不会渲染,而是变透明,显示出imageLayer之后的内容,
maskLayer不透明的地方,imageLayer就会正常渲染,显示出imageLayer本来的内容
如果maskLayer比imageLayer要小,那默认的maskLayer之外的地方都是透明的,都不会渲染。
 
注意:作为mask的layer不能有superLayer或者subLayer!
 
知道了这个,动画的思路就有了:
imageView上有个遮罩,遮罩透明的部分逐渐变大,向外向内同时扩展,使遮罩后面的图片爆料出来。
 
这里首先需要一个圆形的CAShapeLayer,还需要两个动画,使这个layer同时向内向外扩展。
那么问题来了,只有一个layer,还不能有subLayer,怎么让它同时又变大又变小呢?
答案是:换个方式。
 
 
注意CAShapeLayer是线画出来,线也有颜色,还有宽度是 lineWidth,而且这些属性也是可以动画的。
所以最终的方案是:设置圆的线的颜色为透明,圆的填充色为不透明,园外的颜色不透明(这里的设置指的是看到的效果),让圆逐渐变大到可以显示出整个view,同时让圆的lineWidth逐渐变宽到圆的半径那么大。
看到的效果就是图片像上面的效果一样逐渐显露出来了。
 
核心动画代码如下:
- (void)reveal {
    self.backgroundColor = [UIColor clearColor];
    [self.circleLayer removeFromSuperlayer];//理论上作为mask的layer不能有父layer,所以要remove掉
    self.superview.layer.mask = self.circleLayer;
   
    //让圆的变大的动画
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
    UIBezierPath *toPath = [self pathWithDiameter:self.bigDiameter];
    //    UIBezierPath *toPath = [self pathWithDiameter:0];//缩小当前path的动画
    pathAnimation.toValue = (id)toPath.CGPath;
    pathAnimation.duration = 1.0;
 
   
    //让圆的线的宽度变大的动画,效果是内圆变小
    CABasicAnimation *lineWidthAnimation = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(lineWidth))];
    lineWidthAnimation.toValue = @(self.bigDiameter);
    lineWidthAnimation.duration = 1.0;
   
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[pathAnimation, lineWidthAnimation];
    group.duration = 1.0;
    group.removedOnCompletion = NO;//这两句的效果是让动画结束后不会回到原处,必须加
    group.fillMode = kCAFillModeForwards;//这两句的效果是让动画结束后不会回到原处,必须加
    group.delegate = self;
   
    [self.circleLayer addAnimation:group forKey:@"revealAnimation"];
}
 
/**
 *  根据直径生成圆的path,注意圆点是self的中心点,所以(x,y)不是(0,0)
 */
- (UIBezierPath *)pathWithDiameter:(CGFloat)diameter {
    return [UIBezierPath bezierPathWithOvalInRect:CGRectMake((CGRectGetWidth(self.bounds) - diameter) / 2, (CGRectGetHeight(self.bounds) - diameter) / 2, diameter, diameter)];
}

#pragma mark - CAAnimationDelegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    self.superview.layer.mask = nil;
    [self removeFromSuperview];
}

#pragma mark - property

- (CAShapeLayer *)circleLayer {
    if (!_circleLayer) {
        _circleLayer = [CAShapeLayer layer];
        _circleLayer.fillColor = [UIColor clearColor].CGColor;//这个必须透明,因为这样内圆才是不透明的
        _circleLayer.strokeColor = [UIColor yellowColor].CGColor;//注意这个必须不能透明,因为实际上是这个显示出后面的图片了
        _circleLayer.path = [self pathWithDiameter:self.smallDiameter].CGPath;
    }
    return _circleLayer;

}
 
有什么错误欢迎批评指正 
 

利用layer的mask属性实现逐渐揭示的动画效果的更多相关文章

  1. [Java]利用javax.swing.Timer类在窗口上实现动画效果

    javax.swing.Timer类在创建时需要指定时间间隔和定时器到时间需要执行的动作,即ActionListener. Timer timer = new Timer(100, taskPerfo ...

  2. 利用图层的mask属性裁剪图形

    需求如上图. 代码如下 //充值 UIButton *rechargeButton = [[UIButton alloc] initWithFrame:CGRectMake(, , , )]; [re ...

  3. 利用tween,使用原生js实现模块回弹动画效果

    最近有一个需求,就是当屏幕往下一定像素时,下方会有一个隐藏的模块马上显现出来,向上运动后带有回弹效果.然后屏幕滚回去时这个模块能够原路返回 其实这个效果css3就可以很轻松实现,但是公司要求最低兼容i ...

  4. 通过CSS3属性值的变化实现动画效果+触发这些动画产生交互

    css3过渡 transition 兼容性:IE10+ transition: none | all | property 默认为none all 表示所有属性过渡 property 指定属性值,如c ...

  5. iOS开发——UI篇&文字渐变效果:图层中的mask属性

    文字渐变效果:图层中的mask属性 本次文章,主要讲述的是图层中的mask属性,利用它,可以做出文字渐变效果! 一.文字渐变效果: 二.文字渐变实现思路: 1.创建一个颜色渐变层,渐变图层跟文字控件一 ...

  6. 文字渐变效果:图层中的mask属性

    http://www.cocoachina.com/ios/20150716/12571.html 前言 已经很久没写blog了,最近发生了太多事情,失去了生命中一位很重要的成员,使我不得不放下对技术 ...

  7. 如果需要将UIView的4个角全部都为圆角,做法相当简单,只需设置其Layer的cornerRadius属性即可

    如果需要将UIView的4个角全部都为圆角,做法相当简单,只需设置其Layer的cornerRadius属性即可(项目需要使用QuartzCore框架).而若要指定某几个角(小于4)为圆角而别的不变时 ...

  8. iOS—Mask属性的使用

    Mask属性介绍 Mask平时用的最多的是masksToBounds 吧. 其实除此以外Mask使用场景很多,看完之后你会发现好真是好用的不要不要的... 先来了解下Mask属性到底是什么? Mask ...

  9. Unity 摄像机Clear Flags和Culling Mask属性用途详解

    原文地址:http://blog.csdn.net/tanmengwen/article/details/8798231 1.简述两个属性 1.1 Clear Flags 清除标记 每个相机在渲染时会 ...

随机推荐

  1. 传智播客--ADO.net--SqlBulkCopy批量插入数据(小白必知)

    一般情况下,我们在向数据库中插入数据时用Insert语句,但是当数据量很大的时候,这种情况就比较缓慢了,这个时候就需要SqlBulkCopy这个类. SqlBulkCopy本身常用的函数有这么几个 D ...

  2. 利用angular结合translate为项目实现国际化

    前言 利用H5项目第一版本已经上线,话说有了第一期就有了第二期,这不要为第二期做准备了,老大发话第一件事就要利用Angular JS实现项目的国际化以及后续要借助这个框架来实现其他功能,好吧我表示没怎 ...

  3. DOM扩展-HTML5、专有扩展

     HTML5 与类相关的扩充 1.getElementsByClassName()方法 改方法接受一个参数,即一个包含一或多个类名的字符串,返回带有指定类的所有元素的NodeList.传入多个类型时, ...

  4. Redis碎碎念

    1. 关于Cluster cluster_known_nodes:4 cluster_size:3 说明集群中总共有4个节点:集群的size是3,相当于3个主节点参与了槽位分配 2. 如何查看key的 ...

  5. T-Sql学习系列完结

    T-Sql(一)简单语法 T-Sql(二)事务(Transaction) T-Sql(三)存储过程(Procedure) T-Sql(四)表关联和视图(view) T-Sql(五)xml操作 T-Sq ...

  6. Web接口测试工具---Poster与Postman

    工作当中有不少时间在编写和维护接口自动化测试用例.打算先整理一些接口相关工具的使用. 简单对接Web口测试的相关工具/技术做个划分. HTTP/SOAP协议接口的功能测试: 1.浏览器URL(GET请 ...

  7. Cesium原理篇:6 Render模块(3: Shader)

    在介绍Renderer的第一篇,我就提到WebGL1.0对应的是OpenGL ES2.0,也就是可编程渲染管线.之所以单独强调这一点,算是为本篇埋下一个伏笔.通过前两篇,我们介绍了VBO和Textur ...

  8. SQL Server在哪里存放DMV的数据?

    我被反复问到的一个问题是,通过各个DMV和DMF返回的数据,SQL Server在哪里存放? 很多人认为这类数据会存放在像mater这样的系统数据库里.但事实并非如此.各个系统数据库(master和m ...

  9. 内存中OLTP与内存不足

    我已经写了好几次内存中OLTP的文章和”为什么我还不推荐内存中OLTP给用户”.今天我想进一步谈下内存中OLTP背后的内存需求,还有如果你内存不够的话会发生什么. 一切都与内存有关! 我们都知道很久之 ...

  10. System.Security.Cryptography.CryptographicException,密钥集不存在

    非常感谢,已经解决了.是当前用户没有权限访问证书的私钥文件的问题,之前尝试去解决,但是在对:C:\Documents and Settings\All Users\Application Data\M ...