CSS3 值频繁变化时转换过渡会卡顿(与性能无关)

CSS3 transform transition stutters when value changes frequently (not performance related)

我目前正在 HTML 和 CSS PhoneGap 项目中构建一个指南针应用程序,使用 DeviceOrientation plugin 获取指南针航向。

我创建了 a jsbin to emulate the heading change

我遇到的问题是,当值频繁变化时(每 200 毫秒),CSS 转换会出现相当多的断断续续。

你可以通过转到我上面链接的 jsbin 并慢慢拖动滑块来增加或减小旋转度来看到这个问题,特别是当你缓慢地来回拖动滑块时。

这让我相信这不仅仅是性能或帧率问题;这很可能是由中断转换的快速值变化引起的。

请注意在实际的 PhoneGap 应用程序中,罗盘值每 200 毫秒(或其他任意时间间隔)刷新一次,而不是您在 jsbin 模拟中看到的不一致的更新间隔.

我试着调整一下过渡持续时间,none 成功了。这是我尝试过的:

  1. 尝试使转换持续时间比值更改间隔短 0.5 毫秒。例如。每 500 毫秒获取新值,将转换持续时间设置为 450 毫秒。不仅让我口吃,还让整个过渡明显欠缺。
  2. 试图使过渡持续时间比更新间隔长(出于绝望),惊讶于它的工作...一段时间然后又开始让我口吃。
  3. 试图使过渡持续时间与更新间隔相同,同样卡顿。

现在我的问题是:当旋转值频繁变化时,我应该如何使 CSS3 过渡平滑而不卡顿? 另外,是否切换到 JavaScript 动画缓解了这个问题,比如在值改变时暂停过渡?

解法:

用 Javascript 动画替换 CSS3 过渡。我使用 Velocity.js 作为动画。每次指南针航向值发生变化时,我首先通过执行 Velocity(compass_element, "finish") 来完成上一个动画,然后为该元素的 rotateZ 设置动画。

在 CodeMentor 上看到了您的 post。问题是每次值更改时,它 停止 当前正在发生的转换并开始另一个相同(长)持续时间的转换。如果这是快速连续完成的,它看起来并没有做很多事情,因为它试图不断地缓和并且永远不会进入过渡太远,从而导致卡顿。

您需要根据行进的距离来进行转换,而不仅仅是像您现在这样的时间。有很多方法可以做到这一点,一对夫妇如下:

  • 每次值更改时,计算指针需要移动多远,并根据一些速度和缓动输入为其创建过渡。
  • 每次值变化时都以对数方式逼近新目标。这意味着每 n 分之一秒,您将向目标移动大约 1/k 的距离(只要距离至少为一个像素),其中 k 是某个常数,例如 2。因此,如果您转换元素每 0.05 秒中途,它会相当快地接近目标。使用这种方法的难点在于开始时看起来还不错,我不确定它到底是如何工作的,它可能需要一些尝试。

另一个选项(我个人可能会这样做)只是让过渡持续时间更短,拖动时,0.1s 似乎效果很好。您可以将 dragstart 上的过渡持续时间更改为这个较短的值,然后将其切换回 dragstop,为点击留出更长的过渡持续时间。