CAShapeLayer & UIBezierPath & CABasicAnimation

CAShapeLayer

普通CALayer在被初始化时是需要给一个frame值的,这个frame值一般都与给定view的bounds值一致,它本身是有形状的,而且是矩形.
每个CAShapeLayer对象都代表着将要被渲染到屏幕上的形状(shape),CAShapeLayer在初始化时也需要给一个frame值,但是,它本身没有形状,它的形状来源于你给定的一个path,然后它去取CGPath值,它与CALayer有着很大的区别.

并且,系统仅会渲染CAShapeLayer对象的形状,其他任何非CAShapeLayer的自由属性在渲染是都会被忽略。因此从某种意义上讲CAShapeLayer仅是形状的容器。虽然由于其实CALayer的子类,可以设置contentsbackgroundColor等属性,但这些属性在渲染时也会被忽略。

- 但是,CAShapeLayer提供了自身的可设置性:

path fillColor fillRule strokeColor
strokeStart strokeEnd lineWidth miterLimit
lineCap lineJoin lineDashPhase lineDashPattern
  • path
    动画路径,默认为NULL,不支持隐式动画。路径可以使用任何的具体子类的动画CAPropertyAnimation。如果此属性的值是不为NULL,则path使用指定的路径,而不是创建该层的合成后的alpha通道。它使用的是非零缠绕规则和当前颜色,不透明度和模糊半径填充。

  • fillColor
    填充颜色,默认为不透明的黑色,若值为nil,则没有填充效果。
    fillColor针对于闭合的图形,对于镂空图形只需设置画笔颜色strokeColor即可。

//闭合多边形
- (void)drawTriangle {
    UIView *view = [self.view viewWithTag:1026];
    
    CAShapeLayer *triangle = [CAShapeLayer layer];
    triangle.lineWidth = 2;
    triangle.strokeColor = [UIColor clearColor].CGColor;
    triangle.fillColor = [UIColor redColor].CGColor;
    [view.layer addSublayer:triangle];
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:CGPointMake(kDeviceWidth/2.0, 50)];
    [bezierPath addLineToPoint:CGPointMake(kDeviceWidth/2.0-100, 150)];
    [bezierPath addLineToPoint:CGPointMake(kDeviceWidth/2.0+100, 150)];
    [bezierPath addLineToPoint:CGPointMake(kDeviceWidth/2.0, 50)];
    
    triangle.path = bezierPath.CGPath;
}
fillColor和strokeColor两种设置的效果
  • fillRule
    填充规则,默认是kCAFillRuleNonZero。
    kCAFillRuleNonZero:指定非零缠绕规则。计算每个左到右的路径+1或-1为每个从右到左的道路。如果所有交叉的总和为0,则点是路径之外,如果该和为非零,改点是在路径内与包含它的区域被填充。
    kCAFillRuleEvenOdd:指定奇偶缠绕规则。算路径交叉的总和,如果横跨的数目是偶数,改点在路径之外。如果横跨的数目是奇数,所述点是在路径内与包含它的区域应被填充。

  • strokeColor
    画笔颜色。

  • strokeStart
    和strokeEnd组合使用,默认值为1.0,取值范围0.0~1.0

  • strokeEnd
    和strokeStart组合使用,默认值为1.0,取值范围为0.0~1.0

  • lineWidth
    线宽。注意线宽有一个特点,线宽从你设置的起点往左右两边同时伸展。

  • miterLimit
    斜接样式,默认值为10.0

  • lineCap
    线端点样式,默认值为kCALineCapButt,还有kCALineCapRound,kCALineCapSquare


    线端点样式示例
  • lineJoin
    拐角样式,默认值为kCALineJoinMiter(尖角),还有kCALineJoinRound(圆角),kCALineJoinBevel(平角)


    拐角样式示例
  • lineDashPhase
    冲刺阶段应用到的形状的路径,默认是0.0

  • lineDashPattern
    设置线的样式,默认为实线,该数组为一个NSNumber数组,数组中的数值依次表示虚线中,单个线的长度,和空白的长度,如:数组@[@10,@5] 表示 有长度为10的线,长度为5的空白,不断循环后组成的虚线。
    当然数组的长度是不做限制的,你亦可以@[@2,@3,@4,@5],可以表示为长度为2的线+长度为3的空白+长度为4的线+长度为5的空白,不断循环直到线段结束。

  • mask
    mask本身就是个CALayer,mask属性用作裁剪功能。
    mask只作为形状(shape)的样子,裁剪后的形状以mask为准,其他例如颜色等属性以原图为准。


    两种mask裁剪示例

- CAShapeLayer有以下几点特点:

  • 它依附于一个path,必须给予path,即使path不完整也会自动首尾相接。
  • strokeStartstrokeEnd代表着在这个path中所占用的百分比。
  • CAShapeLayer动画仅限于沿着边缘的动画效果,它不能直接实现填充效果,但可以间接实现填充效果。

