web-dev-qa-db-ja.com

SafariのCSSアニメーションのバグ

CSSアニメーションに遅延があり、遅延中に一時停止します。 FirefoxとChromeでは期待どおりに動作し、「Hello」は移動しません。ただし、Safariでは、アニメーションは最後のフレームにジャンプします。なぜそしてどのように修正するのですか?

function test() {
  var timeout = 1000;
  setTimeout(function() {
    document.getElementById('animation').style.animationPlayState = 'paused';
  }, timeout);
}

document.addEventListener("DOMContentLoaded", test);
#animation {
  animation: test 2s linear 2s;
}

@keyframes test {
  to {
    transform: translateY(100px);
  }
}
<div id="animation">
  Hello (this text should not move)
</div>

2秒の遅延を削除し、期間を4秒に設定し、transform:noneを使用してキーフレームを追加すると、この簡単な例を機能させることができます。ただし、私の実際のケースには、遅延と同期する複数のアニメーションがあります。

17
Patrick

Safariの動作は、タイムアウトがアニメーション遅延よりも小さい値に設定されている場合にのみバグがあります。したがって、回避策は、初期状態をanimation-play-stateを介してpausedに設定し、次にJSを介して制御することです。未満:

function test() {
  let el = document.getElementById("animation");
  let timeout = 1000;
  
  // Get the delay. No luck with el.style.animationDelay
  let delay =
    window
      .getComputedStyle(el)
      .getPropertyValue("animation-delay")
      .slice(0, -1) * 1000;

  // Only resume and later pause when timeout is greater than animation delay
  if (timeout > delay) {
    el.style.animationPlayState = "running";
    setTimeout(function() {
      el.style.animationPlayState = "paused";
    }, timeout);
  }
}

document.addEventListener("DOMContentLoaded", test);
#animation {
  animation: test 2s linear 3s;
  animation-play-state: paused; /* Pause it right after you set it */
}

@keyframes test {
  to {
    transform: translateY(100px);
  }
}
<div id="animation">
  Hello (this text should not move)
</div>

別のタイムアウト値を試して、動作することを確認してください。なぜこれが起こっているのかは言えません。私にはバグのようです。 OS X El Capitan 10.11.6/Safari 11.0(11604.1.38.1.7)でテスト済み。

Codepenデモ

12
Kostas Siabanis

これは問題に対する答えではありません。ただし、アニメーションの遅延を削除すると、アニメーションの一時停止と再開が正常に機能します。アニメーションの遅延が問題の原因であるようです。おそらく、CSSを使用して遅延を処理するのではなく、JavaScriptを使用してプログラムでアニメーションの遅延を制御します。

以下のアニメーションの一時停止と実行を参照してください

function test() {
  var timeout = 1000;
  setTimeout(function() {
    document.getElementById('animation').style.animationPlayState ='paused';
    document.getElementById('animation').style.webkitAnimationPlayState ='paused';
  }, timeout);
  setTimeout(function() {
    document.getElementById('animation').style.animationPlayState='running';
    document.getElementById('animation').style.webkitAnimationPlayState ='running';
  }, timeout * 2);
}

document.addEventListener("DOMContentLoaded", test);
#animation {
    -webkit-animation: test 2s linear;
        animation: test 2s linear;
}

@-webkit-keyframes test {
  to {
    -webkit-transform: translateY(100px);
        transform: translateY(100px);
  }
}

@keyframes test {
  to {
    -webkit-transform: translateY(100px);
        transform: translateY(100px);
  }
}
<div id="animation">
  Hello (this text should not move)
</div>
4
wlh