HTML Canvas渲染混乱

时间:2020-04-26 20:54:08

标签: javascript html canvas

我一直在研究一个小程序,它可以从几层中生成一个完整的图像。我需要将它们全部放在一个画布上,以便可以将最终产品保存为单个图像。但是,当我运行代码时,它将以随机顺序绘制图层。如果有人可以向我解释如何按顺序渲染图层,我将不胜感激!

function addimage(image, layer) {
var canvas = document.getElementById('paper'),
context = canvas.getContext('2d');

var img = new Image();
img.src = "Images/" + image;
img.onload = function(){
    if (image == "Khundii_Agouti_Basic.png"){
        context.globalCompositeOperation = "multiply";
    } else if (image == "Khundii_Agouti_Cinnamon.png"){
        context.globalCompositeOperation = "overlay";
    } else if (layer == "pattern1"){
        context.globalCompositeOperation = "overlay";
    } else {
        context.globalCompositeOperation = "source-over";
    }
    context.drawImage(img, 0, 0, 500, 500);
}
}

上面是将图像添加到画布的代码

addimage(baseImage);
if (pattern1 == true)
    addimage(pattern1Image, "pattern1");
if (pattern2 == true)
    addimage(pattern2Image);
if (tint1 == true)
    addimage(tint1Image);
if (tint2 == true)
    addimage(tint2Image);
if (agouti == true)
    addimage(agoutiImage);
addimage(maneImage);
addimage(eyeImage);

addimage("Khundii_Line_Black.png");

在这里被称为

要查看更多代码,请参见here

1 个答案:

答案 0 :(得分:1)

这种看似随机排序的原因是由于渲染图像之前的加载时间。由于加载是一个异步过程,因此计算机将遍历所有图像并开始连续加载它们。取决于图像,与最后一个图像相比,计算机加载第一张图像可能要花费更多时间。

现在我们了解了问题所在,可能的解决方法是什么?最糟糕的情况是使图像同步加载。我将在此处留下link供参考,但是这样做绝不是一个好主意。更好的方法是为addImage函数提供一个回调函数。这样的事情可以解决问题:

function addimage(image, layer, callback) {
    var canvas = document.getElementById('paper'),
    context = canvas.getContext('2d');

    var img = new Image();
    img.src = "Images/" + image;
    img.onload = function(){
        if (image == "Khundii_Agouti_Basic.png"){
            context.globalCompositeOperation = "multiply";
        } else if (image == "Khundii_Agouti_Cinnamon.png"){
            context.globalCompositeOperation = "overlay";
        } else if (layer == "pattern1"){
            context.globalCompositeOperation = "overlay";
        } else {
            context.globalCompositeOperation = "source-over";
        }
        context.drawImage(img, 0, 0, 500, 500);
        callback();
    }
}

要使用此功能,只需将要稍后运行的所有代码放入回调函数中即可。