如果我使用 translateX(100%),在大量 javascript 函数 css 动画中停止

Fre*_*ors 2 javascript css css-transitions css-animations svelte

脚步

  1. 继续 REPL:https ://codesandbox.io/s/css-sidebar-animation-100-transform-wxchf ? file =/ App.svelte
  2. 单击“切换侧边栏”按钮
  3. 动画流畅,流畅
  4. 取消注释第 28 行
  5. 第 29 行评论
  6. 再次点击按钮
  7. heavy()调用toggleSidebar()函数时动画停止(在函数中)

问题

我不明白为什么会这样?

如果我更改-200px-100%正在发生的事情会导致动画停止吗?

我该如何解决这个问题?如果我事先不知道侧边栏宽度怎么办?如果是动态的呢?

代码

.sidebar {
  animation: sidebar-slide-right 3s ease-out;
}

@keyframes sidebar-slide-right {
  0% {
    /* transform: translateX(-100%); */
    transform: translateX(-200px);
  }
  100% {
    transform: translateX(0);
  }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

我花了一些时间在 Web 浏览器开发工具中用性能时间测试您的 repl。我的结论是:

在现代网络浏览器中,我们有

  • 主线程
  • 合成器线程

第二个非常好,因为通过对自身承担一些责任来帮助主线程。

通常,主线程负责:

  • 运行你的 JavaScript。

  • 计算 HTML 元素的 CSS 样式。

  • 布置您的页面。将您的元素绘制成一个或多个位图。

  • 将这些位图交给合成线程。

通常,合成器线程负责:

  • 通过 GPU 将位图绘制到屏幕上。

  • 要求主线程更新页面可见或即将可见部分的位图。

  • 找出页面的哪些部分是可见的。确定滚动时哪些部分将很快可见。

  • 滚动时移动页面的各个部分。

来源:http : //sking7.github.io/articles/572118798.html

基于 CSS 的动画和本机支持的 ​​Web 动画通常在称为“合成器线程”的线程上处理。这与浏览器的“主线程”不同,在主线程中执行样式、布局、绘制和 JavaScript。这意味着如果浏览器在主线程上运行一些昂贵的任务,这些动画可以继续进行而不会被中断。

在许多情况下,对转换和不透明度的其他更改也可以由合成器线程处理。

如果任何动画触发绘制、布局或两者,“主线程”将需要执行工作。对于基于 CSS 和基于 JavaScript 的动画都是如此,布局或绘制的开销可能会使与 CSS 或 JavaScript 执行相关的任何工作相形见绌,从而使问题变得毫无意义。

资料来源:https : //developers.google.com/web/fundamentals/design-and-ux/animations/animations-and-performance

所以当我们必须处理动画时,合成器非常好。使用 px 作为度量单位很容易,并且可以由合成器线程完成,但是使用 % 会使我们的浏览器计算动画的每个“步骤”,因此主线程必须帮助我们完成它。通过使用await您阻止主线程,因此您的浏览器等待重新计算位置。当您使用绝对单位时,合成器线程会执行动画,因此即使您阻塞主线程,您的动画也能流畅运行。

将您的代码替换为

  async function toggleSidebar() {
    sidebarVisible = !sidebarVisible;
    console.log("1");
    await sleep(800);
    console.log("2");
    heavy(40);
  }
Run Code Online (Sandbox Code Playgroud)

您可以注意到使用 % 原因:

动画运行

  1. 控制台日志 1
  2. 动画停止
  3. 控制台日志 2
  4. 动画运行

使用像素:

  1. 控制台日志 1
  2. 动画仍在运行
  3. 控制台日志 2
  4. 动画结束