web-dev-qa-db-ja.com

複数の要素間でCSSアニメーションを同期する方法は?

CSSを介してアニメーション化する2つの要素(具体的には、-webkit-animation)がページにあります。アニメーション自体は、要素を上下にバウンスするだけです。 1つの要素は常に表示されてバウンスし、もう1つの要素はマウスオーバー(ホバー)するまでアニメーション化されません。

私の質問は、2番目の要素のアニメーションがいつ開始されたかに関係なく、両方の要素間でアニメーションを同期する(両方の要素を同時に頂点に到達させるなど)ことは可能ですか?

これが私のHTMLです:

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

と私の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;
}

そして最後に、問題の実用的なデモ: http://jsfiddle.net/7ZLmq/2/

(問題を確認するには、黄色のブロックの上にマウスを置きます)

24
busticated

ネイティブで可能だとは思いませんが、バウンスラッパーと位置変更を使用して、同様の機能を実際にハックすることができます

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;
}

デモ http://jsfiddle.net/A92pU/1/

23
Valerij

黄色のものを2つ積み重ねて、親要素を介して:hoverの表示を切り替えることができるようです。

アニメーションを常に実行する必要があります。そうしないと、同期の問題が発生します。

コードを少し変更して this。

2
Nick Dumais

setIntervalを使用して、最初のアニメーションのアニメーション状態を維持し、他のアニメーションに負の遅延を与えて、マウスオーバー時に一致するキーフレームを探すことができます。

「CSSアニメーションの操作」セクションで、state-maintaining-interval-thing here について読んでください。シークする負の遅延について読んでください ここ

2
Protector one

私はここで提案されたものの代替ソリューションを探していました。理由は次のとおりです。

  1. 私は背景色をアニメーション化しています-受け入れられた答えでポジショニングマジックを使用することはできません。
  2. アプリで非常に単純なアニメーションの計算を避けたかったのです。

さらに調査した後、私は このモジュール by bealearts に出くわしました。

これは、名前を参照することでアプリ全体でアニメーションの同期を維持できる非常に優れたAPIを公開します。

import sync from 'css-animation-sync';
sync('spinner');

これは少し良すぎるように思えたので、このフィドルでライブラリ(単一の短いファイル)をテストし、報告して喜んでいます 動作します (3番目の画像にカーソルを合わせると、 2番目の画像のアニメーションにすばやく同期します):)。

クレジット:私はフィドルの基礎として、Simuraiによる このフィドル のアニメーションを使用しました。

この同期の背後にあるメカニズムを複製したい場合、コードは開いていますが、本質的には、アニメーション自体のイベントリスナーを同期ポイントとして使用します。

window.addEventListener('animationstart', animationStart, true);
window.addEventListener('animationiteration', animationIteration, true);

これがこの問題の解決策を探している次の人に役立つことを願っています。

マウスホバー時:

  1. 両方の要素からアニメーションクラスを削除します
  2. requestAnimationFrame(() => { ... add here "bounce" class to both elements })を使用する

うまく同期する必要があります。

1
pankleks