Stopping a CSS Animation But Letting Its Current Iteration Finish

Stopping a CSS animation but letting its current iteration finish

Stop the animation upon receiving an animationiteration event. Something like this (using jQuery):

CSS

@-webkit-keyframes rotate {
to {
-webkit-transform: rotate(360deg);
}
}
.rotate {
width: 100px;
height: 100px;
background: red;
}
.rotate.anim {
-webkit-animation-name: rotate;
-webkit-animation-duration: 5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}

HTML

<div class="rotate anim">TEST</div>
<input id="stop" type="submit" value="stop it" />

JS (JQuery)

$("#stop").click(function() {
$(".rotate").one('animationiteration webkitAnimationIteration', function() {
this.classList.remove("anim");
});
});

Fiddle: http://jsfiddle.net/jmp2fakn/

Note that I'm using .one here (not .on) so that the handler only runs once. That way, the animation can later be restarted.

Css keyframe loop, finish iteration of animation on element with multiple animations

So I found out why it didn't work. There is some additional information in how I've managed to get it to work after all, that I'll explain here.

It was my fault because there is another animation attached sub element:

<div id="a1"> <-- Main animation that should finish the loop
<div id="a2"></div> <-- sub animation that should not be finished
</div>

That was the reason why the animation call backs where triggered more often than expected. But: I found out that I can filter by animation name!

$("#a1").on('animationiteration webkitAnimationIteration', function(e) {
/* this triggers not only when animation of #a1 iterated but also if animation of #a2 iterated */
let animation_name = e.originalEvent.animationName;
if(animation_name == "animation1name"){
//This will only trigger if the correct animation iterated
}
});

I hope this solution can help someone who tries to handle multiple looping animations applied to one element (or sub element)

Thanks to everyone else who helped! ( I adjusted the question title in order to highlight what the problem actually was )

Smooth animation stop

It's not possible without JS.
What you can do with CSS is that the animation will be paused by unchecking the checkbox and continues if you check the box again:

#toggle:checked ~ #jumping-div {
animation-play-state:running;
}

#jumping-div {
animation-play-state:paused;
animation-name: jump;
animation-duration: 2.0s;
animation-iteration-count: infinite;
}

If you want to finish on animation you may use the solution WITH JS that was discussed here:
Stopping a CSS animation but letting its current iteration finish

Break infinite animation in css

There is no way without javascript.You need to use "animationiteration" event to remove the "rotating" class. so whenever you decide to set the current iteration the last one, add a "on" or "one" EventHandler to your element and inside the listener remove animation class.

this should do the job :

$(".rings").one('animationiteration', function() {
$(this).removeClass("rotating");
});

Maintaining the final state at end of a CSS3 animation

Try adding animation-fill-mode: forwards;. For example like this:

-webkit-animation: bubble 1.0s forwards; /* for less modern browsers */
animation: bubble 1.0s forwards;

CSS animation suddenly ends

Thanks for your suggestions. I did it using JS and animationiteration event.

HTML:

<div class="spinner">
<i class="material-icons refresh-icon" onclick="spinner(this)">refresh</i>
</div>

JS:

const spinner = el => {
if($(el).hasClass('lock')) return;

if($(el).hasClass('loading')){
$(el).addClass('lock').one('animationiteration webkitAnimationIteration', function() {
$(el).removeClass('loading').removeClass('lock');
});
}else{
$(el).addClass('loading');
}
}

Link to codepan: https://codepen.io/nenazarko/pen/zYGPoZy

SVG CSS animation after hover off

You can't do what you want with pure CSS. You need to use JS.

Here's one way, using the animationiteration event, which fires each time the animation loop ends.

// Get the SVG DOM objectvar mysvg = document.getElementById("mysvg");var running = false;
// On hover add the "run" class, which makes the animation runmysvg.addEventListener("mouseenter", function(evt) { evt.target.classList.add("run"); running = true;});
// On mouse out, arrange to remove the "run" class when the animation loop endsmysvg.addEventListener("mouseleave", function(evt) { running = false;});
// When animation loop ends, remove the "run" class if we no longer want to continue runningmysvg.addEventListener("animationiteration", function(evt) { if (!running) { evt.target.ownerSVGElement.classList.remove("run"); }});
.box {  width: 300px;  height: 500px;}
<div class="box">  <svg id="mysvg" width="100%" height="100%" viewBox="-30 0 250 500" version="1.1" xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">      <rect x="0" y="5" width="100" height="100" fill="red" />    <path id="heart" class="heart" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z" fill="#fff"/>   


<style type="text/css"> svg .heart { } .run .heart { animation-timing-function: ease-in-out; animation-duration: 4s; animation-iteration-count: infinite; animation-name: rotation; animation-direction: normal; animation-fill-mode: forwards; }
@keyframes rotation { 50% { transform: rotateY(180deg); opacity:0; }
60% { transform: translate(100px, 0); opacity:0; }
100% { transform: translate(0, 0); opacity:1; } } </style></svg></div>


Related Topics



Leave a reply



Submit