coreAnimation 使用代码

Posted 超超不会飞55

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了coreAnimation 使用代码相关的知识,希望对你有一定的参考价值。

记录一下 看注释

 

 

CABasicAnimation:

 self.view.backgroundColor = [UIColor whiteColor];
    /*****formValue tovalue 依照path确认内容*****/
    /*旋转。。。跳跃我闭着眼*/
    UIImageView *rotationViewX = [[UIImageView alloc] initWithFrame:CGRectMake(20, 100, 70, 70)];
    rotationViewX.image = [UIImage imageNamed:@"123.jpeg"];
    [self.view addSubview:rotationViewX];
    //transform.rotation 的 x 、 y 、z 轴旋转
    CABasicAnimation *rotationAnimX  = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimX.beginTime = 0.0;
    rotationAnimX.toValue = @(2*M_PI);
    rotationAnimX.duration = 5.0;
    rotationAnimX.repeatCount = CGFLOAT_MAX;
    [rotationViewX.layer addAnimation:rotationAnimX forKey:@"rotationAnimX"];
    
    /* 移动丫*/
    UIImageView *moveView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 240, 70, 70)];
    moveView.image = [UIImage imageNamed:@"123.jpeg"];
    [self.view addSubview:moveView];
    CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    // 以中心点为准
    moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(35, 240)];
    moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 240)];
    moveAnimation.duration = 2.f;
    moveAnimation.repeatCount = 2;
    // 动画节奏 线性变化
    moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    //动画完成后是否以动画形式回到初始值
    moveAnimation.autoreverses = YES;
    
    // 以下两句 控制View动画结束后,停留在动画结束的位置
    [moveAnimation setRemovedOnCompletion:NO];
    //此属性为动画填充模式表示动画完成后的状态是怎样的
    moveAnimation.fillMode = kCAFillModeForwards;
    ///
    [moveView.layer addAnimation:moveAnimation forKey:@"moveAnimation"];
    
    /**内容变化*/
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(150, 310, 70, 70)];
    imageView.image = [UIImage imageNamed:@"123.jpeg"];
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    imageView.clipsToBounds  = YES;
    [self.view addSubview:imageView];
    // contents  backgroundColor cornerRadius
    CABasicAnimation *contentAnimation = [CABasicAnimation animationWithKeyPath:@"contents"];
    contentAnimation.toValue = (__bridge id _Nullable)([UIImage imageNamed:@"321.jpg"].CGImage);
    contentAnimation.duration = 1.5;
//    contentAnimation.autoreverses = YES;
    contentAnimation.repeatCount = 1;
    // 测试说明 setRemovedOnCompletion 设置 no kCAFillModeForwards动画后 kCAFillModeBackwards 动画前
    [contentAnimation setRemovedOnCompletion:NO];
    contentAnimation.fillMode = kCAFillModeForwards;
    //
    [imageView.layer addAnimation:contentAnimation forKey:@"contentAnimation"];
    
    /* 比例缩放动画 */
    UIImageView *scaleView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 410, 140, 140)];
    scaleView.image = [UIImage imageNamed:@"321.jpg"];
    [self.view addSubview:scaleView];
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.y"];
    scaleAnimation.fromValue = @(0.3);
    scaleAnimation.toValue = @(1.3);
    scaleAnimation.autoreverses = YES;
    scaleAnimation.duration = 5.f;
    scaleAnimation.repeatCount = CGFLOAT_MAX;
    [scaleView.layer addAnimation:scaleAnimation forKey:@"scaleAnimation"];
    
    /*划线动画部分*/
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 100, 250, 500)];
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc]init];
    //设置描边色,默认无色。
    shapeLayer.strokeColor = [UIColor purpleColor].CGColor;
    //是填充路径的颜色,或不需要填充。默认颜色为不透明的黑色。
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    // 线条宽度
    shapeLayer.lineWidth = 2;
    // lineCap为线端点类型,值有三个类型,分别为kCALineCapButt 、kCALineCapRound 、kCALineCapSquare,默认值为Butt;lineJoin为线连接类型,其值有三个类型,分别为kCALineJoinMiter、kCALineJoinRound、kCALineJoinBevel,默认值是Miter。
    shapeLayer.lineCap = kCALineCapRound;
    shapeLayer.lineJoin = kCALineJoinRound;
    //
    shapeLayer.path = bezierPath.CGPath;
    [self.view.layer addSublayer:shapeLayer];
    //
    CABasicAnimation *lineAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    lineAnimation.duration = 5.0;
    lineAnimation.fromValue = @(0);
    lineAnimation.toValue = @(1);
    lineAnimation.autoreverses = YES;
    lineAnimation.fillMode = kCAFillModeForwards;
    lineAnimation.repeatCount = CGFLOAT_MAX;
    lineAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [shapeLayer addAnimation:lineAnimation forKey:@"lineAnimation"];

 CAKeyframeAnimation:

 UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 100, 250, 500)];
    //
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 70, 80)];
    imageView.clipsToBounds = YES;
    imageView.contentMode = UIViewContentModeScaleToFill;
    imageView.image = [UIImage imageNamed:@"123.jpeg"];
