过渡期间CSS转换的变化导致当前状态迷失并跳到开始(Chrome错误)

Ole*_*yra 11 javascript css animation css3 css-transforms

已在Google Chrome 73(正式版)(64位)中经过测试。

还在最新的稳定版Mozilla,Opera和Safari中进行了测试。

看来这只是Chrome的错误。希望有解决方法,直到Chrome小组修复该错误为止。

演示版

我创建了Codepen来显示问题。

const div = document.querySelector('div');

const cssTransition = 2500;
const states = [
  ['INITIAL', 'translate(0)', cssTransition / 2],
  ['A', 'translate(0, 100px)', cssTransition + 500],
  ['B', 'translate(100px, 100px)', cssTransition / 2],
];

let cursor = 0;

const animate = () => {
  cursor = (cursor + 1) % states.length;
  const [name, value, delay] = states[cursor];
  setTimeout(() => {
    div.innerText = name;
    div.style.transform = value;
    animate();
  }, delay);
};

animate();
Run Code Online (Sandbox Code Playgroud)
div {
  width: 100px;
  height: 100px;
  background: brown;
  color: white;
  font-size: 25px;
  font-family: sans-serif;
  text-align: center;
  line-height: 100px;
  margin: 50px auto;
  transition: 2.5s ease;
}
Run Code Online (Sandbox Code Playgroud)
<div>INITIAL</div>
Run Code Online (Sandbox Code Playgroud)

任务

通过JavaScript对元素进行动画处理,以使用CSS3 transform属性更改其在屏幕上的位置。

条件:

  1. 元素具有固定的过渡时间(在CSS文件中定义)。
  2. 在动画的任何时候,JavaScript都可以设置元素的新位置,即在现有动画完成之前进行更改。
  3. 元素的新位置未知=>即CSS类列表在这里不是一个选项。

问题是 -过渡不平滑,因为新动画从先前动画的初始位置跳转,而不是从当前位置平滑过渡。

实际行为

当元素的CSS变换属性在过渡期间(即,当前动画完成之前)更改时,下一个动画将从上一个动画的初始状态开始。

错误,跳跃的CSS过渡

  • 步骤1-5是第一个动画(INITIAL和A状态之间的转换)。
  • 步骤6-10是第二个动画(INITIAL和B状态之间的转换)。
  • 步骤3是第一个动画被中断的地方,因为最终的变换属性已更改,即第二个动画从此处开始。

如您所见,动画跳到了错误的INITIAL状态(不需要)。步骤6的位置应靠近步骤3。

预期行为

CSS转换属性更改应将内部动画计时器重置为0(因此,新动画将按照过渡属性中的定义持续运行),但将当前的转换状态保留为下一个动画的初始状态。

正确的预期CSS过渡

  • 步骤1-5是第一个动画(INITIAL和A状态之间的转换)。
  • 步骤6-10是第二个动画(在中间“ INITIAL到A”和B状态之间的转换)。
  • 步骤3是第一个动画被中断的地方,因为最终的变换属性已更改,即第二个动画从此处开始。

如您所见,新动画将从所需的位置精确开始-从第3步开始,将元素很好地移动到新位置。

谢谢阅读。期待您的帮助。

Bal*_*alo 3

我不确定为什么会发生这种情况,但解决方案是transform在更改为新的所需属性之前,手动将转换的属性(此处)设置为其当前计算值。

div.style.transform = getComputedStyle(div).transform;
// Cause a reflow to force the browser to apply the set transform
div.innerWidth;
div.style.transform = value;
Run Code Online (Sandbox Code Playgroud)

这是你的笔的叉子,包括修复程序。

getComputedStyle得到了广泛的支持,所以你不需要担心polyfill,除非你想支持 IE < 9