CAShapeLayer的path动画

CAShapeLayer的path动画

 

效果

 

源码

https://github.com/YouXianMing/Animations

//
//  CAShapeLayerPathController.m
//  Animations
//
//  Created by YouXianMing on 15/11/17.
//  Copyright  2015年 YouXianMing. All rights reserved.
//

#import "CAShapeLayerPathController.h"
#import "PathView.h"
#import "UIView+SetRect.h"
#import "GCD.h"

@interface CAShapeLayerPathController ()

@property (nonatomic, strong) PathView *pathView;
@property (nonatomic, strong) GCDTimer *timer;

@property (nonatomic, strong) CAShapeLayer *lineShapeLayer;
@property (nonatomic, strong) CAShapeLayer *fillShapeLayer;

@property (nonatomic) CGPoint A;

@property (nonatomic, strong) CALayer *pointA;

@end

@implementation CAShapeLayerPathController

- (void)viewDidLoad {

    [super viewDidLoad];
}

- (void)setup {

    [super setup];

    // background view
    self.pathView        = [[PathView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    self.pathView.center = self.view.center;
    self.pathView.gap    = 10.f;
    [self.pathView setNeedsDisplay];
    [self.view addSubview:self.pathView];
    UIBezierPath *path = [self randomPath];

    // point A
    self.pointA                 = [CALayer layer];
    self.pointA.frame           = CGRectMake(0, 0, 4, 4);
    self.pointA.cornerRadius    = 2.f;
    self.pointA.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f].CGColor;
    self.pointA.position        = CGPointMake(self.A.x + 10, self.A.y + 10);
    [self.pathView.layer addSublayer:self.pointA];

    // shape
    self.fillShapeLayer             = [CAShapeLayer layer];
    self.fillShapeLayer.path        = path.CGPath;
    self.fillShapeLayer.strokeColor = [UIColor clearColor].CGColor;
    self.fillShapeLayer.fillColor   = [UIColor cyanColor].CGColor;
    self.fillShapeLayer.lineWidth   = 0.f;
    self.fillShapeLayer.frame       = CGRectMake(self.pathView.gap,
                                                 self.pathView.gap,
                                                 self.pathView.width - 2 * self.pathView.gap,
                                                 self.pathView.width - 2 * self.pathView.gap);
    [self.pathView.layer addSublayer:self.fillShapeLayer];

    // line
    self.lineShapeLayer             = [CAShapeLayer layer];
    self.lineShapeLayer.path        = path.CGPath;
    self.lineShapeLayer.strokeColor = [UIColor redColor].CGColor;
    self.lineShapeLayer.fillColor   = [UIColor clearColor].CGColor;
    self.lineShapeLayer.lineWidth   = 0.5f;
    self.lineShapeLayer.lineDashPattern = @[@(3), @(3)];
    self.lineShapeLayer.frame       = CGRectMake(self.pathView.gap,
                                                 self.pathView.gap,
                                                 self.pathView.width - 2 * self.pathView.gap,
                                                 self.pathView.width - 2 * self.pathView.gap);
    [self.pathView.layer addSublayer:self.lineShapeLayer];

    // timer
    self.timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
    [self.timer event:^{

        // path animation.
        UIBezierPath *newPath            = [self randomPath];
        CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
        basicAnimation.duration          = 0.5;
        basicAnimation.fromValue         = (__bridge id)(self.lineShapeLayer.path);
        basicAnimation.toValue           = (__bridge id)newPath.CGPath;
        self.lineShapeLayer.path         = newPath.CGPath;
        self.fillShapeLayer.path         = newPath.CGPath;
        [self.lineShapeLayer addAnimation:basicAnimation forKey:@"lineShapeLayerPath"];
        [self.fillShapeLayer addAnimation:basicAnimation forKey:@"fillShapeLayerPath"];

        // fillColor animation.
        UIColor *newColor = [self randomColor];
        CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"fillColor"];
        colorAnimation.duration          = 0.5;
        colorAnimation.fromValue         = (__bridge id _Nullable)(self.fillShapeLayer.fillColor);
        colorAnimation.toValue           = (__bridge id)newColor.CGColor;
        self.fillShapeLayer.fillColor    = newColor.CGColor;
        [self.fillShapeLayer addAnimation:colorAnimation forKey:@"fillShapeLayerColor"];

        // path animation.
        CGPoint newPoint = CGPointMake(self.A.x + 10, self.A.y + 10);
        CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        positionAnimation.duration          = 0.5f;
        positionAnimation.fromValue         = [NSValue valueWithCGPoint:self.pointA.position];
        positionAnimation.toValue           = [NSValue valueWithCGPoint:newPoint];
        self.pointA.position                = newPoint;
        [self.pointA addAnimation:positionAnimation forKey:@"positionAnimation"];

    } timeIntervalWithSecs:1.f];
    [self.timer start];
}

- (UIBezierPath *)randomPath {

    CGPoint pointA = [self randomPointA];
    CGPoint pointB = [self randomPointB];
    CGPoint pointC = [self randomPointC];
    CGPoint pointD = [self randomPointD];

    self.A = pointA;

    UIBezierPath* bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:pointA];
    [bezierPath addLineToPoint:pointB];
    [bezierPath addLineToPoint:pointC];
    [bezierPath addLineToPoint:pointD];
    [bezierPath closePath];

    return bezierPath;
}

