Home  >  Article  >  Web Front-end  >  A brief analysis of the implementation principles of Javascript animation_javascript skills

A brief analysis of the implementation principles of Javascript animation_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:11:451121browse

Suppose there is such an animation function requirement: change the width of a div from 100px to 200px. The code written may look like this:

Copy code The code is as follows:


function animate1(element, endValue, duration) {
var startTime = new Date(),
         startValue = parseInt(element.style.width),
         step = 1;
 
var timerId = setInterval(function() {
        var nextValue = parseInt(element.style.width) step;
          element.style.width = nextValue 'px';
If (nextValue >= endValue) {
               clearInterval(timerId);
// It takes time to display the animation
                element.innerHTML = new Date - startTime;
}
}, duration / (endValue - startValue) * step);
}

animate1(document.getElementById('test1'), 200, 1000);


The principle is to increase 1px at regular intervals until it reaches 200px. However, the display time after the animation ends is more than 1s (usually about 1.5s). The reason is that setInterval does not strictly guarantee the execution interval.

Is there a better way? Let’s take a look at a primary school math problem:

Copy code The code is as follows:

Building A and Building B are 100 meters apart. A person walks from Building A to Building B at a constant speed and walks for 5 minutes to reach the destination. How far is he from Building A at the third minute?

The calculation formula for calculating the distance at a certain moment in uniform motion is: distance * current time / time. So the answer should be 100 * 3 / 5 = 60 .

The inspiration brought by this question is that the distance at a certain moment can be calculated through a specific formula. In the same way, the value at a certain moment during the animation process can also be calculated through a formula instead of accumulating:

Copy code The code is as follows:


function animate2(element, endValue, duration) {
var startTime = new Date(),
         startValue = parseInt(element.style.width);

var timerId = setInterval(function() {
      var percentage = (new Date - startTime) / duration;

var stepValue = startValue (endValue - startValue) * percentage;
          element.style.width = stepValue 'px';

if (percentage >= 1) {
               clearInterval(timerId);
                element.innerHTML = new Date - startTime;
}
}, 13);
}

animate2(document.getElementById('test2'), 200, 1000);

After this improvement, you can see that the animation execution time will only have an error of 10 ms at most. But the problem has not been completely solved. Checking the test2 element in the browser development tool shows that the final width of test2 may be more than 200px. Careful inspection of the code of the animate2 function reveals:

The value of 1.percentage may be greater than 1, which can be solved by limiting the maximum value through Math.min.
2. Even if it is guaranteed that the value of percentage is not greater than 1, as long as endValue or startValue is a decimal, the value of (endValue - startValue) * percentage may still produce errors because the precision of Javascript decimal operations is not enough. In fact, what we want to ensure is the accuracy of the final value, so when the percentage is 1, just use endValue directly.

So, the code of animate2 function is modified to:

Copy code The code is as follows:

function animate2(element, endValue, duration) {
var startTime = new Date(),
         startValue = parseInt(element.style.width);

var timerId = setInterval(function() {
​​​​ // Ensure that the percentage is not greater than 1
      var percentage = Math.min(1, (new Date - startTime) / duration);

var stepValue;
If (percentage >= 1) {
​​​​​​ // Ensure the accuracy of the final value
             stepValue = endValue;
         } else {
             stepValue = startValue (endValue - startValue) * percentage;
}
          element.style.width = stepValue 'px';

if (percentage >= 1) {
               clearInterval(timerId);
                element.innerHTML = new Date - startTime;
}
}, 13);
}

There is one last question: Why is the interval of setInterval set to 13ms? The reason is that the refresh rate of current monitors generally does not exceed 75Hz (that is, refreshed 75 times per second, that is, refreshed every about 13ms). It is better to synchronize the interval with the refresh rate.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn