經過時間扭曲實現緩動動畫

經過時間扭曲實現緩動動畫

常常會見到各種緩動函數,在CSS裏面有現成的bounce、elastic等緩動效果直接用。若是在canvas動畫中,咱們要實現這些緩動函數。直接去思考怎麼處理挺頭疼的,介紹一種不錯的實現方式,源自《HTML5 Canvas核心技術》。canvas

此次的實踐在一個封裝的基礎上,請參考:canvas精靈封裝segmentfault

Begin

緩動動畫的本質,是在單位時間內移動不一樣的距離。函數

一個簡單的公式:距離 = 速度 × 時間;動畫

要實現距離緩動,只有兩種方式:this

  • 要麼保持時間正常流動,實現速度緩動;spa

  • 要麼保持速度不變實現時間扭曲;code

下圖是elastic效果的距離與時間函數,我亂拿了一個三角函數圖像,忽略掉負軸就好ip

clipboard.png

△V = △S / △T,理論上對距離/時間曲線進行求導,獲得速度的變化曲率,改變速度也能實現。ci

此次實現的是保持速度不變,扭曲時間實現緩動:get

一、每一個動畫時間固定,經過時間能獲取到動畫進度:

先給出時間扭曲函數:

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;
    };
};

函數圖像:

clipboard.png

經過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);
            
        }
    }
相關文章
相關標籤/搜索