Pure JavaScript - Timed Animation - Consistent height?

时间:2016-04-21 21:48:27

标签: javascript animation timed

I have created a script that animates the height of an element in 500ms.

The timer works fine but I am struggling to make the height increase consistently.

How do I animate the height smoothly within the time period? It jumps at the moment.

I want to replace the following with something smarter:

self.startHeight + 5

I imagine it has something to do with the speed and elapsed time?

https://jsfiddle.net/zrm7xena/1/

(function () {
    'use strict';

    var animator = {};

    animator.endHeight = 200; //The end height
    animator.interval = null; //Create a variable to hold our interval
    animator.speed = 500; //500ms
    animator.startHeight = 0; //The start height

    animator.animate = function (el) {
        var self = this,
            startTime = Date.now(); //Get the start time

        this.interval = setInterval(function () {
            var elapsed = Date.now() - startTime, //Work out the elapsed time
                maxHeight = self.maxHeight; //Cache the max height 

            //If the elapsed time is less than the speed (500ms)
            if (elapsed < self.speed) {
                console.log('Still in the timeframe');

                //If the client height is less than the max height (200px)
                if (el.clientHeight < self.endHeight) {
                    self.startHeight = self.startHeight + 5; //Adjust the height
                    el.style.height = self.startHeight + 'px'; //Animate the height
                }
            } else {
                console.log('Stop and clear the interval');
                el.style.height = self.endHeight + 'px';
                clearInterval(self.interval);
            }
        }, 16); //60FPS
    };

    animator.animate(document.getElementById('box'));
}());

Thanks in advance!

Carorus gave a great answer below. I have updated my jsfiddle so you can see the final code working:

https://jsfiddle.net/zrm7xena/8/

Typhoon posted a great link in relation to the browser FPS:

How to determine the best "framerate" (setInterval delay) to use in a JavaScript animation loop?

I would probably use request animation frame instead of a setInterval:

http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

Cheers all!

1 个答案:

答案 0 :(得分:2)

The harcoded 5 that you are using for the height increment doesn't allow the animation to complete the entire final height (200) in the time that you are setting (500ms), you need to calculate the height increment based on the final height, the animation time and the interval to make it consistent:

(function () {
'use strict';

var animator = {};

animator.endHeight = 200; //The end height
animator.interval = null; //Create a variable to hold our interval
animator.speed = 500; //500ms
animator.startHeight = 0; //The start height
animator.interval = 16;

animator.animate = function (el) {
    var self = this,
    startTime = Date.now(); //Get the start time
    //calculating height variation
    self.deltaHeight = (animator.endHeight / animator.speed) * animator.interval;
    this.intervalId = setInterval(function () {
        var elapsed = Date.now() - startTime, //Work out the elapsed time
            maxHeight = self.maxHeight; //Cache the max height 

        //If the elapsed time is less than the speed (500ms)
        if (elapsed < self.speed) {
            console.log('Still in the timeframe');

            //If the client height is less than the max height (200px)
            if (el.clientHeight < self.endHeight) {
                self.startHeight = self.startHeight + self.deltaHeight; //Adjust the height
                el.style.height = self.startHeight + 'px'; //Animate the height
            }
        } else {
            console.log('Stop and clear the interval');
            el.style.height = self.endHeight + 'px';
            clearInterval(self.intervalId);
        }
    },  animator.interval); //60FPS
};

animator.animate(document.getElementById('box'));
}());