首页 > 开发 > 设计 > 正文

iOS easing tween 动画效果

2017-09-15 09:33:22  来源: 网友分享

在iOS 开发中,要做一个动画效果,我们会用到CAKeyframeAnimation。 这个库提供了一些对frame 动画的控制,什麽是frame 动画? frame 动画就好比电视动画那样,由一格一格的图画(也可以想像成frame)构成, 快速播放图画便成了动画。 在CAKeyframeAnimation 的概念是一样, 你只需要提供keyframe 的信息, 程序会自动完成keyframe之间的"图画"。 如果大家有用过adobe flash 这工具, 其实是等同motion/shape tween。 好吧!举个例子比较清楚明白。 如果想对一个图形做一个弹出的动画, 用CAKeyframeAnimation可以写成

CAKeyframeAnimation *boundsOvershootAnimation = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size"]; CGSize startingSize = CGSizeZero; CGSize targetSize = CGSizeMake(100,100); CGSize overshootSize = CGSizeMake(120,120); CGSize undershootSize = CGSizeMake(80,80); NSArray *boundsValues = [NSArray arrayWithObjects:[NSValue valueWithCGSize:startingSize], [NSValue valueWithCGSize:targetSize], [NSValue valueWithCGSize:overshootSize], [NSValue valueWithCGSize:undershootSize], [NSValue valueWithCGSize:targetSize], nil]; [boundsOvershootAnimation setValues:boundsValues]; NSArray *times = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0f], [NSNumber numberWithFloat:0.5f], [NSNumber numberWithFloat:0.8f], [NSNumber numberWithFloat:0.9f], [NSNumber numberWithFloat:1.0f], nil]; [boundsOvershootAnimation setKeyTimes:times]; boundsOvershootAnimation.duration = 1.0;

这个弹出的动画包含了5个keyframe, 目的是令弹出带点跳动的感觉。 [boundsOvershootAnimation setValues:boundsValues] 这一行代码就设定了这动画的keyframe。 另一个重要的元素就是时间, CAKeyframeAnimation 提供了keyframe 时间的控制, 如果不设定便会以直线性发展。 而这动画会以先慢後快的形式出现, 为什麽呢? 请看[boundsOvershootAnimation setKeyTimes:times] 这一段。 动画长一秒, 由0-0.5秒会进行 startingSize 到 targetSize 的动画, 0.5-0.8秒会进行 targetSize 到 overshootSize 的动画。 如此类推就会做出先慢後快的效果。

CAKeyframeAnimation 还提供了其他方法去控制keyframe, 以下是一个透明淡出的动画。

CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; opacityAnimation.fromValue = [NSNumber numberWithFloat:1.0f]; opacityAnimation.toValue = [NSNumber numberWithFloat:0.0f]; opacityAnimation.timingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]]; // EaseIn curve //opacityAnimation.timingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; // EaseOut curve //opacityAnimation.timingFunction = [CAMediaTimingFunction functionWithControlPoints:1.0 :0.0 :1.0 :0.1]; // Bezier curve

opacityAnimation.timingFunction 是用来控制动画线性发展。 其中[CAMediaTimingFunction functionWithControlPoints:1.0 :0.0 :1.0 :0.1] 是一个贝塞尔曲线的控制方法。 这也可以令动画做到先慢後快或先快後慢的结果。 你会问, 我怎知道效果会怎样? 这里有一个图表化的工具说明数字线性关係 http://netcetera.org/camtf-playground.html

CAKeyframeAnimation提供了不错的功能, 但对於一些比较複杂的动画效果, CAKeyframeAnimation的配置就会变得複杂, 代码亦会很长。 比方说,我要做一个好像皮球跳动的效果。 我们要计算每一个keyframe的位置, 再为每一个keyframe配置动画时间。要做成这麽的一个效果, keyframe会有很多。所以参考了actionscript的Tween动画之後, 开发了一个用於iOS的Tween效果库。 基本原理是用一些Tween function 包裹计算变化值的公式, 再扩展CAKeyframeAnimation自动按照Tween function来计算keyframe。以下是皮球跳动的效果。

EasingFunction easingFn = [Easing getBounce]; CAKeyframeAnimation *transAnimi = [CAKeyframeAnimation animationWithKeyPath:@"position.x" easeFunction:easingFn.easeOut fromValue:0.0 toValue:200]; transAnimi.duration = 3.0;

[Easing getBounce] 是Tween动画库内跳动效果的公式。 [CAKeyframeAnimation animationWithKeyPath:@"position.x" easeFunction:easingFn.easeOut fromValue:0.0 toValue:200]是CAKeyframeAnimation的扩展。 回传的是一般CAKeyframeAnimation, 可以直接用在UIView 物件上。Tween动画库提供以下效果, 图表化可到这里 http://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html

-Elastic-Bounce-Back-Linear-Expo-Quad-Cubic-Quart-Quint-Sine-Circ

Tween动画库是可以再扩展。参考下列直线性的公式, t是当前时间值, b是属性开始值, c是属性变化差, d是总时间值, 回传的是t时间的属性值。大家可以自由改变去创建一个新的公式。

+(EasingFunction)getLinear{ EasingFunction ease; ease.easeIn = ^double(double t, double b, double c, double d) { return c*t/d + b; }; ease.easeOut = ^double(double t, double b, double c, double d) { return c*t/d + b; }; ease.easeInOut = ^double(double t, double b, double c, double d) { return c*t/d + b; }; return ease; }

演示Demo

最后附上源码, 请留言交流指教。

http://url.cn/EyBoWa

Tags: , , , , ,