5

Each time a css3 animation loops I'd like to change a variable in the style.

For example the following css drops a group of parachutes from the top to the bottom of the screen:

@-webkit-keyframes fall {
  0% { top: -300px; opacity: 100; }
  50% { opacity: 100; }
  100% { top: 760px; opacity: 0; }
}

#parachute_wrap {
  -webkit-animation-name: fall;
  -webkit-animation-iteration-count: infinite; 
  -webkit-animation-duration: 70s;
  -webkit-animation-timing-function: linear;
}

Ideally however, at the end of each loop I'd like to throw in a random X position.

The default style of the group is:

#parachute_wrap {
  position: absolute;
  top: -300px;
  left: 50%;
  margin-left: 140px;
}

So after 70 seconds, I would like to change the margin-left or left attribute anywhere between -200px and 200px.

I understand I could do something like this with jquery and everytime():

$('#parachute_wrap').everyTime ( 70000, function (){
    $("#parachute_wrap").css({left: Math.floor(Math.random() * 51) + 5 + '%'},0);
});

But is there a way to tie the css loop to js to do this? i.e. is there a return call of any kind which js can listen to for perfect syncing with the animation? I fear that if I use JS on a 70s timer whats going to happen is the timing is going to not sync right, and half way through the css animation the js will do its timed loop and the parachutes are going to jump around the place half way through the animation.

How would you approach this?

willdanceforfun
  • 11,044
  • 31
  • 82
  • 122
  • 1
    If sync is your only worry, you could change the `parachute_wrap` css from an ID to a class, then assign it to the elements you want inside a `$(document).ready()` event setting your timer right after it, inside the `.ready()` as well. There might be an easier way around, but this is what I can think of right now. – Fabrício Matté May 16 '12 at 00:27
  • 1
    This appears to be a near-duplicate of [this question](http://stackoverflow.com/questions/4797675/how-do-i-re-trigger-a-webkit-css-animation-via-javascript). The accepted answer seems to offer a way ahead. – Beetroot-Beetroot May 16 '12 at 01:08

2 Answers2

14

CSS3 animations have an animationEnd event fired when the animation completes.

You can bind that event to your animated element thus triggering that left change at the end of each animation:

$('#parachute_wrap').on('webkitAnimationEnd mozAnimationEnd msAnimationEnd oAnimationEnd animationEnd', function(e) {
    $(this).css({left: Math.floor(Math.random() * 51) + 5 + '%'},0);
});

This way, you know exactly when the animation ends and the left change is applied correctly.

Zuul
  • 16,217
  • 6
  • 61
  • 88
2

There is also an animationiteration event fired at the start of every new animation iteration, i.e. every iteration except the first.

$('#parachute_wrap').on('animationiteration webkitAnimationIteration oanimationiteration MSAnimationIteration', function(e) {
    $(this).css({left: Math.floor(Math.random() * 51) + 5 + '%'},0);
});

http://www.w3.org/TR/css3-animations/#animationiteration

maiis
  • 735
  • 1
  • 6
  • 13