Slow motion animation by time warping


Slow motion animation by time warping

We often see all kinds of jogging functions. In CSS, there are ready-made jogging effects such as bounce and elastic, which can be used directly. If we want to implement these jog functions in canvas animation. It’s a headache to think about how to deal with it directly. This paper introduces a good implementation method, which comes from HTML5 canvas core technology.

This practice is based on a package. Please refer to:Canvas sprite encapsulation


The essence of slow motion animation is to move different distances in unit time.

A simple formula: distance = speed × Time;

There are only two ways to realize distance jog

  • Either keep the normal flow of time, realize the slow motion of speed;

  • Either keep the speed unchanged to achieve time warping;

The figure below is the distance and time function of elastic effect. I took a trigonometric function image randomly and ignored the negative axis

Slow motion animation by time warping

△ v = △ s / △ T. theoretically, the derivative of the distance / time curve is obtained to obtain the change curvature of the velocity, which can also be realized by changing the velocity.

This time, the goal is to keep the speed unchanged and twist the time to achieve slow motion

1. Each animation time is fixed, and the animation progress can be obtained through time

Firstly, the time warping function is given

f(x) = ((1 - cos(x * pi * 3)) * (1-x)) + x

Convert to code:

Var makeelastic = function (passes) {// passes is the number of jumps
       passes = passes || 3;
       return function (percentComplete) {
           return ((1-Math.cos(percentComplete * Math.PI * passes)) *
               (1 - percentComplete)) + percentComplete;

Function image:

Slow motion animation by time warping

Time warping is realized by sprite encapsulated 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){
            //The core!
            //Here's animationelapsed, which is the distorted time
            //Getelassedtime() is the makeelastic above
            //After some encapsulation, we can get the distorted time
            var animationElapsed = pushAnimationTimer.getElapsedTime(),
            elapsed = animationElapsed - this.lastTime;