//    [self.view addSubview:imageView];
    //
    CAKeyframeAnimation *orbitAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    // 时间
    orbitAnim.duration = 5;
    // 路线
    orbitAnim.path = bezierPath.CGPath;
    // 动画的计算模式  ②中我们说要介绍此属性,此属性代表的是计算模式分别有kCAAnimationLinear(线性)kCAAnimationDiscrete(离散即不连续的)kCAAnimationPaced(节奏)kCAAnimationCubic(立方)kCAAnimationCubicPaced(立方节奏)当它被我们设置为kCAAnimationPaced(节奏)或kCAAnimationCubicPaced(节奏立方)的时候我们所设置的③ keyTimes和④ timingFunctions这两个属性会被忽略。
    
    orbitAnim.calculationMode = kCAAnimationPaced;
    //此属性为动画填充模式表示动画完成后的状态是怎样的
    orbitAnim.fillMode = kCAFillModeForwards;
    //动画沿路径旋转方式  kCAAnimationRotateAuto(自动旋转)kCAAnimationRotateAutoReverse(自动倒转)
    orbitAnim.rotationMode = kCAAnimationRotateAutoReverse;
    orbitAnim.repeatCount = CGFLOAT_MAX;
    [imageView.layer addAnimation:orbitAnim forKey:@"orbitAnim"];
    //
    CAShapeLayer *shapeLayer = [CAShapeLayer new];
    shapeLayer.strokeColor = [UIColor purpleColor].CGColor;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.lineWidth = 0.5;
    shapeLayer.lineJoin = kCALineJoinRound;
    shapeLayer.lineCap = kCALineCapRound;
    shapeLayer.path = bezierPath.CGPath;
    [self.view.layer addSublayer:shapeLayer];
    
    UIImageView *imageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 70, 80)];
    imageView2.clipsToBounds = YES;
    imageView2.contentMode = UIViewContentModeScaleToFill;
    imageView2.image = [UIImage imageNamed:@"123.jpeg"];
    [self.view addSubview:imageView2];
    
    
    ///
    CAKeyframeAnimation *keyAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    //设置每个阶段的位置(第一个代表的是起始位置,最后一个代表的是结束位置)注意这CGPoint代表的是中点。
    
    keyAnimation.values=@[[NSValue valueWithCGPoint:CGPointMake(0, 200)],[NSValue valueWithCGPoint:CGPointMake(100, 200)],[NSValue valueWithCGPoint:CGPointMake(100, 300)],[NSValue valueWithCGPoint:CGPointMake(200, 300)],[NSValue valueWithCGPoint:CGPointMake(0, 100)]];
    
    keyAnimation.autoreverses= YES;
    
    keyAnimation.removedOnCompletion=NO;
    //设置动画为累加效果 累加 会有位置变化问题
