I animate a block with a keyframe, then trigger the reversed animation in javascript, like this :
$('#block').removeClass('animate1').addClass('animate2');
With animate1
and animate2
corresponding to two CSS classes calling the animation (for the demo, in webkit only), and #block
a simple div
:
.animate1 {
-webkit-animation: shift 1s ease-in-out forwards;
}
.animate2 {
-webkit-animation: shift 1s ease-in-out backwards reverse;
}
@-webkit-keyframes shift {
from {
left: 0px;
}
to {
left: 200px;
}
}
<div id="block" class="animate2"></div>
It simply doesn't work. See this fiddle for demo (Chrome 30).
If I trigger the animations the other way around, I mean the reversed one first, then the normal one, it's working properly (demo):
$('#block').removeClass('animate2').addClass('animate1'); //Works.
It's working too if I remove the current class and add the next class with independent functions triggered by click on buttons.
Can someone help me understand this strange behavior? I'm stuck!
For future visitors, I'm not looking for a workaround anymore, just trying to find out what's happening here:
I'll change the accepted answer if appropriate.
Reverse keyframes In the Keyframe Editor in MotionMotionMotion is a software application produced by Apple Inc. for their macOS operating system. It is used to create and edit motion graphics, titling for video production and film production, and 2D and 3D compositing for visual effects.https://en.wikipedia.org › wiki › Motion_(software)Motion (software) - Wikipedia, drag a selection rectangle to select the keyframes to reverse. Control-click a selected keyframe, then choose Reverse Keyframes from the shortcut menu. The keyframes are reversed.
The animation-direction CSS property sets whether an animation should play forward, backward, or alternate back and forth between playing the sequence forward and backward.
When you are reusing an animation, sometimes you inherit the state of it.
The way this happens is a little difficult to forecast, because it isn't always consistent (I guess also that the w3c standard doesn't set exactly what should happen in this cases).
In your case, you are reusing an animation that should happen once (animation-iteration-count : initial, i.e. 1), and that has already happened once. So, nothing happens. (It is true that the other way round works, but as I said before that issue is not always consistent.)
One way to solve it is to reset the transition.
setTimeout(function () {
$('#block').removeClass('animate1');
}, 1950);
setTimeout(function () {
$('#block').addClass('animate2');
}, 2000);
That leaves the div without any animation for a moment, and so reset efectively the transition. You have now the problem that the div jumps to the initial state, so this is not usable right as it is; but I am trying to explain why you have the problem.
A working solution can be going thru transitions, as Jacob says, or creating to different animations.
jumping demo
CSS3 animations appear to be intended for one-off or infinitely looping animations, as suggested by MDN's "Using CSS animations" developer guide.
To keep the logic as you have it, I'd switch to CSS3 transitions.
First, in CSS, let's define two alternate "states" our cat photo can be in (on the left, or on the right):
.transition1 {
transition-property: left;
transition-duration: 1s;
left: 0px;
}
.transition2 {
transition-property: left;
transition-duration: 1s;
left: 200px;
}
Now, using your JS, with our renamed CSS classes:
$('#swap1').click(function () {
$('#block').removeClass('transition1').addClass('transition2');
});
$('#swap2').click(function () {
$('#block').removeClass('transition2').addClass('transition1');
});
On button click, the (cat photo) element's left
property will transition from 0px
to 200px
(or vice-versa) over one second time. Here's my code: http://jsfiddle.net/u6jsC/.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With