我有一组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);
}
有人可以在这里指导我实现这一目标的最佳方法吗?
答案 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(不是必需的,但可能有助于栅格化过程)。在使用naturalWidth
和naturalHeight
读取原始维度时,此维度由具有相同名称的属性读取。
根据需要进行修改。希望这会有所帮助。