经过调研发现,SVG.js 和 Rapheal 都是直接使用脚本控制动画,而不是使用原生的动画标签。加上实现上的难度和维护的简易程度,以及后期拓展到不同底层的时候迁移的难度,决定使用脚本来进行动画控制。
主要由三个类来完成动画。Animator 进行动画定义,Timeline 进行动画控制,MotionAnimator 进行路径动画定义。
下面代码展示了如何使用动画。
var a = new Animator(0, 100, function( target, value ) {
target.setPositionX( value );
});
a.start(rect1, 1000, 'ease-in');
// or rect1.startAnimate( a, 1000, 'ease' );
a.start(rect2, 500, 'ease-out', 500);
a.on('finish', function( e ) {
console.log('the ' + e.target.getId() + ' has move right');
});
创建一个动画器,它产生从 beginVal 到 finishVal 变化的动画值。
beginVal, finishVal <Number|Color|Point|Matrix>
支持三种数据类型的值:数值、颜色、点和变换矩阵
setter(target, val) <Function>
指定动画值的使用方法,该方法接受两个参数:动画对象(target)以及当前动画值(val)。
创建一个动画器,它组合了给定的动画器,会让指定的动画按顺序播放。
在指定目标上创建动画时间线,并开始播放。
target <Object>
指定动画作用的目标对象。
duration <Number|String>
指定动画时长。如果为数字,则认为单位为 ms。如果为字符串,请指定单位(ms、s 或 min)。不指定将使用默认值 Animator.DEFUALT_DURATION(300)。
easing <String>
指定动画的播放曲线,不指定则使用默认值 Animator.DEFAULT_EASING("linear")
delay <Number|String>
指定动画延时,默认为 0。
return <Timeline>
返回动画的时间轴,用于对动画进行进一步控制
在指定目标上创建动画时间线,但先不开始播放。参数形式和意义和 start 方法一致,但是不包含 delay 参数的支持。
动画结束后的事件。对于每次调用 start 方法,都会产生一条时间线(Timeline)对象。只要 Timeline 对象播放结束,Animator 的 finish 事件会触发。
e.animateTarget <Object>
动画目标,和 start 方法中传入的目标一致
e.animateTimeline <Timeline>
和动画目标关联的 Timeline 对象
获取时间轴当前状态,有以下值:
playing 当前正在播放
paused 已暂停
stoped 已停止
finished 播放结束
获取产生该 Timeline 的 animator
暂停当前正在播放的动画。会让动画对象在当前值上暂停。
停止当前正在播放的动画。会让动画对象结束在最终值上。
play 方法的操作决定于时间线的状态:
playing: 不做任何操作
paused: 继续播放动画
stoped: 重头开始播放动画
finished: 重头开始播放动画
循环播放当前的动画
repeat <int|bool>
指定是否循环或循环的次数。指定为 true 则无限循环。
rollback <bool>
表示是否在循环之间插入回滚播放的动画
时间线在变为播放时触发的事件。注意,如果时间线本来就在播放状态,play() 方法不会触发该事件。
e.target <Object>
动画目标
e.lastStatus <"paused"|"stoped"|"finished">
动画播放之前的状态
产生沿着指定 Path 运动的动画,setter 中接受 Point 作为坐标参数。
*该功能需要图形方法:getPathPosition()
var path = new Path('M0 0 C100 0 100 0 100 100')
var m = new MotionAnimator(path, function(target, point) {
target.setTransform(new Matrix().translate(point.x, point.y));
});