UIBezierPath

使用UIBezierPath可以创建基于矢量的路径,此类是Core Graphics框架关于路径的封装。使用此类可以定义简单的形状,如椭圆、矩形或有多个直线和曲线组成的形状等。

UIBezierPathCGPathRef数据类型的封装。如果是基于矢量形状的路径,都用直线或曲线去创建。我们使用直线段去创建矩形和多边形,使用曲线去创建圆弧、圆或其他复杂的曲线形状。

  • 最基本的初始化方法,用它创建的对象,我们可以根据我们的需要任意定制样式,可以话任何想画的图形。
+ (instancetype)bezierPath;
  • 初始化一个矩形矩形贝塞尔曲线。
+ (instancetype)bezierPathWithRect:(CGRect)rect;
  • 根据一个矩形画内切曲线,通常用来画圆或椭圆(取决于传入的rect是正方形还是长方形)。
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
  • 画矩形,但是这个矩形可以画圆角。第一个参数是矩形,第二个参数是圆角大小。
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;
  • 画矩形,矩形可以圆角,可以指定某个角或其中多个角成为圆角。参数:UIRectCornerTopLeftUIRectCornerTopRightUIRectCornerBottomLeftUIRectCornerBottomRightUIRectCornerAllCorners
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
  • 画弧线,参数说明:
    • center 弧线中心点的坐标
    • radius 弧线所在圆的半径
    • startAngle 弧线开始的角度值
    • endAngle 弧线结束的角度值
    • clockwise 是否顺时针画弧线
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;

CABasicAnimation

CABasicAnimation类的使用方式就是关键帧动画,所谓关键帧动画,就是将Layer的属性作为keyPath来注册,指定动画的起始帧和结束帧,然后自动计算和实现中间的过渡动画的一种动画方式。

CABasicAnimation自己只有三个property:

@property(nullable, strong) id fromValue;
@property(nullable, strong) id toValue;
@property(nullable, strong) id byValue

当创建一个CABasicAnimation的时候,需要通过 -setFromValue-setToValue 来指定一个开始值和结束值。当你增加基础动画到层中的时候,它开始运行。当用属性做动画完成时,例如用位置属性做动画,层就会立刻返回到它的初始位置。

- 设定动画的属性说明

属性 说明
duration 动画时长(单位:秒)
repeatCount 重复次数,永久重复的话设置为HUGE_VALF
beginTime 指定动画开始时间。从开始指定延迟几秒执行的话,请设置为「CACurrentMediaTime() + 秒数」的形式
timingFunction 设定动画的速度变化
autoreverses 动画结束时是否执行逆动画
shadowColor 阴影的颜色
shadowOffset 阴影的偏移量
shadowOpacity 阴影的透明度
shadowRadius 阴影的圆角
fromValue 所改变属性的起始值
toValue 所改变属性的结束时的值
byValue 所改变属性相同起始值得改变量 ;

- 常用的animationWithKeyPath值的总结

说明 使用形式
transform.scale 比例转化 @(0.8)
transform.scale.x 宽的比例 @(0.8)
transform.scale.y 高的比例 @(0.8)
transform.rotation.x 围绕x轴旋转 @(M_PI)
transform.rotation.y 围绕y轴旋转 @(M_PI)
transform.rotation.z 围绕z轴旋转 @(M_PI)
cornerRadius 圆角的设置 @(20)
backgroundColor 背景颜色的变化 [UIColor orangeColor].CGColor;
bounds 大小,中心不变 [NSValue valueWithCGRect:CGRectMake(100,100)];
position 位置(中心点的改变) [NSValue valueWithCGPoint:CGPointMake(100,100)];
contents 内容(比如UIImageView的图片) imageAnima.toValue = (id)[UIImage imageNamed:@“toIcon”].CGImage;
opacity 透明度 @(0.8)
contentsRect.size.width 横向拉伸缩放 @(0.5)最好在0~1之间
- 捕获动画开始时和终了时的事件

设置委托对象,实现委托方法。

/** 
 * 动画开始时 
 */
- (void)animationDidStart:(CAAnimation *)theAnimation {
    NSLog(@"begin");  
}  
   
/** 
 * 动画结束时 
 */  
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {  
    NSLog(@"end");  
}  

结语

CAShapeLayerUIBezierPath规定一个形状,CABasicAnimation为其添加动画。下一篇我将写具体的实例。最后,非常感谢您阅读本文。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,825评论 4 377
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,887评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,425评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,801评论 0 224
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,252评论 3 299
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,089评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,216评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 31,005评论 0 215
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,747评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,883评论 2 255
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,354评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,694评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,406评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,222评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,242评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,017评论 2 281

推荐阅读更多精彩内容