欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CoreAnimation核心动画

程序员文章站 2022-04-11 13:19:36
...

CoreAnimation核心动画

一、基本概念

1、核心动画概念

  • Core Animation(核⼼动画)是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍

  • 使⽤它需要先添加QuartzCore.framework和引入对应的框架

<QuartzCore/QuartzCore.h>

2、创建动画的步骤

  1. 初始化⼀个动画对象(CAAnimation)并设置一些动画相关的属性
  2. CALayer中有很多属性都可以通过CAAnimation实现动画效果,包括:opacity、position、transform、bounds、contents等
  3. 使用CALayer的addAnimation:forKey方法增加动画到层,当动画对象添加到层后会⾃动执⾏。
  4. Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。

###3、CAAnimation CAAimation是所有动画对象的基类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类

CAAnimation继承结构如下:
注意:图中的紫色虚线代表“继承”某个类,红色虚线代表“遵守”某个类 CoreAnimation核心动画

二、基本动画

CABasicAnimation是CAPropertyAnimation的子类

扩展示例代码-平移:

CABasicAnimation *animation =   
[CABasicAnimation animationWithKeyPath:"transform.translation.x"];    

animation.toValue = @320;  
animation.duration = 1;  
animation,timingFuntion =   
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];  
animation.fillMode = KCAFillModeForwards  
animation.removedOnCompletion = NO;    

[self.animationView.layer addAnimation:animation forKey:@"animation"];

扩展示例代码-缩放:

CABasicAnimation *animation=[CABasicAnimationanimationWithKeyPath:"transform.scale"];    

animation.toValue = @2;  
animation.duration = 0.25;  
animation.repeatCount = 1;  
animation.autoreverses = YES;  
  
[self.animationView.layer addAnimation:animation forKey:@"animation"];

--
动画的设置

    // 4、动画时间
    animation.duration = 2.0;
    
    /* 5、动画的填充模式:
     kCAFillModeForwards
     kCAFillModeBackwards
     kCAFillModeBoth
     kCAFillModeRemoved
    */
    animation.fillMode = kCAFillModeForwards;
    
    // 6、动画后是否移除动画后的状态(回到原始状态),默认是YES, 前提是要设置fillModle为:kCAFillModeForwards
    animation.removedOnCompletion = NO;
    
    // 7、是否有回复效果
    animation.autoreverses = YES;
    
    // 8、设置动画重复次数
    animation.repeatCount = HUGE_VALF; //  HUGE_VALF 最大浮点数,表示无限次重复
    
    // 9、播放动画的速度
    animation.speed = 2;
    


三、关键帧动画

CAKeyframeAnimation,也是CAPropertyAnimation的子类。但关键帧动画和简单动画的区别是:简单动画只能从一个数值过渡到另一个数值,而关键帧动画有一个NSArray来保存多个数值的过渡。

绘制路径代码如下:

// 绘制路径
- (UIBezierPath *)path {
    
    // 椭圆
//    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:self.view.bounds];
    // 圆角矩形
//    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.view.bounds cornerRadius:50];
    // 内切圆
//    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 100, 300, 300)];
    
    // 贝塞尔曲线
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, TScreenHeight)];
    CGPoint point_1 = CGPointMake(TScreenWidth, TScreenHeight);
    CGPoint controPoint_1 = CGPointMake(TScreenWidth / 2, - TScreenHeight);
//    CGPoint controPoint_2 = CGPointMake(TScreenWidth / 4 * 3, TScreenHeight);
    
    [path addQuadCurveToPoint:point_1 controlPoint:controPoint_1];
//    [path addCurveToPoint:point_1 controlPoint1:controPoint_1 controlPoint2:controPoint_2];
    
    return path;
}
 

四、转场动画

CATransition并不像属性动画那样平滑的在两个值之间做动画,而是影响到整个图层的变化,过渡动画首先展示之前的图层外观,然后通过一个交换过渡到新的外观

相关属性:
1.type????????????????????:动画过渡类型
2.subtype:动画过渡方向
????????????????????????????3.startProgress:动画起点

示例代码如下:

- (CAAnimation *)transitionAnimation {
    
    CATransition *transitionAni = [CATransition animation];
    transitionAni.duration = 1.0;
    /*
     1. fade     淡出效果
     2. moveIn 进入效果
     3. push    推出效果
     4. reveal   移出效果
     
     // 未公开的
     5. cube   立方体翻转效果
     6. suckEffect  抽走效果
     7. rippleEffect 水波效果
     8. pageCurl    翻开页效果
     9. pageUnCurl 关闭页效果
     10. cameraIrisHollowOpen  相机镜头打开效果
     11.  cameraIrisHollowClose  相机镜头关闭效果
    */
    
    transitionAni.type = kCATransitionPush;
    // transitionAni.type = @"push";
    
    // 转场的方向:`fromLeft', `fromRight', `fromTop'  `fromBottom'
    transitionAni.subtype = @"fromTop";
    
    // 开始转场和结束转场的进度位置
    // transitionAni.startProgress = 0.5;
    // transitionAni.endProgress = 1;
    
    return transitionAni;
}
  

##五、动画的暂停和继续



- (void)pauseAnimation {
    
    NSLog(@"CACurrentMediaTime:%f",CACurrentMediaTime());
    
    // CACurrentMediaTime(): 当前媒体时间,表示系统启动后到当前的秒数,当系统重启后这个时间也重置
    CFTimeInterval pauseTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    // 设置动画的时间的偏移
    layer.timeOffset = pauseTime;
    
     layer.speed = 0;
}


- (void)resumeAnimation {
    
    // 获取暂停时的时间
    CFTimeInterval pasuseTime = [layer timeOffset];
    
    layer.speed = 1;
    layer.timeOffset = 0;
    layer.beginTime = 0;
    
    // 设置开始的时间(继续动画,这样设置相当于让动画等待的秒数等于暂停的秒)
    layer.beginTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pasuseTime;
}


- (CAAnimation *)rotationAnimation {
    
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    
    animation.duration = 2.0;
    animation.byValue = @(2 * M_PI);
    animation.repeatCount = HUGE_VALF;
    
    // 设置动画开始的媒体时间(用于设置动画的延迟启动),要加上CACurrentMediaTime
    animation.beginTime =  CACurrentMediaTime() + 2;

    [layer addAnimation:animation forKey:@"rotaion"];
    

<h3>附:CALayer中可以用来做动画的属性 </h3> ![G-Dragon CALayer](https://static.oschina.net/uploads/img/201608/27154527_rkWq.png "属性")

转载于:https://my.oschina.net/hgvbhb/blog/738720