Before reading this article I was hoping that you would be able to use setTimeout for simple animations, that is, using recursion instead of setInterval for animations.
RequestAnimationFrame (), which replaces timers to create smoother and higher performance animations that match the refresh rate of the device, solves the problem of timer animation interval instability (i.e., timer animation is not smooth). Its use is similar to setTimeout.
Like setTimeout, which returns a unique identifier, setTimeout can be turned off by clearTImeout(). So requestAnimationFrame() uses cancelAnimationFrame() to close the animation.
The difference with this method is that you only need to pass in a callback function, no other parameters are required, so you are wondering how to do animation without specifying the time interval.
The time interval is naturally there, but the time interval is determined by the system of the device (independent of other tasks). Normally your incoming callback will be executed 60 times per second, but if your device’s browser follows W3c standards, the number of times per second the callback will be executed will match your device’s refresh rate. Not only that, but it’s also a high-performance way to stop animation on most browsers as soon as the page is not in the browser’s current TAB.
If we use timer setTimeout for animation, we assume that the monitor has a refresh rate of 60Hz (60Hz refers to 60 animations played at 1 second). To make the animation look smooth, we need to set the timer setTimeout interval ** “1000/60” ** that is 60 callbacks per second, approximately every 16.67 milliseconds, to match the frame rate of the display. Seems like a perfect match the problem actually there will be caton, because the timer belongs to macro task, and macro task must wait for synchronization task to complete, wait for micro tasks completed will perform the callback function (task queue, the callback function to see this article, there is no detail), so you specified time interval is unstable inaccurate.
Here is an animation of a horizontal element, comparing requestAnimationFrame with setTimeout.
SetTimeout () :
const box = document.querySelector('.box');
let move;
let timer = setTimeout(function fn() {
move = parseInt(getComputedStyle(box).left);
if (move < 800) {
box.style.left = move + 8 + 'px';
setTimeout(fn, 1000/60);
} else {
clearTimeout(timer); }},1000/60);
Copy the code
RequestAnimationFrame () draws elements horizontally:
const box = document.querySelector('.box');
let move;
let timer = requestAnimationFrame(function fn() {
move = parseInt(getComputedStyle(box).left);
if (move < 800) {
box.style.left = move + 8 + 'px';
requestAnimationFrame(fn);
} else{ cancelAnimationFrame(timer); }});Copy the code
Now that you know the basics, you can use requestAnimationFrame() to animate
If you’re worried about compatibility, here’s what you can do (here’s the code from Ruan Yifeng)
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60); }; }) ();Copy the code
Conclusion:
- RequestAnimationFrame () automatically matches the frame rate of the device to display the animation (120 frames per second).
- High performance and no animation lag
- There will be compatibility issues with the viewer
The reason for summarizing this article is that RECENTLY I was writing a VUE project which needed to realize the function of clicking back to the top. Since it was a mobile terminal project, the refresh rate of mobile terminal devices could not be uniform, so I used this API, and then found it was really sweet!! I have returned to the top of the function package into a component (component source point here), in learning vUE partners can refer to my code, also hope you give some advice.
You can also follow me if you are interested:
CNSD: m0_46217225
Nuggets: buzz cut boy
Making: Buzz_cut
Wechat official account: web_mycode
Man with a buzz cut
My QQ: 2356924146
I will continue programming dry stuff.