gpt4 book ai didi

javascript - 如何确保复杂 Canvas 操作的正确执行顺序

转载 作者:行者123 更新时间:2023-11-27 23:33:31 27 4
gpt4 key购买 nike

我有一些代码可以将特定的 DOM 元素渲染到 Canvas 上,有点像截屏。 (它是为非常特殊的 DOM 结构构建的自定义代码,作为图形编辑游戏的一部分,而不是像 rasterHTML.js 这样的通用库)

代码流程非常程序化:

  1. 获取 A 类的一些 DOM 元素并将它们绘制到 Canvas
  2. 获取B类的一些DOM元素并将它们绘制到 Canvas

问题是,与步骤 2 相比,步骤 1 非常密集,并且在步骤 2 之前没有完成绘制,搞砸了图层(实际上,我有几个 Canvas 同时做几件事,不幸的是, Canvas 被调整了大小)在所有绘图完成之前)。我试图在这个 fiddle 中复制它:https://jsfiddle.net/1hucuLg9/

伪代码:

context.drawComplexSVG(); // slow
context.drawSimpleImage(); //fast
//canvas now has an SVG drawn on top of an image, not underneath.

我见过很多 setTimeout 示例,试图让一个函数依次执行,但对我来说,这似乎有点像黑客……理想情况下我不这样做不想延迟执行,只要严格按顺序执行一切即可。我还看到了 postMessage 的想法来实现这一点,但我不知道如何将消息传递给自己。在继续之前,确保函数/行完全执行(或者在我的情况下, Canvas 完全更新 - 这是同一件事吗?)的正确方法是什么?

最佳答案

“获取一些 DOM 元素”应该是同步的,不需要任何复杂的代码来处理排序绘制操作。

您在 fiddle 中面临的问题是您正在动态加载一些图像来绘制 - 和 for those, you need to wait ,这使得操作异步。

Promise 可以拯救你,但你必须正确使用它们。只需像您在自己的答案中那样立即调用 resolve 即可确保一些异步,但这并不比 setTimeout 方法脆弱。相反,您应该始终在异步的核心创建 promise ,在您的情况下是图像加载:

function loadImage(src) {
return new Promise(resolve, reject) {
var img = new Image();
img.onload = function(){ resolve(img); };
img.onerror = reject;
img.src = src;
});
}

以便您可以在 Canvas 绘图代码中使用它:

function drawSwatches(currentSwatch) {
var data = …;
var url = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(data);

return loadImage(url).then(function(img) {
ctx.drawImage(img, 0, 0, vw, vh);
});
}

然后正确链接它们:

var swatches = Array.from(document.getElementsByClassName("swatch"));
swatches.reduce(function(promise, swatch) {
return promise.then(function() {
return drawSwatches(swatch);
});
}, Promise.resolve()).then(function() {
var otherObjects = document.getElementsByClassName("otherObjects");
for (var i=0; i<otherObjects.length; i++) {
drawOtherObjects(otherObjects[i], 0, 0, 100, 100);
}
});

关于javascript - 如何确保复杂 Canvas 操作的正确执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34335145/

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