//    keyAnimation.cumulative= YES;
//    keyAnimation.fillMode=kCAFillModeBackwards;
    
    keyAnimation.duration=4.0f;
    
    //设置其速度变化的函数
    
    keyAnimation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    //设置的是每个阶段速度变化的函数
    
    keyAnimation.timingFunctions=@[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
    
    //动画重复的次数
    
    keyAnimation.repeatCount = CGFLOAT_MAX;
    
    [imageView2.layer addAnimation:keyAnimation forKey:@"asdasd"];

CASpringAnimation:

#import "WaterVC.h"

@interface WaterVC ()

@property (nonatomic, strong) CADisplayLink *waveDisplaylink;
@property (nonatomic, strong) CAShapeLayer  *firstWaveLayer;
@property (nonatomic, strong) CAShapeLayer  *secondWaveLayer;



@end

@implementation WaterVC
{
    
    // 水纹振幅
    CGFloat _waveA;
    // 水纹周期
    CGFloat _waveW;
    // 位移
    CGFloat _offsetX;
    // 当前浪纹高度
    CGFloat _currentK;
    //水纹速度
    CGFloat _waterSpeed;
    //水纹路宽度
    CGFloat _waterWaveWidth;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //
    _waveA = 8;
    _waveW =  2 * M_PI/self.view.bounds.size.width;
    _offsetX = 0;
    _currentK = self.view.bounds.size.height / 2 ;
    _waterSpeed = 0.05;
    _waterWaveWidth = self.view.bounds.size.width;
    //
    self.view.backgroundColor = [UIColor whiteColor];
    //
    _firstWaveLayer = [CAShapeLayer new];
    _firstWaveLayer.fillColor = [UIColor colorWithRed:73/255.0 green:142/255.0 blue:178/255.0 alpha:0.5].CGColor;
    _firstWaveLayer.strokeStart = 0.0;
    _firstWaveLayer.strokeEnd = 0.8;
    [self.view.layer addSublayer:_firstWaveLayer];
    //
    _secondWaveLayer = [[CAShapeLayer alloc] init];
    _secondWaveLayer.fillColor = [UIColor colorWithRed:73/255.0 green:142/255.0 blue:178/255.0 alpha:0.5].CGColor;
    _secondWaveLayer.strokeStart = 0.0;
    _secondWaveLayer.strokeEnd = 0.8;
    [self.view.layer addSublayer:_secondWaveLayer];
    //
    _waveDisplaylink =  [CADisplayLink displayLinkWithTarget:self selector:@selector(getCurrentWave)];
    [_waveDisplaylink addToRunLoop:NSRunLoop.currentRunLoop forMode:NSRunLoopCommonModes];
}
//正弦型函数解析式:y=Asin(ωx+φ)+b
//各常数值对函数图像的影响:
//φ:决定波形与X轴位置关系或横向移动距离(左加右减)
//ω:决定周期(最小正周期T=2π/∣ω∣)
//A:决定峰值(即纵向拉伸压缩的倍数)
//b:表示波形在Y轴的位置关系或纵向移动距离(上加下减)

- (void)getCurrentWave{
    _offsetX = _offsetX + _waterSpeed;
    CGMutablePathRef path = CGPathCreateMutable();
    CGFloat y = _currentK;
    CGPathMoveToPoint(path, NULL, 0, y);
    for (int i=0; i<(int)_waterWaveWidth+1; i++) {
        y = _waveA * sin(_waveW * i + _offsetX) + _currentK;
        CGPathAddLineToPoint(path, NULL, i, y);
    }
    CGPathAddLineToPoint(path, NULL,  _waterWaveWidth, self.view.bounds.size.height);
    CGPathAddLineToPoint(path, NULL,  0, self.view.bounds.size.height);
    CGPathCloseSubpath(path);
    _firstWaveLayer.path = path;
    //
    CGMutablePathRef path2 = CGPathCreateMutable();
    CGFloat y2 = _currentK;
    CGPathMoveToPoint(path2, NULL, 0, y);
    for (int i=0; i<(int)_waterWaveWidth+1; i++) {
        //
        y2 = _waveA * sin(_waveW * i + _offsetX - _waterWaveWidth/2 ) + _currentK;
        CGPathAddLineToPoint(path2, NULL, i, y2);
    }
    CGPathAddLineToPoint(path2, NULL,  _waterWaveWidth, self.view.bounds.size.height);
    CGPathAddLineToPoint(path2, NULL,  0, self.view.bounds.size.height);
    CGPathCloseSubpath(path2);
    _secondWaveLayer.path = path2;
}

水纹:

 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 200, 50, 50)];
    imageView.image = [UIImage imageNamed:@"321.jpg"];
    [self.view addSubview:imageView];
    //
    CASpringAnimation *springAnim = [CASpringAnimation animationWithKeyPath:@"position.x"];
    //质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
    springAnim.mass = 1;
    //阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
    springAnim.damping = 2;
    //刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快
    springAnim.stiffness = 100;
    //初始速率,动画视图的初始速度大小 Defaults to zero
    //速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反
    springAnim.initialVelocity = 0;
    //
    springAnim.fromValue = @(imageView.layer.position.x);
    springAnim.toValue = @(imageView.layer.position.x +100);
    springAnim.repeatCount = CGFLOAT_MAX;
    // settlingDuration 估算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算
    springAnim.duration = springAnim.settlingDuration;
    [imageView.layer addAnimation:springAnim forKey:@"springAnim"];

