Multiple Webkit Animations

Play multiple CSS animations at the same time

TL;DR

With a comma, you can specify multiple animations each with their own properties as stated in the CriticalError answer below.

Example:

animation: rotate 1s, spin 3s;

Original answer

There are two issues here:

#1

-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;

The second line replaces the first one. So, has no effect.

#2

Both keyframes applies on the same property transform

As an alternative you could to wrap the image in a <div> and animate each one separately and at different speeds.

http://jsfiddle.net/rnrlabs/x9cu53hp/

.scaler {
position: absolute;
top: 100%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
animation: scale 4s infinite linear;
}

.spinner {
position: relative;
top: 150px;
animation: spin 2s infinite linear;
}

@keyframes spin {
100% {
transform: rotate(180deg);
}
}

@keyframes scale {
100% {
transform: scaleX(2) scaleY(2);
}
}
<div class="spinner">
<img class="scaler" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="Sample Image" width="120" height="120">
<div>

Multiple webkit animations

You can separate multiple animations with a , and set a delay on the second one if needed:

-webkit-animation: shrink 2s ease-out, pulsate 4s 2s infinite ease-in-out;

2s in the second animation is the delay


Since Chrome 43 and Safari 9/9.2, the -webkit- prefix is only needed for Blackberry and UC (Android) browser. So the new correct syntax would be

animation: shrink 2s ease-out, pulsate 4s 2s infinite ease-in-out;

Chaining Multiple CSS Animations

The problem is actually not with the order of the animations but because of how multiple animations on pme element works. When multiple animations are added on an element, they start at the same time by default.

Because of this, both the laydown and falling animations start at the same time but the laydown animation actually completes within 1000ms from the start but the first animation (which is falling) doesn't complete till 2000ms.

The W3C spec about animations also say the following about multiple animations accessing the same property during animation:

If multiple animations are attempting to modify the same property, then the animation closest to the end of the list of names wins.

In the code provided in question, both animations are trying to modify the transform property and the second animation is the closest to the end. So while the second animation is still running (which is, for the first 1000ms) the transform changes are applied as specified in the second animation. During this time the first animation is still running but it has no effect because its values are overwritten. In the 2nd 1000ms (when the second animation has already completed but 1st is still executing), the transforms are applied as directed by the first animation. This is why it looks as if the second animation is running before the first animation and then the first.


To fix this problem, the execution of the second animation should be put on hold (or delayed) until the time the first animation is complete. This can be done by adding a animation-delay (that is equal to the animation-duration of the first animation) for the second animation.

animation-name: falling, laydown;
animation-duration: 2000ms, 1000ms;
animation-delay: 0ms, 2000ms; /* add this */
animation-timing-function: ease-in, ease-out;
animation-iteration-count: 1, 1;

html,body {  height: 100%;}body {  display: flex;  align-items: center;  justify-content: center;}@keyframes falling {  0% {    transform: translate3d(0, -400px, 0);  }  100% {    transform: translate3d(0, 40%, 0) rotateX(30deg) rotateY(0deg) rotateZ(60deg);  }}@keyframes laydown {  0% {    transform: translate3d(0, 40%, 0) rotateX(30deg) rotateY(0deg) rotateZ(60deg);  }  100% {    transform: translate3d(0, 40%, 0) rotateX(70deg) rotateY(0deg) rotateZ(80deg);  }}#falling-card-parent {  height: 150px;  width: 100px;  margin: auto;  perspective: 1000px;}#falling-card {  height: 150px;  width: 100px;  background-color: black;  margin: auto;  transform: translate3d(0, 40%, 0) rotateX(70deg) rotateY(0deg) rotateZ(80deg);  animation-name: falling, laydown;  animation-duration: 2000ms, 1000ms;  animation-delay: 0ms, 2000ms;  animation-timing-function: ease-in, ease-out;  animation-iteration-count: 1, 1;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script><div id="falling-card-parent">  <div id="falling-card"></div></div>

Combining multiple CSS animations into one overall animation

One animation one element is how it works as the animations change the styles of a single element. You can however apply delays to the animations to achieve what you want, allowing you to move pretty much everything out of JS.

This example merges your .outside an .inside animations, by basically appending them with a comma to the rule and you JS now just adds the class like this -webkit-animation-name: button-bounce, rotate, skyblue;

