【问题标题】:How to stop and reset an animation without destroying the original tag object?如何在不破坏原始标签对象的情况下停止和重置动画?
【发布时间】:2018-09-17 06:56:02
【问题描述】:

我正在尝试将对象的动画重置为其初始点,以便我可以从头开始重新启动它。

function swap_animation(node, from, to) {
  let t = node.style.animationDuration;
  node.style.animationDuration = "0s";
  node.style.animationPlayState = "initial";
  setTimeout(function(){
    node.style.animationDuration = t;
    node.classList.remove(from);
    node.classList.add(to);
  }, 10);
}

function grow() {
  let node = document.getElementById("item");
  swap_animation(node, "shrink", "grow");
}

function shrink() {
  let node = document.getElementById("item");
  swap_animation(node, "grow", "shrink");
}
.grow {
  animation-name: title-min;
  animation-duration: 10s;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
  transform-origin: 0% 100% 0;
}

.shrink {
  animation-name: title-min;
  animation-duration: 10s;
  animation-timing-function: linear;
  animation-direction: reverse;
  animation-fill-mode: forwards;
  transform-origin: 0% 100% 0;
}

@keyframes title-min
{
  from { transform: scale(0.5); }
  to   { transform: scale(1.0); }
}
<body>
  <button onclick="grow()">Eat me! ????</button>
  <button onclick="shrink()">Drink me! ????</button>
  <h1 id="item">Alice ????</h1>
</body>

示例显示,如果您在 Eat me!Drink me! 之间单击,Alice 会在 10 秒内变大和变小。但是,如果您在两者之间切换,您会注意到动画从切换前的位置继续播放。

我想我在某处读到过,一种方法是克隆对象并用新对象替换旧对象。这似乎真的有点矫枉过正,我认为可能会导致性能问题,如果对象很大则更是如此,而且还会很糟糕,因为它会导致内存碎片。

必须有某种方法来保留对象并修改它的属性来解决这个问题,不是吗?

【问题讨论】:

    标签: javascript jquery css-animations keyframe


    【解决方案1】:

    好的,我找到了答案。这是触发回流。从this site 得到答案。不完全确定 void 在那里做什么。

    function swap_animation(node, from, to) {
      node.classList.remove(from);
      void node.offsetWidth;
      node.classList.add(to);
    }
    
    function grow() {
      let node = document.getElementById("item");
      swap_animation(node, "shrink", "grow");
    }
    
    function shrink() {
      let node = document.getElementById("item");
      swap_animation(node, "grow", "shrink");
    }
    .grow {
      animation-name: title-min;
      animation-duration: 10s;
      animation-timing-function: linear;
      animation-fill-mode: forwards;
      transform-origin: 0% 100% 0;
    }
    
    .shrink {
      animation-name: title-min;
      animation-duration: 10s;
      animation-timing-function: linear;
      animation-direction: reverse;
      animation-fill-mode: forwards;
      transform-origin: 0% 100% 0;
    }
    
    @keyframes title-min
    {
      from { transform: scale(0.5); }
      to   { transform: scale(1.0); }
    }
    <body>
      <button onclick="grow()">Eat me! ?</button>
      <button onclick="shrink()">Drink me! ?</button>
      <h1 id="item">Alice ?</h1>
    </body>

    【讨论】:

    • void 是为了确保您的 node.offsetWidth; getter 被实际调用,因为理论上它可能会被 JIT 优化器破坏(我自己没见过这种情况......)
    猜你喜欢
    • 2013-08-02
    • 2019-10-03
    • 2014-07-29
    • 1970-01-01
    • 2013-04-13
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多