简体   繁体   中英

Using RequestAnimationFrame to create Fade in effect

I know this can be done by using CSS transition, however this 2 seconds fade-in exercise has to be done by using requestAnimationFrame, below is my code, it shows the picture but no fade in effect, also the render process is not smooth. Could you tell me where i get wrong and how to correct it? Thanks very much.

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { height: 100vh; } #picture { background-image: url("p1.jpg"); background-repeat: no-repeat; background-position: center; background-size: 400px 400px; width: 80%; margin: auto; height: 80%; } </style> </head> <body> <div id="picture"></div> <script> var start = null; var abc = document.getElementById("picture") var opacity = 0; function step(timestamp) { if (!start) start = timestamp; var progress = timestamp - start; opacity = Number(window.getComputedStyle(abc).getPropertyValue("opacity")); if (opacity < 1) { opacity = opacity + 0.1; abc.style.opacity = opacity; } if (progress < 2000) { window.requestAnimationFrame(step); } } window.requestAnimationFrame(step); </script> </body> </html>

Your script never sets the opacity of the abc element to 0, so the opacity you read in the step function, will always be 1.

So add this line in the initialisation part:

abc.style.opacity = 0;

This shows the animation, but as you add 0.1 in each step, the fading will be completed in 10 frames, which is quite fast.

Here is an adapted version of your code:

 function animateOpacity(abc, duration) { let start; function step(timestamp) { if (!start) start = timestamp; const opacity = (timestamp - start) / duration; abc.style.opacity = opacity; if (opacity >= 1) return; window.requestAnimationFrame(step); } window.requestAnimationFrame(step); } const abc = document.getElementById("picture"); abc.style.opacity = 0; window.addEventListener("load", () => animateOpacity(abc, 3000));
 body { height: 100vh; } #picture { background-image: url("https://i.stack.imgur.com/440u9.png"); background-repeat: no-repeat; background-position: center; background-size: contain; width: 80%; margin: auto; height: 80%; }
 <div id="picture"></div>

You have two problems.


The first is that you haven't set opacity in the CSS, so when you call opacity = Number(window.getComputedStyle(abc).getPropertyValue("opacity")); it starts out at 1 and never gets changed.

Add opacity: 0 to the #picture { rules.


window.requestAnimationFrame will be called at variable intervals depending on how busy the browser is.

This is why you have a calculation for progress which tells you how far between "the start" and "2 seconds later" you are.

Your calculation for opacity completely ignores progress . It just increments by 0.1 every time you get a new frame.

Since frames are usually quite frequent, you get from 0 to 1 in 10 frames which is very quick.

You need to calculate opacity as a proportion of progress and not make it completely independent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM