当值频繁更改时 CSS3 转换过渡口吃(与性能无关)

Posted

技术标签:

【中文标题】当值频繁更改时 CSS3 转换过渡口吃(与性能无关)【英文标题】:CSS3 transform transition stutters when value changes frequently (not performance related) 【发布时间】:2015-05-17 19:23:54 【问题描述】:

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

我创建了a jsbin to emulate the heading change。

我遇到的问题是,当值频繁更改(每 200 毫秒)时,CSS 过渡会卡顿很多。

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

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

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

我尝试稍微调整一下过渡持续时间,但都没有奏效。这是我尝试过的:

    尝试使转换持续时间比值更改间隔短 0.5 毫秒。例如。每 500 毫秒获取新值,将转换持续时间设置为 450 毫秒。不仅让我结结巴巴,而且让整个过渡过程明显缺乏。 试图使转换持续时间长于更新间隔(出于绝望),但对它的工作感到惊讶......过了一会儿,然后又开始让我口吃。 试图使转换持续时间与更新间隔相同,同样的卡顿。

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

解决方案:

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

【问题讨论】:

【参考方案1】:

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

您需要根据要行驶的距离进行转换,而不仅仅是像您当前那样的时间。有很多方法可以做到这一点,如下所示:

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

另一个选项(我个人可能会这样做)只是使过渡持续时间更短,当拖动时,像 0.1 秒这样的东西似乎工作得很好。您可以将 dragstart 上的过渡持续时间更改为这个较短的值,然后在 dragstop 上将其切换回,从而为点击留下更长的过渡持续时间。

【讨论】:

嗨 Zach,非常感谢您花时间写详细的解释!你能看看我的问题的“请注意”部分吗?我昨天添加了那部分......对不起,我没有明确说这是一个编辑,因为当时没有很多人注意到这个问题。谢谢! @user14412 我的回答是对这两部分的回应 :) 如果您已经尝试过我的建议,那么恐怕我不能充分理解您的问题 是的,我一定会尝试你今天的建议,并让你知道结果。只是想我应该告诉你我的忍者编辑,以防你没有看到它。 对不起,上周我真的没时间尝试,但我今天设法尝试了。首先,非常感谢您的建议!我摆脱了 CSS3 过渡并开始使用 Javascript 动画。结果是惊人的!我将在原始问题中发布我的发现。

以上是关于当值频繁更改时 CSS3 转换过渡口吃(与性能无关)的主要内容,如果未能解决你的问题,请参考以下文章

UINavigation 过渡口吃

特定属性的css3转换延迟

CSS3动画2D3D转换

CSS3实践之路:CSS3的过渡效果(transition)与动画(animation)

CSS3之过渡

css3背景过渡在第一个时闪烁:悬停