jsFiddle

CSS

.outside.animate {
-webkit-animation-delay: 0s, .5s, .5s;
-webkit-animation-duration: 500ms, 1000ms, 1000ms;
-webkit-animation-name: button-bounce, rotate, skyblue;
}

.animate {
-webkit-animation-fill-mode: forwards;
-webkit-animation-timing-function: ease;
-webkit-transform: translateZ(0);
}

.outside.animate .inside {
-webkit-animation-delay: .5s, .5s, 1.5s;
-webkit-animation-duration: 1000ms, 1000ms, 750ms;
-webkit-animation-name: rotate, magenta, scale-in;
}

New animations

@-webkit-keyframes magenta {
0% { border: 1px solid magenta; }
99.99% { border: 1px solid magenta; }
100% { border: 1px solid skyblue; }
}
@-webkit-keyframes skyblue {
0% { border: 1px solid skyblue; }
99.99% { border: 1px solid skyblue; }
100% { border: 1px solid magenta; }
}

JavaScript

$(document).ready(function() {
$(document).click(function() {
var count = 0;
var jqElement = $('.outside');
if (!jqElement.hasClass('animate')) {
jqElement.addClass('animate');
jqElement.on('animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd', function(event) {
count++;
if (count >= 6) {
jqElement.off('animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd');
jqElement.removeClass('animate');
}
});
}
});
});

Multiple CSS animations: How to avoid re-triggering one of them?

You have an element that is a set of @-webkit-keyframes to animate in. On hamburger-menu click, these keyframes run, and that works well.

Next, you have a second set of @-webkit-keyframes on hover, so on hover works well too.

However, the instant the mouse is away from the element, the first (intro) set of keyframes gets run again. You don't want it to run after it first runs.

Here is what I was able to accomplish:
https://codepen.io/CapySloth/pen/RgxKEb

<div id="workouts" class="sml smlOne">
<div class="test1">
<a href="">Go there</a>
</div>
</div>

Instead of stacking classes which contain keyframe animations onto the one ".sml" class, I have split the task between two elements. ".sml" now acts as a wrapper which takes care of the "hamburger-menu open" animation and "test1 a" takes care of the "whop" animation.

If you can find a way to hide/show parents of the "test1 a/test2 a/test3 a" then you will have what you want.

Using two animations on one element, CSS

Reason:

The slide-up animation executes once again when you move the mouse out of the element because of the following reasons:

  • On load, the element has only one animation (which is slide-up). The browser executes this.
  • On hover, the animation property again specifies only one animation (which is rotate). This makes the browser remove the slide-up animation from the element. Removing the animation makes the browser also forget about the execution state or the execution count of it.
  • On hover out, the default div selector becomes applicable for the element and so the browser again removes the rotate animation and attaches the slide-up animation. Since it is being re-attached, the browser thinks it must execute it again.

Solution:

You can make the slide-up animation run only once by making sure that the animation is actually never removed from the element even when :hover is on and animation-iteration-count is 1.

In the below snippet, you'd note how I have retained the slide-up animation definition within :hover selector also. This makes the browser see this animation as ever present and since this animation is already executed once on load, it won't execute it again (because of iteration count).

(Note: Just to avoid any confusions - the default value for animation-iteration-count is 1 but I had made it explicit for the purpose of explanation. It is not the primary reason but is just an extra step to make sure that its value doesn't mess up the solution.)

div {  height: 100px;  width: 100px;  border: 1px solid;  animation: slide-up 2s 1;}div:hover {  animation: slide-up 2s 1, rotate 2s forwards;}@keyframes slide-up {  from {    margin-top: 100px;  }  to {    margin-top: 0px;  }}@keyframes rotate {  from {    transform: rotate(0deg);  }  to {    transform: rotate(60deg);  }
<div>Some div</div>

Multiple CSS keyframe animations using transform property not working

You cannot animate same attribute ( here transform attribute ) more than once, on a same element, the last one will overwrite other,

You should put your target element into a div, and apply one transform-animation on the div and other transform-animation on the target element....

.div_class
{
animation:animate1 1000ms linear infinite;
}

.element
{
animation:animate2 3000ms linear infinite;
}


Related Topics



Leave a reply



Submit