核心动画
来源:互联网 发布:云涯seo 编辑:程序博客网 时间:2024/05/09 12:30
CAAnimation— CoreAnimation
核心动画主要是为了给用户最大的动画体验而开放出来的api,更加灵活,同时也意味着更加复杂。
创建动画:打开
CAAnimation.h
可以很清楚的看到animation
的定义.
CAAnimation
作为一个父类,主要负责定义属性,方法。
其子类CABasicAnimation
,CAKeyframeAnimation
,CASpringAnimation
才是我们经常使用的类。
举个简单的例子来说明常用的字段的意思:
CABasicAnimation *animation = \
[CABasicAnimation animationWithKeyPath:@"position.x"];
animation.fromValue = @(100);
animation.toValue = @(200);
animation.duration = 3.0;
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
animation.delegate = self;
animation.autoreverses = YES;
[self.animationView.layer addAnimation:animation forKey:@"anitio”];
这段代码实现的效果是,self.animationView的中心点在X轴方向在3.0秒内从100到200做了一段位移。
一段段代码解释:
CABasicAnimation *animation = \
[CABasicAnimation animationWithKeyPath:(nullable NSString *)];keyPath
是NSString
字符串。是你动画的依据,比如你要移动位置,那么keyPath
就是@“position”
,并且keyPath
支持属性.
运算:例如想做一个绕X轴旋转动画,keyPath
就是@“transform.rotaion.x”
keyPath
必须是可靠的,不是随便写的,那么这些值从哪儿来呢,首先layer
里面的所有属性都是可以的,position
就是layer
的属性,position.x
也可以的。为什么keyPath
不能随便写,因为其对应的值是有效的,随便写因为查不到对应的方法,是没有任何动画效果的。
fromValue
、toValue
是两个对应的值,看字面的意思就可以理解,从fromValue
到toValue
进行线性改变,这个值作用在keyPath
上面。需要注意的是 fromValue
和toValue
都是对象,所以填充值需要注意类型。桥接或者转为NSValue
.
duration
是动画的持续时间,单位是秒。
removedOnComplete
设置动画结束后是否结束。YES
表示动画结束后移除动画效果,NO
表示不移除。但是当设置NO
的时候发现这个时候动画还是会有个闪动,回归原位置,那是因为动画虽然没有移除,但是动画效果不作用于属性值的修改,例如上面例子中self.animationView
这个时候的center
是(100,150)
,动画效果是X从100-200
进行动画,在动画结束后,X还在100
的位置,而不是200
。这个也是核心动画和[UIView animation]
的区别,UIView
动画是属性值的直接修改。
fillMode
是当removeOnComplete
为NO
的时候,layer
对于最终动画的位置,
有四个值:kCAFillModeForwards
,kCAFillModeBackwards
,kCAFillModeBoth
,kCAFillModeRemoved
。
效果backwards
和removed
是一致的,表现出来的都是原始状态,至于其他区别我不知道。。 forwards
效果是最终效果是和动画最终效果一致。
delegate
是代理,只有两个代理方法 - (void)animationDidStart:(CAAnimation *)anim;
//动画开始前 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
//动画结束
在这两个代理写一些处理方法。
autoreverses
是设置动画是否返回原始效果,如设置YES
,在X 从100-200动画完成之后,又会200-100的动画,如果在做摄像头扫描效果用这个参数就很省力了。
然后给layer
加上animation
GPU就会根据设置的参数,进行着动画。
这儿的[self.animationView.layer addAnimation:animation forKey:@"anitio”]
; key
是给动画的key
值,可以为空,但是如果想在代理里面区分出来是哪一个animation
,这儿的key就必须有,且唯一。判断方式为:
#pragma mark - CAAnimationDelegate- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { if ([anim isEqual:[self.animationView.layer animationForKey:@"anitio"]]) { <#statements#> }}
这儿基本上经常用的CAAnimation
的属性就讲解完了,更多的实用。
常见的动画组合大部分是一个是同时执行:如,同时进行着缩放和位移,这个时候就需要用到CAAnimationGroup
如下代码:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"]; animation.fromValue = @(100); animation.toValue = @(300);// animation.duration = 1.0;// animation.fillMode = kCAFillModeForwards;// animation.removedOnCompletion = NO; CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scaleAnimation.fromValue = @(1.0); scaleAnimation.toValue = @(0.5);// scaleAnimation.duration = 1.0;// scaleAnimation.fillMode = kCAFillModeForwards;// scaleAnimation.removedOnCompletion = NO; CAAnimationGroup *grop = [CAAnimationGroup animation]; grop.animations = @[animation,scaleAnimation]; grop.duration = 1.0; grop.fillMode = kCAFillModeForwards; grop.removedOnCompletion = NO; [self.animationView.layer addAnimation:grop forKey:@"anitio"];
这儿要注意的是虽然说animation
,scaleAnimation
都可以设置duration,fillMode,removeOnCompletion
,但是最终的效果是以grop
设置的为主,如果不设置,会使用默认的值。
第二种动画组合是:如:先进行位移,位移结束之后进行缩放。
这个时候就需要上面介绍CAAnimationDelegate
来处理
代码如下:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"]; animation.fromValue = @(100); animation.toValue = @(300); animation.duration = 1.0; animation.fillMode = kCAFillModeForwards; animation.removedOnCompletion = NO; animation.delegate = self; [self.animationView.layer addAnimation:animation forKey:@"anitio”];
#pragma mark - CAAnimationDelegate- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { if ([anim isEqual:[self.animationView.layer animationForKey:@"anitio"]]) { CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scaleAnimation.fromValue = @(1.0); scaleAnimation.toValue = @(0.5); scaleAnimation.duration = 1.0; scaleAnimation.fillMode = kCAFillModeForwards; scaleAnimation.removedOnCompletion = NO; [self.animationView.layer addAnimation:scaleAnimation forKey:@"scalAnimation"]; }}
到这儿为止,都是一些简单的动画组合,只要细心,基本上可以满足大多数动画需求,但是还是会有其他更为复杂的动画,上面介绍的可能就不满足或者说能满足,但是代码量很大。这儿就介绍一些其他处理方式:
1.CAShapeLayer
+ UIBezierPath
;如:需要一个动画,三角形变化成为圆形,循环变化。
栗子如下:这儿只是提供思路,和简单的代码实现,如需要实现真实的场景,需要多花点心思来书写UIBezierPath
UIBezierPath *triangle_path = [UIBezierPath bezierPath]; [triangle_path moveToPoint:CGPointMake(50, 20)]; [triangle_path addLineToPoint:CGPointMake(30, 70)]; [triangle_path addLineToPoint:CGPointMake(80, 70)]; [triangle_path closePath]; UIBezierPath *cycle_path = [UIBezierPath bezierPath]; [cycle_path addArcWithCenter:CGPointMake(50, 50) radius:30 startAngle:0 endAngle:M_PI * 2 clockwise:YES]; self.shaperLayer.path = triangle_path.CGPath; CABasicAnimation *shaperAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; shaperAnimation.fromValue = (__bridge id _Nullable)(triangle_path.CGPath); shaperAnimation.toValue = (__bridge id _Nullable)(cycle_path.CGPath); shaperAnimation.duration = 0.5; shaperAnimation.fillMode = kCAFillModeForwards; shaperAnimation.removedOnCompletion = NO; [self.shaperLayer addAnimation:shaperAnimation forKey:@"shapeAnimation”];
2.重绘layer
。动画的本质就是根据一个输入,作用出来一些过渡效果,展示给用户看。屏幕刷新频率是60帧/1秒
所以只要有能力可以根据算法写一些关键帧的参数,自己重绘layer
来达到自己想要的动画效果,据我所知,谷歌给的动画Pop sdk
,就是用CADisplayLink
+ CAShapeLayer
绘制而成;
这篇文章也是核心动画的一些个概念,介绍了一些简单的用法和技巧,完了之后我重现一下现有APP上面的一些好看的动画,也是基于上面概念的应用。
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 核心动画
- 浅谈深度学习中的激活函数
- glBufferSubData
- java线程作业1
- Mybatis逆向工程简易配置
- 如何成为一名机器学习算法工程师?
- 核心动画
- Linux的CentOS安装JDK方法
- 十六、列表生成式
- Saver使用
- 605. Can Place Flowers种植花园即边界处理
- 牛客网剑指offer-用两个栈实现一个队列
- 2.springboot配置文件
- Java语言的异或操作
- hdoj 1048 the hardest problem ever (水题)