【问题标题】:Reverse Keyframe animation with Javascript使用 Javascript 反转关键帧动画
【发布时间】:2014-01-15 14:23:46
【问题描述】:

我用关键帧为块设置动画,然后在 javascript 中触发反向动画,如下所示:

$('#block').removeClass('animate1').addClass('animate2');

animate1animate2 对应于调用动画的两个 CSS 类(用于演示,仅在 webkit 中),#block 是一个简单的div

CSS

.animate1 {
    -webkit-animation: shift 1s ease-in-out forwards;
}
.animate2 {
    -webkit-animation: shift 1s ease-in-out backwards reverse;
}
@-webkit-keyframes shift {
    from {
        left: 0px;
    }
    to {
        left: 200px;
    }
}

HTML

<div id="block" class="animate2"></div>

它根本不起作用。有关演示 (Chrome 30),请参阅 this fiddle


事实

如果我反过来触发动画,我的意思是先反转的,然后是正常的,它工作正常(demo):

$('#block').removeClass('animate2').addClass('animate1'); //Works.

如果我删除当前类并添加具有通过单击按钮触发的独立功能的下一个类,它也可以工作。

有人可以帮我理解这种奇怪的行为吗?我被困住了!


编辑

对于未来的访问者,我不再寻找解决方法,只是想了解这里发生了什么:

  • 浏览器要求的“重置时间”是多少?
  • 为什么它以某种方式起作用,而以另一种方式起作用?
  • 为什么在内部闭包中触发动画有效?

如果合适,我会更改接受的答案。

【问题讨论】:

    标签: javascript jquery html css css-animations


    【解决方案1】:

    当您重用动画时,有时您会继承它的状态。

    这种情况的发生方式有点难以预测,因为它并不总是一致的(我也猜想 w3c 标准并没有明确规定在这种情况下应该发生什么)。

    在您的情况下,您正在重用应该发生一次的动画(动画迭代计数:初始,即 1),并且 已经发生过一次。所以,什么也没有发生。 (确实,反过来也行,但正如我之前所说,这个问题并不总是一致的。)

    解决它的一种方法是重置转换。

    setTimeout(function () {
        $('#block').removeClass('animate1');
    }, 1950);
    setTimeout(function () {
        $('#block').addClass('animate2');
    }, 2000);
    

    这让 div 暂时没有任何动画,因此有效地重置了过渡。您现在遇到了 div 跳转到初始状态的问题,因此无法按原样使用;但我试图解释为什么你有这个问题。

    正如 Jacob 所说,一个可行的解决方案可以是通过过渡,或者创建不同的动画。

    jumping demo

    【讨论】:

    • 我最终使用了超时,但很奇怪,我使用了 0 秒延迟触发的超时,并且它起作用了。虽然如果我将removeClass()addClass() 分开在两条不同的行上,它就不起作用。我只是无法理解,我能理解的唯一方法是闭包的≠让“时间”(哪个时间?)到浏览器来重置动画。这是为什么?永远不会知道。
    【解决方案2】:

    正如MDN's "Using CSS animations" developer guide 所建议的那样,CSS3 动画似乎用于一次性或无限循环动画。

    为了保持逻辑不变,我会切换到CSS3 transitions

    首先,在 CSS 中,让我们定义猫照片可以处于的两个备用“状态”(在左侧或右侧):

    .transition1 {
        transition-property: left;
        transition-duration: 1s;
        left: 0px;
    }
    .transition2 {
        transition-property: left;
        transition-duration: 1s;
        left: 200px;
    }
    

    现在,使用您的 JS,以及我们重命名的 CSS 类:

    $('#swap1').click(function () {
        $('#block').removeClass('transition1').addClass('transition2');
    });
    $('#swap2').click(function () {
        $('#block').removeClass('transition2').addClass('transition1');
    });
    

    单击按钮时,(猫照片)元素的left 属性将在一秒钟内从0px 转换为200px(反之亦然)。这是我的代码:http://jsfiddle.net/u6jsC/

    【讨论】:

    • 感谢您的解决方法!当我定义一个线性动画时,这可以解决问题。 注意:我同时使用模糊滤镜、缩放和不透明度进行了测试,it works altogether well 我最终还是使用了setTimeout,延迟为 0。
    猜你喜欢
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多