Philip Eagles Philip Eagles - 8 days ago 3
CSS Question

JavaScript if CSS animation ended

I am making a game in HTML/JavaScript and as part of this there is a "special ability" that can only be triggered every x seconds. I have created a GUI element that displays whether the ability is yet ready for use. Because I am using CSS animations, I want to check if, on a keypress, the element has finished animating (indicating that it is ready).

I want to do this in a simple if statement, rather than using

addEventListener
but I am not sure if this is possible.

My code so far is:



var keystate = {};

window.addEventListener("keydown", function(e) {
keystate[e.keycode || e.which] = true;
}, true);
window.addEventListener("keyup", function(e) {
keystate[e.keycode || e.which] = false;
}, true);

window.setInterval(function() {
if (keystate[87]) { //w key, THIS is where I want to check if the animation has completed as well
//do stuff
document.getElementById("circle_flash_glow").classList.add("circle_flash_use");
}
}, 16.666666666666667);

#svg_circle_loader {
position: absolute;
right: 0;
bottom: 0;
background: none;
border: none;
margin: none;
padding: none;
}
#circle_flash_loader {
fill: none;
stroke: #F00;
stroke-width: 10px;
stroke-dashoffset: 80;
animation-fill-mode: forwards;
}
.circle_loader_load {
animation: circle_flash_loading linear;
animation-duration: 2.5s;
}
@keyframes circle_flash_loading {
0% {
stroke-dasharray: 0, 314;
}
100% {
stroke-dasharray: 314, 0;
}
}
#circle_flash_glow {
fill: none;
stroke: #F00;
stroke-width: 0px;
animation-fill-mode: forwards;
opacity: 1;
}
.circle_flash_use {
animation: circle_flash_pulse 0.6s ease-out;
}
@keyframes circle_flash_pulse {
0% {
opacity: 1;
stroke-width: 0px;
}
100% {
opacity: 0;
stroke-width: 70px;
}
}

<svg id="svg_circle_loader" width="200" height="200">
<defs>
<filter id="f1" x="-50" y="-50" width="200" height="200">
<feGaussianBlur stdDeviation="5"></feGaussianBlur>
</filter>
</defs>
<circle cx="100" cy="100" r="50" id="circle_flash_glow" class="" filter="url(#f1)"></circle>
<circle cx="100" cy="100" r="50" id="circle_flash_loader" class="circle_loader_load"></circle>
</svg>




Answer

Add a variable to set the current state, and set it with setTimeout() for checking whether it is animating or not. also add window.onload to get its state by adding

window.onload=function(){
  animating=true;
  sts.value=animating;
  window.setTimeout(function() {
    animating=false;
    sts.value=animating;
  }, 2500);
};

where I am using 2500. because your css animation property has 2.5s=2500ms

var animating = false;
var keystate = {};

window.addEventListener("keydown", function(e) {
  keystate[e.keycode || e.which] = true;
}, true);
window.addEventListener("keyup", function(e) {
  keystate[e.keycode || e.which] = false;
}, true);

window.setInterval(function() {
  if (keystate[87]) { //w key, THIS is where I want to check if the animation has completed as well
    //do stuff
    if (!animating) {
      alert("animation finished");
      document.getElementById("circle_flash_glow").classList.add("circle_flash_use");
    }
  }
}, 16.666666666666667);

window.onload = function() {
  animating = true;
  sts.value = animating;
  window.setTimeout(function() {
    animating = false;
    sts.value = animating;
  }, 2500);
};
#svg_circle_loader {
  position: absolute;
  right: 0;
  bottom: 0;
  background: none;
  border: none;
  margin: none;
  padding: none;
}
#circle_flash_loader {
  fill: none;
  stroke: #F00;
  stroke-width: 10px;
  stroke-dashoffset: 80;
  animation-fill-mode: forwards;
}
.circle_loader_load {
  animation: circle_flash_loading linear;
  animation-duration: 2.5s;
}
@keyframes circle_flash_loading {
  0% {
    stroke-dasharray: 0, 314;
  }
  100% {
    stroke-dasharray: 314, 0;
  }
}
#circle_flash_glow {
  fill: none;
  stroke: #F00;
  stroke-width: 0px;
  animation-fill-mode: forwards;
  opacity: 1;
}
.circle_flash_use {
  animation: circle_flash_pulse 0.6s ease-out;
}
@keyframes circle_flash_pulse {
  0% {
    opacity: 1;
    stroke-width: 0px;
  }
  100% {
    opacity: 0;
    stroke-width: 70px;
  }
}
<svg id="svg_circle_loader" width="200" height="200">
  <defs>
    <filter id="f1" x="-50" y="-50" width="200" height="200">
      <feGaussianBlur stdDeviation="5"></feGaussianBlur>
    </filter>
  </defs>
  <circle cx="100" cy="100" r="50" id="circle_flash_glow" class="" filter="url(#f1)"></circle>
  <circle cx="100" cy="100" r="50" id="circle_flash_loader" class="circle_loader_load"></circle>
</svg>
<input id="sts" value="" />