Animation 如何跨多个元素同步CSS动画?

Animation 如何跨多个元素同步CSS动画?,animation,webkit,css,Animation,Webkit,Css,我有两个元素在一个页面上,我想通过CSS动画(特别是,-webkit动画)。动画本身只是上下反弹一个元素。一个元素始终显示并反弹,另一个元素在鼠标悬停(悬停)之前不会设置动画 我的问题是:无论第二个元素的动画何时开始,是否可以跨两个元素同步(使两个元素同时达到顶点等)动画 这是我的HTML: <div id="bouncy01">Drip</div> <div id="bouncy02">droP</div> 最后,是该问题的工作演示: (要查看

我有两个元素在一个页面上,我想通过CSS动画(特别是,-webkit动画)。动画本身只是上下反弹一个元素。一个元素始终显示并反弹,另一个元素在鼠标悬停(悬停)之前不会设置动画

我的问题是:无论第二个元素的动画何时开始,是否可以跨两个元素同步(使两个元素同时达到顶点等)动画

这是我的HTML:

<div id="bouncy01">Drip</div>
<div id="bouncy02">droP</div>
最后,是该问题的工作演示:


(要查看问题,请将鼠标移到黄色块上)

我认为这在本机上是不可能的,但实际上您可以通过使用反弹包装器和一些位置改变来破解类似的功能

html:


演示

看起来您可以只堆叠两个黄色元素并打开可见性:悬停在父元素中

您需要始终运行动画,否则会遇到同步问题


我对您的代码进行了一些修改,以获得

您可以使用
设置间隔
来保持第一个动画的动画状态,并给另一个动画一个负延迟,以便在鼠标悬停时查找其匹配的关键帧

在“操纵CSS动画”部分阅读关于状态保持间隔的内容;了解搜索的负延迟。

鼠标悬停时:

  • 从两个元素中删除动画类
  • 使用
    requestAnimationFrame(()=>{…在此处将“bounce”类添加到两个元素})

  • 应该可以很好地同步。

    我正在寻找一种替代方案来替代这里提出的方案,因为:

  • 我正在制作背景色的动画-这不能在接受的答案中使用定位魔法
  • 我想避免在我的应用程序中计算一个非常简单的动画
  • 经过进一步的研究,我遇到了一个新的问题

    它公开了一个非常简洁的API,允许您通过引用动画的名称在整个应用程序中保持动画的同步:

    从“css动画同步”导入同步;
    同步(“微调器”);
    
    因为这看起来有点太好了,所以我在这个提琴中测试了库(它是一个单独的短文件),并很高兴地报告(将鼠标悬停在第三个图像上,看到我快速同步到第二个图像的动画):)

    信用证:我用西姆莱的动画作为我小提琴的基础

    如果有人想复制此同步背后的机制,代码是开放的,但本质上,它使用动画本身的事件侦听器作为同步点:

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

    希望这有助于下一位寻找此问题解决方案的人员。

    在添加类之前计算并添加延迟:

    function getTime (seconds) {
      const msDuration = (seconds * 1000).toFixed(0);
      const currentTime = (new Date()).getTime();
      const msDelay = msDuration - (currentTime % msDuration);
      return (msDelay / 1000).toFixed(4);
    }
    
    $('div').css({animationDelay: getTime(0.6) + "s"}).addClass('animating');
    

    您可以在根元素上设置一个类来设置更改状态,然后使用计时器更改该类

    CSS

    .alt.bouncy{
    填充顶部:5px!重要;
    }
    .有弹性{
    垫面:1px;
    过渡:衬垫顶部放松500ms;
    }
    
    HTML

    
    滴下
    滴
    
    Javascript

    $(函数(){
    setInterval(()=>$(“.container”).toggleClass(“alt”),1000)
    })
    

    通过这种方式,过渡和定时器完成css动画的工作,但由一个主开关(容器)控制。

    哦,是的。。。我忘了提到这种方法在我的情况下不起作用(我的元素在页面的不同侧面)。谢谢你!为什么不呢?0px高、空、透明的div不会影响设计和可用性。就像这里一样,如果您提供更多详细信息/向我展示实际设计,我可能会帮助更多看起来很有趣=)这与@Valerij解决方案非常相似,但我认为前者更干净,因为它不是使用重复的内容,而是使用父级来触发悬停时的弹跳改变位置。看看:jsfiddle.net/A92pU/2(您可以在OP中找到它)
    <div id="bouncywrap">
        <div id="bouncy01">Drip</div>
        <div id="bouncy02">droP</div>
    <div>
    
    @-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;
    }
    
    function getTime (seconds) {
      const msDuration = (seconds * 1000).toFixed(0);
      const currentTime = (new Date()).getTime();
      const msDelay = msDuration - (currentTime % msDuration);
      return (msDelay / 1000).toFixed(4);
    }
    
    $('div').css({animationDelay: getTime(0.6) + "s"}).addClass('animating');