ColorTouch动画模块(上)

达芬奇密码2018-07-03 13:43

1 移动端动画简介

       现在主流的移动端平台主要是iOSAndroid,而在这两个平台,都有一套自己的动画api。通过使用这些api,使用者可以实现一些基础或是复杂的动画效果。

1.1 iOS动画模块

      iOS的动画系统称之为Core Animation。若要实现一个简单的线性位移动画,其代码可以写成如下样子:

       CGPoint pointSrc = self.button.layer.position;

       CGPoint pointDes = CGPointMake(pointSrc.x, pointSrc.y + 60);

       CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];

       anim.duration = 5;

       anim.fromValue = [NSValue valueWithCGPoint:pointSrc];

       anim.toValue = [NSValue valueWithCGPoint:pointDes];

       [self.button.layer addAnimation:anim forKey:nil];

                                 代码 1

Core Animation拥有以下优点:

1)       类似视图一样,可以通过CALayer创建复杂的一些动画

2)       系统支持的动画运行在独立的线程里面,并可以独立在主线程之外

3)       提供了一套较为简单的动画api接口,支持属性动画和并行动画

4)       属性动画中,提供了较为完善的动画属性设置,通过这些属性设置,使用者可以定制更为复杂的动画,如配置动画运动轨迹、运行速率、开始延迟时间等

5)       当动画配置完成并启动后,CoreAnimation会自动控制并完成相应的动画帧

6)       提供了CAEmitterLayer,很好地支持了粒子动画

7)       具有较高地应用性能,应用程序只有在发生改变的时候才重绘。

         而从使用者的另一个角度看,CoreAnimation也一些不太方便的地方:

1) 系统api并不支持全部的属性动画

         除了系统支持的属性动画,其余属性的动画并不能通过现成动画类(CABasicAnimationCAKeyframeAnimation)来实现动画,如使用者想要实现控件的宽度变化动画,此时使用者就可能就需要求助计时器,编写专门地代码,利用计时器不停地修改属性值,来达到动画效果。

2) 系统并没提供专门的api来完成串行动画

        CoreAnimation提供了CAAnimationGroup,但却没提供CAAnimationSequence,由此使用者如果需要实现一个由多个属性动画串行执行的动画,就必须自己动手编写相关的逻辑,如在每个属性动画的结束的监听函数 (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 当中启动下一个动画。

3) 动画执行的速率控制曲线并不是真正可以任意定义的

       系统中提供了5种自定义的变量, 来方便使用者描述动画执行速率,见图1.

             

       

          kCAMediaTimingFunctionLinear

         kCAMediaTimingFunctionEaseIn

           kCAMediaTimingFunctionEaseOut

               kCAMediaTimingFunctionEaseInEaseOut        

kCAMediaTimingFunctionDefault

1 系统自定义的速率控制曲线变量

         除此之外,使用者可以通过定义速率控制曲线(3bezier曲线)的中间2个控制点的坐标,来定制速率控制曲线,见代码2。使用bezier曲线会使动画过程比较光顺,然而也限制了使用者定义曲率会发生突变的曲线。

anim.timingFunction=[CAMediaTimingFunction functionWithControlPoints:0.2 :0.2 :0.8 :0.8];

                                                                           代码2

1.2 Android动画模块

         Android的动画模块,支持View的补间动画、桢动画和属性动画(android3.0引入)。相比iOSCore AnimatuonAndroid动画模块在以下几点更为方便:

1)    属性动画支持大部分属性

        对于系统直接支持的动画属性,可通过代码3view执行旋转动画

         ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F)

                                   .setDuration(500)

                                   .start();

                         代码3

       对于系统不直接支持的动画属性,可通过添AnimatorUpdateListener听,来修改属性值,见代码4

        ObjectAnimator anim = ObjectAnimator

                          .ofFloat(view, "anim", 1.0F, 0.0F)

                          .setDuration(500);

        anim.start();

        anim.addUpdateListener(new AnimatorUpdateListener(){ 

                 @Override 

                  public void onAnimationUpdate(ValueAnimator animation){

                   // here to change property values

                  } 

       }); 

                                  代码4

2)    允许用户自定义动画执行的速率控制曲线

         除了系统预定义的几种插值器外,如LinearInterpolator DecelerateInterpolator AccelerateInterpolatorAccelerateDecelerateInterpolator等之外,使用者可以自定义插值器,进而得到自己想要的插值器,来控制动画执行快慢。