CAEmitterLayer&CAEmitterLayer

#import "FireAnimVC.h"

@interface FireAnimVC ()

@property (nonatomic, strong) CAEmitterLayer *fireEmitter;
@property (nonatomic, strong) UIImage   *image;

@property (nonatomic, strong) CAEmitterLayer *testEmitter;


@end

@implementation FireAnimVC

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.clipsToBounds = YES;
    //
    [self showFire];
    [self emitterTest];

}

- (void)emitterTest{
    _testEmitter = [CAEmitterLayer layer];
    //
    _testEmitter.borderColor    = [UIColor redColor].CGColor;
    _testEmitter.borderWidth    = 1.0f;
    
    // 喷射位置
    _testEmitter.position       = CGPointMake(self.view.frame.size.width/2.0, 0);
    
    // 发射源的尺寸
    _testEmitter.emitterSize    = CGSizeMake(self.view.frame.size.width, 1);
    
    //是粒子从什么形状发射出来,它并不是表示粒子自己的形状,
    //    NSString * const kCAEmitterLayerPoint;      ////    NSString * const kCAEmitterLayerLine;               // 直线
//    NSString * const kCAEmitterLayerRectangle;      // 矩形
//    NSString * const kCAEmitterLayerCircle;          // 圆形
//    NSString * const kCAEmitterLayerCuboid;        // 3D rectangle
//    NSString * const kCAEmitterLayerSphere;   // 3D circle
    _testEmitter.emitterShape   = kCAEmitterLayerLine;
    
    //决定了粒子的发射模式。
//    NSString * const kCAEmitterLayerPoints;  // 顶点
//    NSString * const kCAEmitterLayerOutline;     // 轮廓,即边上
//    NSString * const kCAEmitterLayerSurface;   // 表面,即图形的面积内
//    NSString * const kCAEmitterLayerVolume;    // 容积,即3D图形的体积内
    
    _testEmitter.emitterMode    = kCAEmitterLayerSurface;

    // 发射器的渲染 重叠效果
//    renderMode,控制着在视觉上粒子图片是如何混合的。你可能已经注意到了示例中我们把它设置为kCAEmitterLayerAdditive,它实现了这样一个效果:合并例子重叠部分的亮度使得看上去更亮
    _testEmitter.renderMode = kCAEmitterLayerAdditive;
    
    
    //
    CAEmitterCell *particle = [CAEmitterCell emitterCell];
    //
    particle.name = @"snow";
    // 静态图片
    particle.contents = (id)_image.CGImage;
    
    //每秒产生的粒子数量
    particle.birthRate = 20.0f;
    //粒子在系统上存在的时间
    particle.lifetime = 10.f;
    
    /*********横向速度*******/
    // 运动速度
    particle.velocity = 1.f;
    //速度浮动
    particle.velocityRange = 10.f;
    
    
    
    /************  加速度  *************/
    particle.yAcceleration = 15.f;
//    particle.xAcceleration = 15.f;
//    particle.zAcceleration = 15.f;
    
    
    /*******  粒子发射夹角    *****/
    //emissionLongtitude决定了粒子飞行方向跟水平坐标轴(x轴)之间的夹角,默认是0
    particle.emissionLongitude = M_PI/2.0;
    //emissionRange则决定了粒子的发散范围,同样是一个弧度值(radians),表示粒子在沿着emissionLongtitude方向所形成的顶角为2倍emissionRange的圆锥范围内发散
//    particle.emissionRange = M_PI_4;
    
    
    /****    粒子自转角度     ****/
    //弧度速度
//    particle.spin =
    //范围
//    particle.spinRange =
    
    /********    等比缩放   ******/
    particle.scale = 0.5;
    particle.scaleRange = 0.1;
    particle.scaleSpeed = 0.02;
    
    /********       设置颜色        *******/
    //结合contents内容的颜色来改变我们的CAEmitterCell
    particle.color = [UIColor colorWithRed:0.8 green:0.4 blue:0.2 alpha:1.0].CGColor;
    
//    是粒子对应颜色的component的初始取值范围
//    particle.redRange = 1.f;
//    particle.greenRange = 1.f;
//    particle.blueRange = 1.f;

//    表示对应的颜色的变化速度
//    particle.redSpeed  = .1f;
//    particle.greenSpeed = .1f;
//    particle.blueSpeed  = .1f;
    
    //透明色
    particle.alphaRange = .8f;
    particle.alphaSpeed = -.1f;
    
    //
    _testEmitter.emitterCells = @[particle];
    [self.view.layer addSublayer:_testEmitter];
}

