Ghoyos Ghoyos - 4 months ago 12
CSS Question

How to call in Javascript a requestAnimationFrame loop?

I watched a video describing how to use requestAnimationFrame to loop a animation. I tried to replicate it and believe I am very close but am missing a key point. When I click the "box" the onclick="loopKeyFrame()" activates and calls runKeyFrame() only once?

My intention was to loop runKeyframe() infinitely with this code. I know I can put "infinite" in the css to make it run forever but thats not the point. im trying to use requestAnimationFrame as was used in the video.

My code in CodePen

<html>
<head>
<title>RequestAnimation Lesson</title>
<style>
body {
background-color: grey;
}

#box {
position:relative;
width:30px;
border:1px solid blue;
background-color:blue;
height:10px;
top:0px;
left:0px;
}

@keyframes myMove {
0%{left:0%;}
50%{left:95%;}
100%{left:0%;}
}
</style>
<script>

function runKeyFrame() {
document.getElementById("box").style.animation = "myMove 4s";
}

function loopKeyFrame() {
runKeyFrame();
requestAnimationFrame(loopKeyFrame);
}



</script>
</head>
<body>
<div id="box" onclick="loopKeyFrame()"></div>
</body>
</html>

Answer

You can add and remove a className instead of setting style of element, use setTimeout to call requestAnimationFrame with loopKeyFrame as parameter after four seconds.

function runKeyFrame() {
  document.getElementById("box").className = "myMove";
}

function loopKeyFrame() {
  runKeyFrame();
  setTimeout(function() {
    document.getElementById("box").className = ""
    requestAnimationFrame(loopKeyFrame)
  }, 4000)
}
body {
  background-color: grey;
}

#box {
  position: relative;
  width: 30px;
  border: 1px solid blue;
  background-color: blue;
  height: 10px;
  top: 0px;
  left: 0px;
}

.myMove {
  animation: myMove 4s;
}

@keyframes myMove {
  0% {
    left: 0%;
  }
  50% {
    left: 95%;
  }
  100% {
    left: 0%;
  }
}
<div id="box" onclick="loopKeyFrame()"></div>


You could alternatively use .animate(), finish event handler to recursively call loopKeyFrame

function runKeyFrame() {
  loopKeyFrame()
}

function loopKeyFrame() {
  document.getElementById("box")
    .animate([{
      left: "0%"
    }, {
      left: "95%"
    }, {
      left: "0%"
    }], {
      duration: 4000,
      iterations: 1
    })
    .onfinish = runKeyFrame;
}
body {
  background-color: grey;
}
#box {
  position: relative;
  width: 30px;
  border: 1px solid blue;
  background-color: blue;
  height: 10px;
  top: 0px;
  left: 0px;
}
<div id="box" onclick="loopKeyFrame()"></div>