3)    支持串行动画

         AnimatorSet不仅可以实现并行动画,同时也可以实现串行动画,见代码5

             AnimatorSet animSet = new AnimatorSet();

             animSet.play(anim1).before(anim2);

             animSet.play(anim2).with(anim3);

             animSet.play(anim2).with(anim4);

             animSet.play(anim5).after(amin2);

            animSet.start();

       代码5 动画执行顺序为anim1, (anim2, anim3, anim4同时执行), anim5

2 ColorTouch动画模块特性

         综上动画模块简介,可以看出其api对于使用者来说,还有如下几点不够友好,而ColorTouch的动画模块也就是从这几点入手,为使用者提供一套更为统一、友好、跨平台的api

2.1 属性动画的api统一性

        在Core Animation中,想实现width的变化动画,则需要通过其他的途径实现。在Android中,对于系统直接支持的属性动画,可用代码3实现;而对于系统不直接支持的,则必须添加监听,见代码4

        ColorTouch的动画模块为使用者提供了统一的接口,见代码6,使用者不再需要关心该动画类型是否是当前移动平台api支持的,只要该动画的属性对象是当前控件布局外观相关的一个属性。

           local animObj = Button{

                     id = "animationObj",

                     left=20,top=160,

                     width=40,height=20,

                     text="I'm a Button",

           }

           local colorAnim = PropertyAnimation{

                      propertyName = "color",

                      duration = 5,

                      fromValue = {r=255,g=255,b=255,a=1},

                      toValue = {r=255,g=0,b=0,a=1},

                      target = animObj,

                      startOffset = 1,

           }

           animator:addAnimation(colorAnim)

           local bgColorAnim = PropertyAnimation{

                      propertyName = "backgroundColor",

                      duration = 5,

                      fromValue = {r=0,g=0,b=0,a=1},

                      toValue = {r=0,g=255,b=0,a=1},

                      target = animObj,

                      startOffset = 1.5,

            }

            animator:addAnimation(bgColorAnim)

                               代码6

2.2  动画的自由组合能力

         在Core Animation中,由于没有直接支持的串行动画类,由此动画的组合能力也就仅限制于构造并行动画了。而在Android当中使用AnimatorSet能将其它的Animator进行组合,进而运行出复杂的动画效果,而使用withbeforeafter3个接口,个人觉得还是略繁琐。

         ColorTouch动画模块中提供了ParallelAnimationSequenceAnimation2个类,分别用于组合并行动画和串行动画,而组合出来的动画仍然是可组合的。通过组合性,可以创造出更为复杂的动画。

           local sequenceAnim1 = SequenceAnimation{

                     animations = {moveAnim,colorAnim,alphaAnim,},

           }

           local parallelAnim = ParallelAnimation{

                     animations = {scaleAnim,rotateAnim,},

           }

           local sequenceAnim2 = SequenceAnimation{

                      animations = {sequenceAnim1,parallelAnim,},

           }

           animator:addAnimation(sequenceAnim2)

                                  代码7

         sequenceAnim1定义了一个由3个属性动画组成的串行动画,parallelAnim定义了一个由2个属性动画组成的并行动画,sequenceAnim2定义了2个组合动画组成的串行动画。

2.3  逆动画

         Core Animation中,给动画类提供了autoReverse属性,并没有提供reverse接口来获取逆动画的实例。而在Android中,虽然对ValueAnimatorObjectAnimatorTimeAnimator提供了reverse接口,却没有对AnimatorSet提供这个接口,即Android对基本的属性动画和组合动画是区别对待的。

ColorTouch动画模块中为属性动画、串行动画、并行动画都提供了reverse接口,由此使用者不需要关心当前动画是最简单的属性动画,还是多次组合出来后的复杂动画,通过reverse接口都能获取逆动画的实例。

         local reverseAnim = complexAnim:reverse()

                                 代码8

2.4   动画速度控制

          Core Animation中的动画缓动曲线定义仅限于34控制点bezier曲线,而Android中则不受这个限制。为兼容iOSAndroidColorTouch动画模块中允许使用者自定义动画缓动曲线。当然在iOS下,使用自定义速度控制曲线的动画,则必须通过计时器完成动画。除此之外,使用者也可以使用预定义的速度控制曲线,如linearTimelineTypeaccelerateTimelineTypedecelerateTimelineTypeaccelerateDecelerateTimelineTypedecelerateAccelerateTimelineType,或是定义3bezier曲线中间2个控制点的位置来确定速度控制曲线。

相关阅读:ColorTouch动画模块(下)

本文来自网易实践者社区,经作者张云龙授权发布。