Skip to content Skip to sidebar Skip to footer

Can (endless) Css Keyframe Animations Be Stopped At Certain Time Point Or A Defined Keyframe?

I am trying to find out if CSS today offers enough tools to have animations run until an event tells them to stop? Yes this is possible see snippet, however: This animation will ju

Solution 1:

You can pause and resume CSS animations using animation-play-state and toggling a class:

CSS:

.paused {
  animation-play-state: paused;
  -webkit-animation-play-state: paused;
}

Snippet:

functionpause() {
    wrap.classList.add("paused");
}

functionplay() {
    wrap.classList.remove("paused");
}
.paused {
  animation-play-state: paused;
  -webkit-animation-play-state: paused;
}

#wrap {
  background-color: yellow;
  position: relative;
  top: 0px;
  width: 100px;
  height: 100px;
  border-radius: 50px;
  box-sizing: border-box;
  transition: 700ms linear;
  animation-iteration-count: infinite;
}

#wrap:hover {
  background-color: orange;
}

#mouth {
  background-color: transparent;
  position: absolute;
  border-left: 4px solid black;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  border-radius: 0060px60px;
  height: 30px;
  width: 60px;
  top: 52px;
  left: 20px;
  box-sizing: border-box;
  display: inline-block;
  overflow: hidden;
  padding: 0;
}

#left-eye {
  position: absolute;
  background-color: black;
  border-radius: 50%;
  width: 8px;
  height: 16px;
  box-sizing: border-box;
  left: 30px;
  top: 25px;
  display: inline-block;
  overflow: hidden;
  padding: 0;
}

#right-eye {
  position: absolute;
  background-color: black;
  border-radius: 50%;
  width: 8px;
  height: 16px;
  box-sizing: border-box;
  top: 25px;
  right: 30px;
  display: inline-block;
  overflow: hidden;
  padding: 0;
}

#wrap {
  animation-duration: 1200ms;
  animation-name: rotateDiv;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

@keyframes rotateDiv {
  from {
  -ms-transform: rotate(0deg); /* IE 9 */
  -webkit-transform: rotate(0deg); /* Safari */transform: rotate(0deg);
  }

  to {
  -ms-transform: rotate(360deg); /* IE 9 */
  -webkit-transform: rotate(360deg); /* Safari */transform: rotate(360deg);
  }
}
<divid = "wrap"class = "paused"><divid = "left-eye">&nbsp;</div><divid = "right-eye">&nbsp;</div><divid = "mouth">&nbsp;</div></div><inputtype = "button"value = "start"onClick = "play()"><inputtype = "button"value = "stop"onClick = "pause()">

Solution 2:

You may want to consider adjusting the animation play state rather than the iteration count. This will allow you to stop the animation at your desired point, but not reset it to the beginning.

functionplay() {
  let target = document.getElementById('wrap')
  target.style.animationPlayState = 'running'let styles = getComputedStyle(target)
  console.log(styles.getPropertyValue('animation-play-state'))
}

functionpause() {
  let target = document.getElementById('wrap')
  target.style.animationPlayState = 'paused'let styles = getComputedStyle(target)
  console.log(styles.getPropertyValue('animation-play-state'))
}
#wrap {
  background-color: yellow;
  position: relative;
  top: 0px;
  width: 100px;
  height: 100px;
  border-radius: 50px;
  box-sizing: border-box;
  transition: 700ms linear;
  animation-iteration-count: infinite;
}

#wrap:hover {
  background-color: orange;
}

#mouth {
  background-color: transparent;
  position: absolute;
  border-left: 4px solid black;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  border-radius: 0060px60px;
  height: 30px;
  width: 60px;
  top: 52px;
  left: 20px;
  box-sizing: border-box;
  display: inline-block;
  overflow: hidden;
  padding: 0;
}

#left-eye {
  position: absolute;
  background-color: black;
  border-radius: 50%;
  width: 8px;
  height: 16px;
  box-sizing: border-box;
  left: 30px;
  top: 25px;
  display: inline-block;
  overflow: hidden;
  padding: 0;
}

#right-eye {
  position: absolute;
  background-color: black;
  border-radius: 50%;
  width: 8px;
  height: 16px;
  box-sizing: border-box;
  top: 25px;
  right: 30px;
  display: inline-block;
  overflow: hidden;
  padding: 0;
}

#wrap {
  animation-duration: 1200ms;
  animation-name: rotateDiv;
  animation-iteration-count: 0;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-play-state: paused;
}

@keyframes rotateDiv {
  from {
  -ms-transform: rotate(0deg); /* IE 9 */
  -webkit-transform: rotate(0deg); /* Safari */transform: rotate(0deg);
  }

  to {
  -ms-transform: rotate(360deg); /* IE 9 */
  -webkit-transform: rotate(360deg); /* Safari */transform: rotate(360deg);
  }
}
<divid='wrap'><divid='left-eye'>&nbsp;</div><divid='right-eye'>&nbsp;</div><divid='mouth'>&nbsp;</div></div><inputtype='button'value='start'onClick="play()"><inputtype='button'value='stop'onClick="pause()">

Edit:

If you want to access information regarding a component's computed styles, you can use the getComputedStyle function. This will provide information within Javascript about all of an element's computed styles. The returned value from getComputedStyle can be used with the getPropertyValue function to provide information regarding a specific property.

Solution 3:

This was very useful so far, yet the remaining question related to these answers:

I added window.getComputedStyle(wrap, null).getPropertyValue("transform") and write it to an output field. This returns the matrix state of the animation. How should the matrix be interpreted to know at what rotation degree or what keyframe it was paused? I found 4 float values in the matrix. Some values seem to be always the same as, or the negative value of one other value. So I guess I can calculate back to milliseconds with these values?

Or maybe there is a different property to read from with getComputedStyle() that makes this a bit simpler?

I have moved the snipped to a new more detailed question at: How can an animation keyframe or time offset be calculated from a CSS transform matrix?

Post a Comment for "Can (endless) Css Keyframe Animations Be Stopped At Certain Time Point Or A Defined Keyframe?"