我有一些代码可以将特定的DOM元素呈现给画布,就像截取屏幕截图一样。 (它是为特定DOM结构构建的自定义代码,作为图形编辑游戏的一部分,而不是像rasterHTML.js这样的通用库)
代码流程非常具有程序性:
问题在于步骤1与步骤2相比非常密集,并且在步骤2之前没有完成绘制,拧紧图层(实际上我有几个画布同时做几件事,画布是不幸的是,在完成所有绘图之前调整了大小)。我试图在这个小提琴中复制这个:https://jsfiddle.net/1hucuLg9/
在伪代码中:
context.drawComplexSVG(); // slow
context.drawSimpleImage(); //fast
//canvas now has an SVG drawn on top of an image, not underneath.
我已经看到很多setTimeout
例子试图让一个功能一个接一个地执行,但对我来说这似乎是一个黑客攻击...理想情况下我不会&#39 ; t想要延迟执行,只需按严格的顺序执行所有操作。我也看到了postMessage
想法实现这一点的想法,但我不知道你如何将信息传递给自己。在继续之前,确保函数/行完全执行的正确方法是什么(或者在我的情况下,画布是完全更新的 - 它是一样的吗?)?
答案 0 :(得分:1)
"获取一些DOM元素"应该是同步的,不需要任何复杂的代码来处理排序绘制操作。
你在小提琴中遇到的问题是你动态加载一些图像来绘制 - 和for those, you need to wait,这使得操作异步。
承诺是为了你的救援,但你必须正确使用它们。只需像你在自己的回答中那样立即调用resolve
,就可以确保某些异步,但这并不比setTimeout
方法脆弱。相反,你应该始终在异步的核心创建承诺,在你的情况下加载图像:
function loadImage(src) {
return new Promise(resolve, reject) {
var img = new Image();
img.onload = function(){ resolve(img); };
img.onerror = reject;
img.src = src;
});
}
以便您可以在画布绘图代码中使用它:
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);
}
});
答案 1 :(得分:0)
好吧,这似乎可以完成工作:
var promise = new Promise(function(resolve){
context.drawComplexSVG();
resolve();
}
promise.then(function(){
context.drawSimpleImage();
}