CAShapeLayer的使用[2]
CAShapeLayer的使用[2]
CAShapeLayer支持的动画类型有如下这些.
------------------------------------------------------------------------------
/* The path defining the shape to be rendered. If the path extends
* outside the layer bounds it will not automatically be clipped to the
* layer, only if the normal layer masking rules cause that. Defaults
* to null. Animatable. (Note that although the path property is
* animatable, no implicit animation will be created when the property
* is changed.) */
@property CGPathRef path;
------------------------------------------------------------------------------
/* The color to fill the paths stroked outline, or nil for no stroking.
* Defaults to nil. Animatable. */
@property CGColorRef strokeColor;
------------------------------------------------------------------------------
/* These values define the subregion of the path used to draw the
* stroked outline. The values must be in the range [0,1] with zero
* representing the start of the path and one the end. Values in
* between zero and one are interpolated linearly along the path
* length. strokeStart defaults to zero and strokeEnd to one. Both are
* animatable. */
@property CGFloat strokeStart, strokeEnd;
------------------------------------------------------------------------------
/* The line width used when stroking the path. Defaults to one.
* Animatable. */
@property CGFloat lineWidth;
------------------------------------------------------------------------------
/* The miter limit used when stroking the path. Defaults to ten.
* Animatable. */
@property CGFloat miterLimit;
------------------------------------------------------------------------------
/* The phase of the dashing pattern applied when creating the stroke.
* Defaults to zero. Animatable. */
@property CGFloat lineDashPhase;
------------------------------------------------------------------------------
现在来尝试path动画,结果如下:
首先用工具生成path源码:
源码:
- (void)viewDidLoad [super viewDidLoad]; // shapeLayer CAShapeLayer *circleLayer = [CAShapeLayer layer]; circleLayer.frame = (CGRect){CGPointMake(0, 0), CGSizeMake(200, 200)}; circleLayer.position = self.view.center; circleLayer.path = [self getStar1BezierPath].CGPath; circleLayer.fillColor = [UIColor clearColor].CGColor; circleLayer.strokeColor = [UIColor redColor].CGColor; circleLayer.lineWidth = 2.f; [self.view.layer addSublayer:circleLayer]; // 定时器 _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]]; [_timer event:^{ static int i = 0; if (i++ % 2 == 0) CABasicAnimation *circleAnim = [CABasicAnimation animationWithKeyPath:@"path"]; circleAnim.removedOnCompletion = NO; circleAnim.duration = 1; circleAnim.fromValue = (__bridge id)[self getStar1BezierPath].CGPath; circleAnim.toValue = (__bridge id)[self getStar2BezierPath].CGPath; circleLayer.path = [self getStar2BezierPath].CGPath; [circleLayer addAnimation:circleAnim forKey:@"animateCirclePath"]; else CABasicAnimation *circleAnim = [CABasicAnimation animationWithKeyPath:@"path"]; circleAnim.removedOnCompletion = NO; circleAnim.duration = 1; circleAnim.fromValue = (__bridge id)[self getStar2BezierPath].CGPath; circleAnim.toValue = (__bridge id)[self getStar1BezierPath].CGPath; circleLayer.path = [self getStar1BezierPath].CGPath; [circleLayer addAnimation:circleAnim forKey:@"animateCirclePath"]; } timeInterval:NSEC_PER_SEC]; [_timer start]; -(UIBezierPath *)getStar1BezierPath //// Star Drawing UIBezierPath* starPath = [UIBezierPath bezierPath]; [starPath moveToPoint: CGPointMake(22.5, 2.5)]; [starPath addLineToPoint: CGPointMake(28.32, 14.49)]; [starPath addLineToPoint: CGPointMake(41.52, 16.32)]; [starPath addLineToPoint: CGPointMake(31.92, 25.56)]; [starPath addLineToPoint: CGPointMake(34.26, 38.68)]; [starPath addLineToPoint: CGPointMake(22.5, 32.4)]; [starPath addLineToPoint: CGPointMake(10.74, 38.68)]; [starPath addLineToPoint: CGPointMake(13.08, 25.56)]; [starPath addLineToPoint: CGPointMake(3.48, 16.32)]; [starPath addLineToPoint: CGPointMake(16.68, 14.49)]; [starPath closePath]; return starPath; -(UIBezierPath *)getStar2BezierPath //// Star Drawing UIBezierPath* starPath = [UIBezierPath bezierPath]; [starPath moveToPoint: CGPointMake(22.5, 2.5)]; [starPath addLineToPoint: CGPointMake(32.15, 9.21)]; [starPath addLineToPoint: CGPointMake(41.52, 16.32)]; [starPath addLineToPoint: CGPointMake(38.12, 27.57)]; [starPath addLineToPoint: CGPointMake(34.26, 38.68)]; [starPath addLineToPoint: CGPointMake(22.5, 38.92)]; [starPath addLineToPoint: CGPointMake(10.74, 38.68)]; [starPath addLineToPoint: CGPointMake(6.88, 27.57)]; [starPath addLineToPoint: CGPointMake(3.48, 16.32)]; [starPath addLineToPoint: CGPointMake(12.85, 9.21)]; [starPath closePath]; return starPath; }
CALayer中有一个令人抽搐的属性叫mask,据说可以做动画,官方文档上说可以:
但其属性说明中根本就没有animatable字眼.
/* A layer whose alpha channel is used as a mask to select between the
* layers background and the result of compositing the layers
* contents with its filtered background. Defaults to nil. When used as
* a mask the layers `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. */
@property(retain) CALayer *mask;
这是个bug哦:).
将CAShapeLayer当做mask做动画的效果:
源码:
- (void)viewDidLoad [super viewDidLoad]; // shapeLayer CAShapeLayer *circleLayer = [CAShapeLayer layer]; circleLayer.frame = (CGRect){CGPointMake(0, 0), CGSizeMake(200, 200)}; circleLayer.position = self.view.center; circleLayer.path = [self getStar1BezierPath].CGPath; circleLayer.fillColor = [UIColor blackColor].CGColor; circleLayer.strokeColor = [UIColor redColor].CGColor; circleLayer.lineWidth = 2.f; // backgroundLayer CALayer *layer = [CALayer layer]; layer.frame = self.view.bounds; layer.contents = (__bridge id)([UIImage imageNamed:@"psb.jpg"].CGImage); layer.mask = circleLayer; [self.view.layer addSublayer:layer]; // 定时器 _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]]; [_timer event:^{ static int i = 0; if (i++ % 2 == 0) CABasicAnimation *circleAnim = [CABasicAnimation animationWithKeyPath:@"path"]; circleAnim.removedOnCompletion = NO; circleAnim.duration = 1; circleAnim.fromValue = (__bridge id)[self getStar1BezierPath].CGPath; circleAnim.toValue = (__bridge id)[self getStar2BezierPath].CGPath; circleLayer.path = [self getStar2BezierPath].CGPath; [circleLayer addAnimation:circleAnim forKey:@"animateCirclePath"]; else CABasicAnimation *circleAnim = [CABasicAnimation animationWithKeyPath:@"path"]; circleAnim.removedOnCompletion = NO; circleAnim.duration = 1; circleAnim.fromValue = (__bridge id)[self getStar2BezierPath].CGPath; circleAnim.toValue = (__bridge id)[self getStar1BezierPath].CGPath; circleLayer.path = [self getStar1BezierPath].CGPath; [circleLayer addAnimation:circleAnim forKey:@"animateCirclePath"]; } timeInterval:NSEC_PER_SEC]; [_timer start]; -(UIBezierPath *)getStar1BezierPath //// Star Drawing UIBezierPath* starPath = [UIBezierPath bezierPath]; [starPath moveToPoint: CGPointMake(22.5, 2.5)]; [starPath addLineToPoint: CGPointMake(28.32, 14.49)]; [starPath addLineToPoint: CGPointMake(41.52, 16.32)]; [starPath addLineToPoint: CGPointMake(31.92, 25.56)]; [starPath addLineToPoint: CGPointMake(34.26, 38.68)]; [starPath addLineToPoint: CGPointMake(22.5, 32.4)]; [starPath addLineToPoint: CGPointMake(10.74, 38.68)]; [starPath addLineToPoint: CGPointMake(13.08, 25.56)]; [starPath addLineToPoint: CGPointMake(3.48, 16.32)]; [starPath addLineToPoint: CGPointMake(16.68, 14.49)]; [starPath closePath]; return starPath; -(UIBezierPath *)getStar2BezierPath //// Star Drawing UIBezierPath* starPath = [UIBezierPath bezierPath]; [starPath moveToPoint: CGPointMake(22.5, 2.5)]; [starPath addLineToPoint: CGPointMake(32.15, 9.21)]; [starPath addLineToPoint: CGPointMake(41.52, 16.32)]; [starPath addLineToPoint: CGPointMake(38.12, 27.57)]; [starPath addLineToPoint: CGPointMake(34.26, 38.68)]; [starPath addLineToPoint: CGPointMake(22.5, 38.92)]; [starPath addLineToPoint: CGPointMake(10.74, 38.68)]; [starPath addLineToPoint: CGPointMake(6.88, 27.57)]; [starPath addLineToPoint: CGPointMake(3.48, 16.32)]; [starPath addLineToPoint: CGPointMake(12.85, 9.21)]; [starPath closePath]; return starPath; }
附录:
用CAShapeLayer与贝塞尔曲线一起制作下载进度条是相当的容易的说:
//
// RootViewController.m
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//
#import "RootViewController.h"
#import "YXGCD.h"
@interface RootViewController ()
@property (nonatomic, strong) GCDTimer *timer;
@end
@implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 获取path
UIBezierPath *path = [self getBezierPathWithLength:300 lineWidth:1];
// shapeLayer
CAShapeLayer *circleLayer = [CAShapeLayer layer];
circleLayer.frame = path.bounds;
circleLayer.position = self.view.center;
circleLayer.fillColor = [UIColor clearColor].CGColor;
circleLayer.strokeColor = [UIColor redColor].CGColor;
circleLayer.path = path.CGPath;
circleLayer.lineWidth = 1.f;
[self.view.layer addSublayer:circleLayer];
// 定时器
_timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
[_timer event:^{
circleLayer.strokeEnd = arc4random()%100/100.f;
} timeInterval:NSEC_PER_SEC];
[_timer start];
}
-(UIBezierPath *)getBezierPathWithLength:(CGFloat)length lineWidth:(CGFloat)lineWidth
{
//// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(0, 0)];
[bezierPath addLineToPoint: CGPointMake(length, 0)];
bezierPath.lineWidth = lineWidth;
return bezierPath;
}
@end
相关文章
- 三菱PLC FB块的创建与使用
- 【ue4】【使用】后期处理
- 在Golang中常见的7种阻塞使用方式
- 百度语音识别API的python使用示例详解编程语言
- 使用条件变量实现Linux中的同步和互斥操作(条件变量linux)
- 使用SQL Server语句提升数据库运行效率(sqlserver或语句)
- 使用MySQL实现高效行查询的技巧(mysql行查询)
- MySQL中如何使用enum类型(mysql中enum类型)
- 构建高效系统使用Redis缓存策略(使用redis缓存的策略)
- Oracle中使用ORDER BY实现结果排序(oracle中对结果排序)
- 使用Redis改善Web服务访问速度的实例分析(redis访问实例)
- js字符串转换成xml对象并使用技巧解读