动态添加到画布的图像不是加载JAVASCRIPT

时间:2018-01-04 11:56:34

标签: javascript image canvas

我尝试将图像裁剪成我想要在画布中显示的多个部分。 我在数组中保存坐标,如arr [i] .x,arr [i] .y,arr [i] .cropHeight,arr [i] .cropWidth。如果我有三个裁剪的部分,我将在阵列中有三个元素。

当在数组上进行迭代时,我想创建一个画布,我将其添加到我拥有的div中,使用ID" canvasList"。

我迭代如下:

for(var i = 0; i < arr.length; i++)
            {
                var canvas = document.createElement('canvas');
                canvas.id = "canvas"+ arr[i].x + arr[i].y;
                canvas.width = arr[i].width;
                canvas.height = arr[i].height;
                var context = canvas.getContext("2d");
                var imageObj = new Image();
                imageObj.myCustomData = {
                                            x:arr[i].x, 
                                            y:arr[i].y,
                                            wi: arr[i].width,
                                            he: arr[i].height
                                        };
                imageObj.src = 'example.jpg';
                imageObj.onload = function () {
                    var sourceX = this.myCustomData.x;
                    var sourceY = this.myCustomData.y;
                    var sourceWidth = this.myCustomData.wi;
                    var sourceHeight = this.myCustomData.he;
                    var destWidth = sourceWidth;
                    var destHeight = sourceHeight;
                    var destX = 0;
                    var destY = 0;
                    context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
                };
                document.getElementById('canvasList').appendChild(canvas);
            }

问题是当我在arr中有多个对象时,页面中只显示最后一个对象,我不明白为什么。

请帮帮我。 谢谢

enter image description here

1 个答案:

答案 0 :(得分:1)

此行是问题的根源:

context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);

在循环的每次迭代中,您将新的画布上下文定义为context。加载图像(异步)后,它将渲染context上的所有裁剪图像。

由于您正在加载图像异步,循环将在加载图像之前完成,这意味着您使用image.onload函数的context变量等于最后一个上下文集=最后一个作物对象。

因此,所有image.onload函数都使用最后设置的上下文来渲染图像。

<强>修复

imageObj.myCustomData = {
    x:arr[i].x, 
    y:arr[i].y,
    wi: arr[i].width,
    he: arr[i].height,
    context: context
};

将上下文添加到自定义数据对象。

使用set上下文渲染图像:

this.myCustomData.context.drawImage( .. )

小提琴:https://jsfiddle.net/GustavGenberg/ezpu8oor/

修改

而且,当然,最好只加载一次图像:

https://jsfiddle.net/GustavGenberg/Loyu9tvo/