iOS animation动画三个角色(下)

作者: 共田君 | 来源:发表于2016-02-19 18:50 被阅读1302次

    tags: Animation


    上篇iOS animation动画三个角色(上)介绍了主角CALayer和几个动画剧本。本篇以几个小例子配以武功秘籍继续介绍其他主角

    • 形状图层 CAShapeLayer 绘制不规则图形(太极拳)
    • 渐变图层 CAGradientLayer 颜色渐变、阴影(隐身术)
    • 复制图层 CAReplicatorLayer 迭代复制同一个图层(分身术)

    CAShapeLayer 太极圈

    继承自CALayer,因此,可使用CALayer的所有属性。但是,CAShapeLayer需要和贝塞尔曲线配合使用才有意义。

    关于UIBezierPath

    path:表示路径,可以用贝塞尔曲线,也可以自定义路径
    fillcolor:表示填充色
    strokeColor:线条颜色
    linewidth:线的宽度
    strokeStart:stroke的起始点(0~1)
    strokeEnd:stroke的结束点(0~1)
    实例

    @interface ProgressView : UIView
    @end
    @implementation ProgressView
    -(id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            CAShapeLayer * shapelayer = [CAShapeLayer layer];
        
            UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(frame.size.width/2, frame.size.height/2) radius:frame.size.width/2 startAngle:0 endAngle:2*M_PI clockwise:YES];
            //[UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:frame.size.width/2];
            //路径
            shapelayer.path = path.CGPath;
            //填充色
            shapelayer.fillColor = [UIColor clearColor].CGColor;
            // 设置线的颜色
            shapelayer.strokeColor = [UIColor orangeColor].CGColor;
            //线的宽度
            shapelayer.lineWidth = 5;
            [self.layer addSublayer:shapelayer];
            
            //设置stroke起始点
    //        shapelayer.strokeStart = 0;
    //        shapelayer.strokeEnd = 0.75;
            
            CABasicAnimation * anima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
            anima.fromValue = [NSNumber numberWithFloat:0.f];
            anima.toValue = [NSNumber numberWithFloat:1.f];
            anima.duration = 4.0f;
            anima.repeatCount = MAXFLOAT;
            anima.timingFunction = UIViewAnimationOptionCurveEaseInOut;
            [shapelayer addAnimation:anima forKey:@"strokeEndAniamtion"];
     
            
            CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
            anima3.toValue = [NSNumber numberWithFloat:-M_PI*2];
            anima3.duration = 2.0f;
            anima3.repeatCount = MAXFLOAT;
            anima3.timingFunction = UIViewAnimationOptionCurveEaseInOut;
            [self.layer addAnimation:anima3 forKey:@"rotaionAniamtion"];
        }
        return self;
    }
    @end
    

    演示图


    shapeloading

    CAGradientLayer 隐身术,渐变术

    继承calayer,主要用于处理颜色渐变的图层。主要有以下的Properties

    @property(copy) NSArray *colors
    渐变颜色的数组
    注意这几个数字在0到1之间单调递增。
    @property CGPoint startPoint
    映射locations中第一个位置,用单位向量表示,比如(0,0)表示从左上角开始变化。默认值是(0.5,0.0)。
    @property CGPoint endPoint
    映射locations中最后一个位置,用单位向量表示,比如(1,1)表示到右下角变化结束。默认值是(0.5,1.0)。
    @property(copy) NSString *type
    默认值是kCAGradientLayerAxial,表示按像素均匀变化。除了默认值也无其它选项。

    //做颜色渐变
    -(void)testslidetounlock
    {
        UILabel * textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 200, 30)];
        textLabel.center = self.view.center;
        textLabel.textColor = [UIColor colorWithWhite:1 alpha:0.8];
        textLabel.textAlignment = NSTextAlignmentCenter;
        textLabel.text = @">> 滑动来解锁 >>>";
        [self.view addSubview:textLabel];
    
        CAGradientLayer *gradient = [CAGradientLayer layer];
    //    gradient.backgroundColor = [UIColor grayColor].CGColor;
        gradient.frame = textLabel.bounds;
        UIColor *startColor = [UIColor whiteColor];
        UIColor *endColor   = [UIColor clearColor];
        gradient.colors = @[(id)endColor.CGColor,(id)startColor.CGColor, (id)endColor.CGColor];
        gradient.startPoint = CGPointMake(0, 0);//(左,下)
        gradient.endPoint = CGPointMake(1, 0);//(右,下)
    //    [textLabel.layer insertSublayer:gradient atIndex:0];
        gradient.locations = @[@.2,@.5,@.8];
        
        textLabel.layer.mask = gradient;
        CABasicAnimation * gradientanimation = [CABasicAnimation animationWithKeyPath:@"locations"];
        gradientanimation.fromValue = @[@0, @0,@0.25];
        gradientanimation.toValue = @[@0.75,@1 ,@1];
        gradientanimation.duration = 2.5;
        gradientanimation.repeatCount = HUGE;
        [gradient addAnimation:gradientanimation forKey:@"gradientanimation"];//gradient, forKey: nil)
    }
    

    演示图


    滑动开锁动画

    CAReplicatorLayer 分身术

    复制器图层(观音送给孙悟空的三根毫毛,吹一下就变成无数的猴子猴孙)
    CAReplicatorLayer是一个容器层
    复制自己子层的layer,并且复制的出来的layer和原来的子layer拥有相同的动效。然后通过设置一些属性,可以设置其偏移位置让其依次排列,也可以设置不同的触发时间这样就形成了动画的效果
    常用于做loading动画

    repicator例子

    此处包含两个动画,一个是正在播放的状态动画,一个是加载的动画

    播放状态动画

    @interface PlayingAnimationView : UIView
    @end
    
    @implementation PlayingAnimationView
    
    -(id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            CAReplicatorLayer * replicatorLayer = [CAReplicatorLayer new];
            replicatorLayer.bounds = CGRectMake(0, 0, frame.size.width, frame.size.height); 
            replicatorLayer.anchorPoint = CGPointMake(0, 0);
            [self.layer addSublayer:replicatorLayer];
            
            CALayer * rectangle = [CALayer new];
            CGFloat width = (frame.size.width - 30)/4;
            rectangle.bounds = CGRectMake(0, 0, width, frame.size.height - 10);//: 0, y: 0, width: 30, height: 90)
            rectangle.anchorPoint = CGPointMake(0, 0);
            rectangle.position = CGPointMake(frame.origin.x + 10, frame.origin.y + 110);
            rectangle.cornerRadius = 2;
            rectangle.backgroundColor = [UIColor whiteColor].CGColor;
            [replicatorLayer addSublayer:rectangle];
        
            
            CABasicAnimation * moveRectangle = [CABasicAnimation animationWithKeyPath:@"position.y"];
            moveRectangle.toValue = @(rectangle.position.y - 70);
            moveRectangle.duration = 0.7;
            moveRectangle.autoreverses = true;
            moveRectangle.repeatCount = HUGE;
            
            [rectangle addAnimation:moveRectangle forKey:nil];
            
            //复制动画和状态
            //重复次数
            replicatorLayer.instanceCount = 4;
            //平移点的间隔 x y z
            replicatorLayer.instanceTransform = CATransform3DMakeTranslation(width + 10, 0, 0);
            replicatorLayer.masksToBounds = true;
            replicatorLayer.instanceDelay =0.3;//延迟动画开始时间 以造成上下移动的效果 
        }
        return self;
    }
    @end
    

    我们观察到主要CAReplicatorLayer可以对它自己的子Layer进行复制操作。创建了CAReplicatorLayer实例后,设置了它的尺寸大小、位置、锚点位置、背景色,并且将它添加到了replicatorAnimationView的Layer中。
    CAReplicatorLayer.h
    中文翻译如下:

    复制器层创建的副本指定数量的其子层,每个副本都可能有几何,时间和适用于它的颜色变换。

    名称 功能
    instanceCount 要创建的副本个数(默认一个)
    preservesDepth 是否将3D例子系统平面化到一个图层(默认NO)
    instanceDelay 动画时间延迟。默认为0
    instanceTransform 迭代图层的位置 CATransform3D对象(创建方法用:CATransform3DMakeRotation圆形排列,CATransform3DMakeTranslation水平排列)
    instanceColor 颜色组件添加到实例k - 1产生的颜色实例的调制颜色k。清晰的颜色(默认不透明白色)
    instanceRedOffset,instanceGreenOffset,instanceBlueOffset,instanceAlphaOffset 加到实例K-1的颜色的颜色分量,以产生实例k的调制颜色。默认为鲜明的色彩(无变化)。

    等待加载动画

    @interface LoadingView : UIView
    @end
    @implementation LoadingView
    -(id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            CAReplicatorLayer * replicatorLayer = [CAReplicatorLayer new];
            replicatorLayer.bounds = CGRectMake(0, 0, frame.size.width, frame.size.height);
            replicatorLayer.position = CGPointMake(frame.size.width/2, frame.size.height/2);
            [self.layer addSublayer:replicatorLayer];
            CALayer * circle = [CALayer new];
            circle.bounds = CGRectMake(0, 0, 15, 15);
            circle.position = CGPointMake(frame.size.width/2, frame.size.height/2 - 55);
            circle.cornerRadius = 7.5;
            circle.backgroundColor = [UIColor whiteColor].CGColor;
            [replicatorLayer addSublayer:circle];
            //复制15个同样的layer
            replicatorLayer.instanceCount = 15;
            CGFloat angle = 2 * M_PI/ 15.;
            replicatorLayer.instanceTransform = CATransform3DMakeRotation(angle, 0, 0, 1);
            replicatorLayer.instanceDelay = 1./15.;//延迟动画开始时间 以造成旋转的效果
         
            CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
            scale.fromValue = @1;
            scale.toValue = @0.1;
            scale.duration = 1;
            scale.repeatCount = HUGE;
            circle.transform = CATransform3DMakeScale(0.01, 0.01, 0.01);
            [circle addAnimation:scale forKey:nil];
        }
        return self;
    }
    @end
    

    总结:结合上篇文章体会一下,一些原来看起来很复杂的动画其实挺简单的。主要是要分解出最原始的状态,如果有重复就像孙悟空一样拔一根毫毛变出很多的猴子猴孙出来,一个大片用了这些主角,有了剧本,作为程序猿的你这个导演可以开拍大片了。


    相关文章

      网友评论

      本文标题:iOS animation动画三个角色(下)

      本文链接:https://www.haomeiwen.com/subject/xmlvkttx.html