- (CGPoint)randomPointA {

    return CGPointMake(arc4random() % (int)(self.pathView.width - 2 * self.pathView.gap), 0);
}

- (CGPoint)randomPointB {

    return CGPointMake(self.pathView.width - 2 * self.pathView.gap, arc4random() % (int)(self.pathView.width - 2 * self.pathView.gap));
}

- (CGPoint)randomPointC {

    return CGPointMake(arc4random() % (int)(self.pathView.width - 2 * self.pathView.gap), self.pathView.width - 2 * self.pathView.gap);
}

- (CGPoint)randomPointD {

    return CGPointMake(0, arc4random() % (int)(self.pathView.width - 2 * self.pathView.gap));
}

- (UIColor *)randomColor {

    return [UIColor colorWithRed:arc4random() % 101 / 100.f
                           green:arc4random() % 101 / 100.f
                            blue:arc4random() % 101 / 100.f
                           alpha:0.5f];
}

@end

细节

注意keyPath参数。

 

时间: 2024-12-23 22:09:22

CAShapeLayer的path动画的相关文章

用path动画绘制水波纹

用path动画绘制水波纹   效果   源码 // // ViewController.m // PathAnimation // // Created by YouXianMing on 15/7/3. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import "ViewController.h" @interface ViewController () @property (nonatomic, stro

Android L New API之Verctor动画 1 —— SVG Path

导入 1.VectorDrawable是Android L中新增的一个API,让你可以创建基于XML的矢量图,并结合AnimatedVectorDrawable来实现动画效果. 2.Android L新增支持Vector标签,可以使用Path创建动画,同时支持SVG格式. SVG 简介 1.SVG 指可伸缩矢量图形 (Scalable Vector Graphics)2.SVG 用来定义用于网络的基于矢量的图形3.SVG 使用 XML 格式定义图形4.SVG 图像在放大或改变尺寸的情况下其图形质

Android自定义View实现支付宝支付成功-极速get花式Path炫酷动画

本文手把手教你图片->SVG->Path的姿势.. 从此酷炫Path动画,如此简单. 效果先随便上几个图,以后你找到的图有多精彩,gif就有多精彩: 随便搜了一个铅笔画的图,丢进去 随手复制的二维码icon 来自大佬wing的铁塔 前文回顾 这里简单回顾一下前文,GIF如下图: PathAnimView接受的唯一数据源是Path(给我一个Path,还你一个动画View) 所以内置了几种将别的资源->Path的方法: 直接传string.(A-Z,0-9 "." &qu

放肆地使用UIBezierPath和CAShapeLayer画各种图形

CAShapeLayer 是 CALayer 的子类,但是比 CALayer 更灵活,可以画出各种图形,当然,你也可以使用其他方式来画,随你. 杂谈 在 CAShapeLayer 中,也可以像 CALayer 一样指定它的 frame 来画,就像这样: 1 2 3 4 5 let layer = CAShapeLayer() layer.frame = CGRectMake(110, 100, 150, 100) layer.backgroundColor = UIColor.blackColo

Swift:超炫的View Controller切换动画

匿名社交应用Secret的开发者开发了一款叫做Ping的应用,用户可以他们感兴趣的话题的推送. Ping有一个很炫的东西,就是主界面和之间切换的动画做的非常的好.每次看到一个非常炫的动画,都不由得会想:"这个东西我要不要自己实现以下".哈哈~~~ 这个教程里,你会学到如何用Swift实现这样的很酷的动画.你会学到如何使用shape layer,遮罩和使用UIViewControllerAnimnatedTransitioning协议和UIPercentDrivenInteractive

动画效果解析工厂:Mask 动画

前言:很多动效都是多种动画的组合,有时候你可能只是需要其中某个动画,但面对庞杂的代码库或是教程,你可能比较困惑,本系列将复杂动效中不常见的动画效果拆解出来便于学习,授人以鱼不如授人以渔. 第一讲是来自 BubbleTransition 中最夺人眼球的形变动画.这个效果在 StarWars.iOS转场动效有两次应用,非常地炫酷:Raywenderlich.com 也出过一个教程来实现这种效果. BubbleTransition 一般而言,这种效果会使用 UIBezierPath + CAShape

关于CAShapeLayer

内容大纲: CAShapeLayer简介 贝塞尔曲线与CAShapeLayer的关系 strokeStart和strokeEnd 动画 用CAShapeLayer实现进度条效果,以及更加复杂的效果 1.CAShapeLayer简介   1.CAShapeLayer继承自CALayer,可以使用CALayer的所有属性值 2.CAShapeLayer需要与贝塞尔曲线配合使用才有意义 3.使用CAShapeLayer与贝塞尔曲线可以实现不在view的drawRect方法中画出有一些想要的图形 4.C

CAShapeLayer(持续更新)

CAShapeLayer 之前讲过CALayer动画相关知识,再来看看更加复杂的CAShapeLayer相关的动画知识. 普通CALayer在被初始化时是需要给一个frame值的,这个frame值一般都与给定view的bounds值一致,它本身是有形状的,而且是矩形. CAShapeLayer在初始化时也需要给一个frame值,但是,它本身没有形状,它的形状来源于你给定的一个path,然后它去取CGPath值,它与CALayer有着很大的区别     CAShapeLayer有着几点很重要: 1

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