通过时间扭曲实现缓动动画
经常会见到各类缓动函数,在CSS里面有现成的bounce、elastic等缓动效果直接用。如果在canvas动画中,我们要实现这些缓动函数。直接去思考怎么处理挺头疼的,介绍一种不错的实现方式,源自《HTML5 Canvas核心技术》。
这次的实践在一个封装的基础上,请参考:canvas精灵封装
Begin
缓动动画的本质,是在单位时间内移动不同的距离。
一个简单的公式:距离 = 速度 × 时间;
要实现距离缓动,只有两种方式:
要么保持时间正常流动,实现速度缓动;
要么保持速度不变实现时间扭曲;
下图是elastic效果的距离与时间函数,我乱拿了一个三角函数图像,忽略掉负轴就好
△V = △S / △T,理论上对距离/时间曲线进行求导,得到速度的变化曲率,改变速度也能实现。
这次实现的是保持速度不变,扭曲时间实现缓动:
1、每个动画时间固定,通过时间能获取到动画进度:
先给出时间扭曲函数:
f(x) = ((1 - cos(x * pi * 3)) * (1-x)) + x
转换成代码:
var makeElastic = function (passes) {// passes是跳动的次数
passes = passes || 3;
return function (percentComplete) {
return ((1-Math.cos(percentComplete * Math.PI * passes)) *
(1 - percentComplete)) + percentComplete;
};
};
函数图像:
通过Sprite封装的behavior来实现时间扭曲
var moveBall = {
updateBallPosition: function(elapsed){
if (arrow === LEFT){
ball.left -= ball.velocityX * (elapsed/1000);
} else{
ball.left += ball.velocityX * (elapsed/1000);
}
},
execute: function(ball, context,time){
// 核心!
// 这里的animationElapsed是被扭曲过的时间
// getElapsedTime()就是上面的makeElastic
// 经过一些封装,传入t得出扭曲过的时间
var animationElapsed = pushAnimationTimer.getElapsedTime(),
elapsed;
elapsed = animationElapsed - this.lastTime;
this.updateBallPosition(elapsed);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。