Skip to content
Advertisement

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>

Advertisement

Answer

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>
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement