【问题标题】:Questions about Request Animation Frame关于请求动画帧的问题
【发布时间】:2012-05-23 02:10:35
【问题描述】:

我正在尝试构建一个视差网站,它会在滚动网站时移动一些元素。 但是在阅读this post by Paul Irishthis video 之后,我使用requestAnimationFrame 而不是滚动事件监听器,这表明滚动监听器有点错误。我的问题是:

  1. 在 Chrome 中看起来很流畅,但在 Firefox 中闪烁很严重。我在这里做错了吗?
  2. 我的代码实际上是否比使用普通的滚动事件监听器占用更多的资源?每次我使用这段代码时,我都能听到我的笔记本电脑风扇在燃烧。

我的文件位于http://www.socialbuzz.com.au/index.html,请滚动到页面底部以查看正在从 javascript 操作的元素。

【问题讨论】:

  • 您应该将使用requestAnimationFrame的相关代码添加到您的问题中,以供您更新网站后的未来读者使用。
  • 另外,this 是您指的关于requestAnimationFrame 的文章吗?

标签: javascript css frontend parallax requestanimationframe


【解决方案1】:

你应该有一个滚动事件触发 requestAnimationFrame 循环。滚动事件本身不会触发 requestAnimationFrame。你应该有类似 var scrolling = true; 的东西。发生这种情况时,运行您的 requestAnimationFrame 循环,该循环引用来自滚动事件的事件数据。完成后,您需要对滚动事件进行去抖动以关闭循环,这是一件苦差事,但结果是值得的。希望这可以帮助。

【讨论】:

  • 好的,所以我有一个requestAnimationFrame 对象,如果浏览器在视图中,我运行requestAnimationFrame 循环。一旦它不在视野中,我就停止循环?
  • 通过查看您的代码,您的 rAF 位于 jQuery 每个函数中,因此您实际上每帧调用它 4 次。我最初的观点主要是您可以保留滚动侦听器。您的滚动监听器唯一需要做的就是获取您需要的数字(scrollTop 或其他)并让 requestAnimationFrame 知道它需要开始运行(通过滚动变量)。用户停止滚动后,您将变量设置为 false。你的循环应该是这样的。 (function animloop(){ if(scrolling){ requestAnimFrame(animloop); render(); })();
  • 好的..你如何阻止 rAF 运行?我应该喜欢var raf1 = requestAnimFrame(animloop);,然后当我想停止它时,我会喜欢window.cancelAnimFrame(raf1)
  • 我基本上通过去抖动来做到这一点。因此,当触发滚动事件时,它只调用一个设置 var scrolling = true 的函数并调用 animLoop()。要在每次调用滚动事件时设置一个超时,如果在调用函数时存在,则清除它。完成后,setTimeout 的回调应该会关闭您的循环。这样,您的滚动事件只会打开 animLoop 函数,并且它将在 x 毫秒后关闭(无论您将 debounce setTimeout 设置为什么)。在您的动画循环中,它应该看起来像 if(scrolling) rAF(animLoop);渲染动画();
【解决方案2】:

没有在执行动画;也就是说,您不会在没有用户交互的情况下不断地修改图形。您对页面的操作在用户滚动时发生,并且在用户停止滚动后不会继续。因此,使用requestAnimationFrame 没有任何好处,您应该坚持使用简单的事件处理程序。

requestAnimationFrame 的目的是为连续动画提供最佳行为;它的任何优点都不适用于这里。如果循环的每一步都以某种方式更新图形,则循环内不执行任何操作的循环 requestAnimationFrame 是完全合适的,但是当用户不滚动时,循环什么都不做浪费 CPU 时间。

当您应该使用requestAnimationFrame 的一个例子是,如果您的元素故意落后于滚动并在片刻后赶上。追赶动画应该在从滚动事件处理程序启动的requestAnimationFrame 循环中完成,并且该循环应该在追赶结束时自行停止

【讨论】:

  • 是的,我明白你的意思,requestAnimationFrame 不适合我的问题。但回到我的主要问题,这是 Firefox 中的抖动效果。有什么我可以做的让它更平滑吗?
  • 我在 Mac OS X 上的 Firefox 12.0 中查看时没有看到任何抖动或闪烁,所以我无法研究这个问题,抱歉。但是,如果您正在响应滚动,那么如果响应是延迟,就会出现这样的效果,这正是您响应滚动而不是直接在滚动处理程序中发生的情况,所以我建议您取出requestAnimationFrame,然后看看会发生什么。
  • 我认为这个答案是错误的......从问题中没有原始站点很难说,但通常使用滚动操作来实现请求动画帧是合适的。滚动事件会随机触发,使用 requestAnimationFrame 会获得更流畅的外观和感觉。见:youtube.com/…
  • 是的,这是我以前看过的视频。但是,是的,我还没有得到满意的答案..
  • @KevinReid 没错,我的措辞很糟糕。更重要的是 rAF 与浏览器的绘制周期同步。如果您开始构建一个测试页面,我很想看看您的测试页面!
【解决方案3】:

我有过类似的经历,在玩了很多鼠标移动侦听器和setInterval 以增加动画步骤的频率后,我又回到了只使用onscroll 并在 FF10 和 FF 15 上发现它效果很好。

也许我的要求和你的不一样——它是一个跟踪滚动条的元素,所以 onscroll 是改变框位置的提示。它落后并且在 FF 上很生涩,但在 WebKit 和 IE 上运行良好。我发现onscroll 在 FF 上的触发频率不如在 Chrome/IE 上的频繁。

当我最初尝试这个时,它会在 FF 5 或 6 上。使用鼠标移动侦听器或频繁间隔,我能够增加调用手柄滚动功能的频率 - 但这实际上具有使定位看起来更不稳定的效果。现在在 10 ESR 和 15 上使用 onscroll 似乎对我有用,也许他们修复了一些问题。

【讨论】:

  • 是的,我最终回到了onmousescroll 事件。然后为了减少断断续续的效果,我使用了css transition 而不是jquery 动画。它效果更好..但我想了解更多关于request animation frame 我相信这是一个很好的技术..
猜你喜欢
  • 2020-12-23
  • 1970-01-01
  • 2012-12-27
  • 2013-05-09
  • 2015-12-25
  • 2014-04-19
  • 2013-03-29
  • 2011-10-23
  • 1970-01-01
相关资源
最近更新 更多