将图像加载到HTML Canvas中

时间:2014-01-15 00:12:31

标签: html5 html5-canvas

我有一组svg图像和一些我想要加载到HTML Canvas上的属性。目标是将图像以给定的大小加载到给定的x,y坐标上。这是我的示例对象:

var ObjectInstances = {
objects:[
    {
    "ID": "1234",
    "Name": "Backhoe",
    "x": "0",
    "y": "0",
    "height": "150",
    "width": "350",
    "svg": "images/svgs/backhoe.svg"
    },
    {
    "ID": "5678",
    "Name": "Crane",
    "x": "350",
    "y": "150",
    "height": "200",
    "width": "200",
    "svg": "images/svgs/crane1.svg"
    }
] 
};

最理想的是,我会遍历对象,并使用这些键:值对将每个图像渲染到画布上,但我不断遇到对象在重新加载后以不同大小或不同位置出现的情况。我从研究中得知,我必须预先加载所有图像,以便在画布上绘制它们。我已经创建了并行数组来处理这个问题。一个数组用于保存预加载的图像,另一个数组用于保存每个图像的坐标和大小。然后我尝试使用这两个数组绘制图像。这是我的代码:

function loadImages(sources, callback) {
    var images = {};
    var loadedImages = 0;
    var numImages = 0;
    // get num of sources
    for(var src in sources) {
    numImages++;
    }
    for(var src in sources) {
    images[src] = new Image();
    images[src].onload = function() {
        if(++loadedImages >= numImages) {
        callback(images);
        }
    };
    images[src].src = sources[src];
    }
}

// Preload images into a source array
var sources = {};
$.each(ObjectInstances.objects, function(index, value) {
        sources[index]=this.svg;
})

loadImages(sources, function(images) {

$.each(ObjectInstances.objects, function (index, value) {
    var x=$(this)[0].x,
        y=$(this)[0].y,
        w=$(this)[0].width,
        h=$(this)[0].height;
    attach(images[index], x, y, w, h);

});

});


// Load Object Instances

function attach(img, x, y, w, h) {
    context.drawImage(img, x, y, w, h);
}

有人可以在这里指导我实现这一目标的最佳方法吗?

1 个答案:

答案 0 :(得分:1)

我不会将图像元素与其元对象分开。我会用一个数组做这样的事情:

var ObjectInstances = {
objects:[
    {
    "ID": "1234",
    "Name": "Backhoe",
    "x": "0",
    "y": "0",
    "height": "150",
    "width": "350",
    "svg": "images/svgs/backhoe.svg",
    image: null
    },
    {
    "ID": "5678",
    "Name": "Crane",
    "x": "350",
    "y": "150",
    "height": "200",
    "width": "200",
    "svg": "images/svgs/crane1.svg",
    image: null
    }
] 
};

然后迭代数组以通过其url调用加载:

loadImage(ObjectInstances, myCallback);

function loadImages(obj, callback) {

    var i = 0,
        o,
        count = obj.objects.length;

    for(; o = obj.objects[i]; i++) {
        o.image = new Image(o.width, o.height);
        o.image.onload = loader;
        o.image.src = o.svg;
    }

    function loader() {
        count--;
        if (count === 0) callback({
            objectInstances: obj
        });
    }
}

现在,当您遍历原始数组时,您将拥有直接附加到对象本身的有效图像元素(除非发生错误,在这种情况下,回调永远不会被调用,因为代码就在这里 - 添加onerror / onabort事件处理程序处理这种情况)。

请注意,我使用可选的Image参数设置宽度和高度,因为我们正在处理SVG(不是必需的,但可能有助于栅格化过程)。在使用naturalWidthnaturalHeight读取原始维度时,此维度由具有相同名称的属性读取。

根据需要进行修改。希望这会有所帮助。