- (void)showFire{
    //
    _image = [UIImage imageNamed:@"Fire.png"];
    //
    self.view.backgroundColor = [UIColor blackColor];
    //
    _fireEmitter = [CAEmitterLayer layer];
    //    _fireEmitter.emitterSize = CGSizeMake(32, 32);
    //    _fireEmitter.emitterMode = kCAEmitterLayerOutline;
    // 发射位置
    _fireEmitter.emitterPosition = self.view.center;
    // 辐射器的形状
    _fireEmitter.emitterShape= kCAEmitterLayerCircle;
    // 发射器的渲染
    _fireEmitter.renderMode = kCAEmitterLayerAdditive;
    
    //
    CAEmitterCell *fire = [CAEmitterCell emitterCell];
    // 粒子的创建速率,默认为1/s
    fire.birthRate = 200;
    // 粒子存活时间
    fire.lifetime = 0.2;
    // 粒子的生存时间容差
    fire.lifetimeRange = 0.5;
    // 粒子的颜色
    fire.color = [UIColor colorWithRed:0.8 green:0.4 blue:0.2 alpha:0.1].CGColor;
    //
    fire.contents = (id)[_image CGImage];
    //
    fire.name = @"fire";
    // 粒子的速度
    fire.velocity = 35;
    // 粒子动画的速度容差
    fire.velocityRange = 10;
    // 粒子在xy平面的发射角度
    fire.emissionLongitude = M_PI +M_PI_2;
    // 粒子发射角度的容差
    fire.emissionRange = M_PI_2;
    // 缩放速度
    fire.scaleSpeed = 0.3;
    //
    
    _fireEmitter.emitterCells = @[fire];
    [self.view.layer addSublayer:_fireEmitter];
}

好好看 这前面是张照片

 

以上是关于coreAnimation 使用代码的主要内容,如果未能解决你的问题,请参考以下文章

使用CoreAnimation 实现相机拍摄照片之后动画效果

如何使用 pop 或 CoreAnimation 更改动画的起点或锚点

在 iOS 应用程序中使用 CoreAnimation / QuartzCore 动画 UILabel

Core Animation简介

iOS开发CAAnimation详解

Swift coreAnimation 加计时器写的游戏《飞机大战》