反向重复使用 CSS 动画(通过重置状态?)

Reuse CSS animation in reversed direction (by resetting the state?)

我在 CSS 中使用了两个关键帧动画。一个从左向右移动,另一个使用完全相同的值 - 但相反。

@keyframes moveLeft
{
    from {transform: translate3d(50px, 0, 0);}
    to   {transform: translate3d(0px, 0, 0);}
}


@keyframes moveRight
{
    from {transform: translate3d(0px, 0, 0);}
    to   {transform: translate3d(50px, 0, 0);}
}

但是,我想知道是否可以只使用一个关键帧动画。但是只要我添加 animation-direction: reverse,动画就只播放一次。它可能保存了以前使用过一次的信息。 所以:我能以某种方式重置这些信息吗?或者有没有可能在不同的方向使用一个动画两次? (不使用 JS)

http://jsfiddle.net/vrhfd66x/

不,单独使用 CSS 无法重新启动动画。您必须使用 JavaScript 从元素中删除动画,然后将其重新应用到元素(在延迟后)以使其重新启动。

下面是 W3C's CSS3 Animation Spec 所说的(在不同的上下文中,但这一点也适用于这种情况):

Note also that changing the value of ‘animation-name’ does not necessarily restart an animation (e.g., if a list of animations are applied and one is removed from the list, only that animation will stop; The other animations will continue). In order to restart an animation, it must be removed then reapplied.

重点是我的

Chris Coiyer 的 CSS Tricks Article 也表明了这一点,并提供了一些用于重新启动动画的 JS 解决方案。 (注意: 这篇文章引用了 Oli 的 dabblet,它声称更改持续时间、迭代次数等属性会使其在 Webkit 上重新启动,但它似乎已过时,因为它们不再适用于 Chrome).


总结:

虽然您已经谈到了以下内容,但为了完整起见,我将再次重申:

  • 在元素上应用动画后,它会一直保留在元素上,直到被移除。
  • UA 会跟踪元素上的动画以及它是否已完成。
  • 当您在 :checked 上应用相同的动画(尽管方向不同)时,UA 不执行任何操作,因为动画已经存在于元素上。
  • 单击复选框时位置的切换(瞬时)是因为在 :checked 选择器中应用了 transform。动画的存在没有任何区别。

解法:

正如您从下面的代码片段中看到的那样,即使使用 JavaScript,通过单个动画实现这一点也非常复杂。

var input = document.getElementsByClassName("my-checkbox")[0];

input.addEventListener('click', function() {
  if (this.checked) {
    this.classList.remove('my-checkbox');
    window.setTimeout(function() {
      input.classList.add('anim');
      input.classList.add('checked');
    }, 10);
  } else {
    this.classList.remove('anim');
    window.setTimeout(function() {
      input.classList.remove('checked');
      input.classList.add('my-checkbox');
    }, 10);
  }
});
input {
  transform: translate3d(50px, 0, 0);
}
.my-checkbox {
  animation: moveLeft 1s;
  animation-direction: reverse;
}
.checked {
  transform: translate3d(0px, 0, 0);
}
.anim{
  animation: moveLeft 1s;
}
@keyframes moveLeft {
  from {
    transform: translate3d(50px, 0, 0);
  }
  to {
    transform: translate3d(0px, 0, 0);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<input type="checkbox" class="my-checkbox">

因此,最佳选择(如果你想坚持使用 CSS 动画)是使用两种不同的动画 .

或者,您也可以看看马塞洛的评论。如果实际用例正是 fiddle 中提供的,那么 transition 就足够了,不需要 animation。转换本质上可以在正向和反向方向上工作,因此是一个更安全的选择。