How To Sync CSS Animations Across Multiple Element

2019-01-24 00:43发布

问题:

I have two elements on a page that I'd like to animate via CSS (specifically, -webkit-animation). The animation itself simply bounces an element up and down. One element is always shown and bouncing, the other is not animated until mouse-over (hover).

My question is: Is it possible to sync (have both elements reach their apex at the same time, etc) the animation across both elements regardless of when the 2nd element's animation is started?

Here's my HTML:

<div id="bouncy01">Drip</div>
<div id="bouncy02">droP</div>

and my CSS:

@-webkit-keyframes bounce {
    0% {-webkit-transform: translateY(0px);}
    25% {-webkit-transform: translateY(-2px);}
    50% {-webkit-transform: translateY(-4px);}
    75% {-webkit-transform: translateY(-2px);}
    100% {-webkit-transform: translateY(0px);}
}
#bouncy01,
#bouncy02 {
    margin:10px;
    float: left;
    background: #ff0000;
    padding: 10px;
    border: 1px solid #777;
}
#bouncy01 {
    -webkit-animation:bounce 0.25s ease-in-out infinite alternate;
}
#bouncy02 {
    background: #ffff00;
}
#bouncy02:hover {
    -webkit-animation:bounce 0.25s ease-in-out infinite alternate;
}

and finally, a working demo of the issue: http://jsfiddle.net/7ZLmq/2/

(to see the problem, mouse-over the yellow block)

回答1:

I don't think its possible natively, but you can actually hack similar functionality by using a bouncing wrapper and some position altering

html:

<div id="bouncywrap">
    <div id="bouncy01">Drip</div>
    <div id="bouncy02">droP</div>
<div>

CSS:

@-webkit-keyframes bounce {
    0% { padding-top:1px;}
/* using padding as it does not affect position:relative of sublinks
 * using 0 instead of 0 b/c of a box-model issue,
 * on kids wiht margin, but parents without margin, just try out
 */
    50% { padding-top:5px;} /*desired value +1*/
    100% { padding-top:1px;}
}

#bouncy01,
#bouncy02 {
    margin:10px;
    background: #ff0000;
    padding: 10px;
    border: 1px solid #777;
    width:30px;
       position:absolute;
}
#bouncywrap {
    -webkit-animation:bounce 0.125s ease-in-out infinite;
    position:relative;
    width:140px;
    height:50px;
/*    background:grey; /*debug*/
}
#bouncy02 {
    background: #ffff00;
    left:60px;
    top:2px; /*half of desired value, just a fix for the optic*/
}
#bouncy02:hover {
    position:relative; /*here happens the magic*/
    top:0px;
}

demo http://jsfiddle.net/A92pU/1/



回答2:

Looks like you can just stack two of the yellow ones and switch visibility on :hover through a parent element.

You need the animation to always be running otherwise you'll run into the sync issue you've got.

I modified your code a bit to get this.



回答3:

You could use a setInterval to maintain the animation state of the first animation and give the other animation a negative delay to seek to its matching keyframe on mouse-over.

Read about the state-maintaining-interval-thing here, at the "Manipulating CSS Animations" section; read about the negative delay to seek here.



回答4:

on mouse hover:

  1. remove animation classes from both elements
  2. use requestAnimationFrame(() => { ... add here "bounce" class to both elements })

Should sync nicely.