gpt4 book ai didi

javascript - 为什么每次删除并重新创建目标元素时动画速度都会增加?

转载 作者:行者123 更新时间:2023-11-27 22:30:21 24 4
gpt4 key购买 nike

我根据其他人的 Chrome 实验创建了一个 jQuery 插件,该插件将 Canvas 元素插入目标元素,并在 Canvas 中绘制交互式星空。

每次调整窗口大小时,canvas 元素都会被删除然后恢复,以便它的大小与其父元素匹配并且一切都正确地进行动画处理;它是响应式的。

但是,无论何时恢复,动画速度都会增加。为什么要这样做?我认为所有变量(包括速度)都已使用 this.start() 方法重置为其默认值。

您可以在 CodePen 上查看代码(和演示) ;你也可以在 Github 上 fork 它,尽管我认为 Github 版本比我自己的版本落后了几个提交。

(此外,这是我的第一个真正的 jQuery 插件,所以如果您发现任何问题,请务必告诉我。)

有什么线索吗?

最佳答案

单独使用 cancelAnimationFrame 不一定会停止动画循环(事实证明)。

为了绝对确定您还需要使用条件检查 - 一个通用示例:

var isPlaying; /// our condition

function loop() {

/* funky stuff here */

If (isPlaying === true)
requestId = requestAnimationFrame(loop);
}

然后启动它:

functiom start() {
isPlaying = true;
loop();
}

现在当你想停止你需要做的动画时:

function stop() {

isPlaying = false;

/// kill any request in progress
if (requestId) cancelAnimationFrame(requestId);
}

如果您不这样做,您将面临堆积循环调用的风险 - 例如:

如果您调整大小并且 cAF 没有阻止 rAF 重新触发循环,则旧循环仍将在后台运行,您将在此之上开始一个新循环。

这就是为什么您会看到速度增加的原因,因为旧循环和新循环都会在星星被绘制到屏幕之前增加位置。

在第三次调整大小时,又开始了另一个循环,最终整个过程将阻塞浏览器。

然而

我建议您使用以下方法,而不是利用循环的开始和停止:

  • 一次创建 Canvas
  • 只开始循环一次
  • 在这种情况下,对整个调整大小机制进行重构可能会有所帮助(例如,将需要的初始化(元素的宽度和高度)与可以在以后重新使用的首次初始化分开)。<
  • 无需为每次调整大小重新初始化星星,因为您将使用宽度和高度来检查它们的边界(canvas 会进行剪裁)。

在调整大小时,您可以考虑使用条件标志来防止在调整大小时渲染

尽管通常情况下,由于 JavaScript 的单线程特性,在 Canvas 更改大小时阻止渲染的条件实际上不是必需的,在这种情况下,您会对当前元素大小进行边界检查。 Canvas 本身会为您处理剪裁。

也就是说:不需要每次都重新创建 Canvas 元素。

这会产生不必要的开销。如果 Canvas 已经创建,只需在其属性上设置新的宽度和高度:

if (typeof canvas === 'undefined')
canvas = /* only create if it doesn't exist */

canvas.width = width;
canvas.height = height;

附言: I "hampered" a version with some brute-force-ish implementations 以上。它远未完成或质量不高,但为了示例而消除了一些痛苦,为您提供了一些指导。

请根据您的需要采用。

更新:

要包含来自附加评论的更多信息:

当在 Canvas 元素上设置新尺寸时,其上下文将重置为默认值(fillStyle 变为透明,strokeStyle 变为黑色,变换为重置等等)。

这意味着所有非默认设置必须在每次设置新尺寸后重新设置。

设置新的大小可能(并且通常会)清除 Canvas 的内容,以便所有像素都变成透明的黑色。

关于javascript - 为什么每次删除并重新创建目标元素时动画速度都会增加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18476545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com