CAShapeLayer
普通CALayer
在被初始化时是需要给一个frame值的,这个frame值一般都与给定view的bounds值一致,它本身是有形状的,而且是矩形.
每个CAShapeLayer
对象都代表着将要被渲染到屏幕上的形状(shape),CAShapeLayer在初始化时也需要给一个frame值,但是,它本身没有形状,它的形状来源于你给定的一个path,然后它去取CGPath
值,它与CALayer有着很大的区别.
并且,系统仅会渲染CAShapeLayer对象的形状,其他任何非CAShapeLayer的自由属性在渲染是都会被忽略。因此从某种意义上讲CAShapeLayer仅是形状的容器。虽然由于其实CALayer的子类,可以设置contents
、backgroundColor
等属性,但这些属性在渲染时也会被忽略。
- 但是,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不完整也会自动首尾相接。 -
strokeStart
及strokeEnd
代表着在这个path中所占用的百分比。 - CAShapeLayer动画仅限于沿着边缘的动画效果,它不能直接实现填充效果,但可以间接实现填充效果。
UIBezierPath
使用UIBezierPath
可以创建基于矢量的路径,此类是Core Graphics
框架关于路径的封装。使用此类可以定义简单的形状,如椭圆、矩形或有多个直线和曲线组成的形状等。
UIBezierPath
是CGPathRef
数据类型的封装。如果是基于矢量形状的路径,都用直线或曲线去创建。我们使用直线段去创建矩形和多边形,使用曲线去创建圆弧、圆或其他复杂的曲线形状。
- 最基本的初始化方法,用它创建的对象,我们可以根据我们的需要任意定制样式,可以话任何想画的图形。
+ (instancetype)bezierPath;
- 初始化一个矩形矩形贝塞尔曲线。
+ (instancetype)bezierPathWithRect:(CGRect)rect;
- 根据一个矩形画内切曲线,通常用来画圆或椭圆(取决于传入的rect是正方形还是长方形)。
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
- 画矩形,但是这个矩形可以画圆角。第一个参数是矩形,第二个参数是圆角大小。
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;
- 画矩形,矩形可以圆角,可以指定某个角或其中多个角成为圆角。参数:
UIRectCornerTopLeft
,UIRectCornerTopRight
,UIRectCornerBottomLeft
,UIRectCornerBottomRight
,UIRectCornerAllCorners
+ (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");
}
结语
CAShapeLayer
和UIBezierPath
规定一个形状,CABasicAnimation
为其添加动画。下一篇我将写具体的实例。最后,非常感谢您阅读本文。
网友评论