我有一系列4张图片,我试图将这些图片放在fabricjs的指定坐标处,并且我有时会在页面加载时将它们放置得不一致。刷新一次或两次通常会给出正确的布局。试图阻止这种情况发生。
有谁知道如何解决这个问题?这是我的代码:
var objects = [
{ type: "image", filename : "tv.png" , x: 688, y: 184, angle: 0, zIndex: 10 },
{ type: "image", filename : "polaroid.jpg" , x: 347, y: 515 },
{ type: "image", filename : "polaroid.jpg" , x: 138, y: 643 },
{ type: "image", filename : "polaroid.jpg" , x: 429, y: 803 },
{ type: "text", text: "Your favorite band", x: 1168, y: 1163, angle: -17, canvasRef: null,zIndex: 50 }
];
for (var i=0; i<objects.length;i++){
var objRef = objects[i];
switch(objRef.type){
case 'image':
var url = "img/" + objRef.filename;
fabric.Image.fromURL(url, function(img) {
var objRef = objects[curObject];
img.set({
left: objRef.x,
top: objRef.y,
angle: objRef.angle,
hasBorders: false,
hasControls: false,
hasRotatingPoint: false,
lockMovementX: true,
lockMovementY: true
});
canvas.add(img).renderAll();
img.moveTo(objRef.zIndex);
curObject++;
//canvas.setActiveObject(img);
});
break;
case 'text':
var text = objRef.text;
var fabricText = new fabric.Text(text, {
left: objRef.x,
top: objRef.y,
angle: objRef.angle,
hasBorders: false,
hasControls: false,
hasRotatingPoint: false,
lockMovementX: true,
lockMovementY: true
});
objRef.canvasRef = fabricText;
addTextListeners(fabricText);
canvas.add(fabricText);
break;
}
}
我还应该提一下,这个代码在window.ready之后都没有发生,并且在所有使用imagesloaded插件预加载了Fabric尝试加载到画布的图像之后。
我还应该提一下,我已尝试在每次加载(而不是循环)之间使用setTimeout延迟每个连续图像的加载,并将canvas.renderAll()保存到循环之后,但没有成功。甚至尝试在将项目放置在屏幕上之后运行循环来重新定位项目。以下是问题的图像 - 分别是正确的和不正确的。
答案 0 :(得分:5)
看起来您在不同订单中加载图片时会遇到竞争条件。
fabric.Image.fromURL()
方法正在使用回调函数,该函数在图像加载后触发,因此您无法保证内部函数的激活顺序与您调用它的顺序相同。但是,每次调用函数时,您都会使用curObject
向上递增,这假设它们按顺序被调用。并且objRef
可以在图像加载时重新分配给新对象,这就是x / y / rotate值关闭的原因(使用数组中其他对象的值)。 / p>
因此,在加载图片后,不要使用img.set()
,而是使用Image.fromURL()
方法的第三个参数传入属性:
for (var i=0; i<objects.length;i++){
var objRef = objects[i];
switch(objRef.type){
case 'image':
var url = "img/" + objRef.filename;
fabric.Image.fromURL(url, function(img) {
canvas.add(img).renderAll();
}, {
left: objRef.x,
top: objRef.y,
angle: objRef.angle,
hasBorders: false,
hasControls: false,
hasRotatingPoint: false,
lockMovementX: true,
lockMovementY: true
});
break;
case 'text':
// ...
break;
}
}
答案 1 :(得分:0)
所以答案的关键是异步回叫。只需检查何时调出Alert消息。
fabric.Image.fromURL('hulk.png', function (img) {
alert('came1');
canvas.add(img).renderAll();
}, {
id: 'hulkid',
num: 1,
left: 10,
top: 10,
angle: 0
});
fabric.Image.fromURL('hulk.png', function (img) {
alert('came2');
canvas.add(img).renderAll();
}, {
id: 'hulkid',
num: 2,
left: 25,
top: 25,
angle: 0
});
alert('came Last');
答案 2 :(得分:0)
我发现了setTimeout函数的方法。
我用MidnightLightning的样本进行了测试
但是画布中的图像z-index仍然存在一些问题(所有设置都不错)。我认为有时fabric.Image.fromURL回调函数正在等待图像加载,因此在绘制图像的队列中会出现一些错误。
所以我给函数添加了一些超时时间。
var count_layer=0;
var image_src_list_array=['1.jpg', '2.jpg'];
function paint_layer(){
console.log(image_src_list_array[count_layer]);
if(image_src_list_array[count_layer]!=''){
fabric.Image.fromURL(
image_src_list_array[count_layer],
function(img){
console.log('rendering');
fabric_canvas.add(img).renderAll();
}, {
id: count_layer+1,
left: ...,
top: ...,
angle: ...,}
);
count_layer++;
setTimeout(paint_layer,3000);
}
}
然后,控制台日志结果为:
1.jpg
rendering
2.jpg
rendering
在输出之前
1.jpg
2.jpg
rendering
rendering