fabricjs图像在画布上的位置不一致 [英] fabricjs placement of images on canvas inconsistent

查看:445
本文介绍了fabricjs图像在画布上的位置不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列4张图像,试图将它们放置在fabricjs中的指定坐标上,有时在页面加载时会不一致地放置它们。刷新一次或两次通常会给出正确的布局。试图防止这种情况发生。

I have a series of 4 images which I'm attempting to place at specified coordinates in fabricjs, and I'm getting them placed inconsistently sometimes when the page loads. Refreshing once or twice will usually give the correct layout. Trying to prevent this from happening.

有人知道如何解决吗?这是我的代码:

Anybody know how to solve this? Here's my code:

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 插件。

I should mention also that none of this code happens until after window.ready, and after all the images that fabric is attempting to load to canvas have been preloaded using the imagesloaded plugin.

我还应该提到,我已经尝试过在每次加载之间使用setTimeout来延迟每个连续图像的加载(而不是循环),并保存canvas.renderAll()直到循环之后,否则均不会成功。甚至尝试将它们放到屏幕上后运行一个循环来重新放置它们。以下是该问题的图片-分别是正确和错误。

I should also mention that I've tried delaying the loading of each successive image using setTimeout between each load (instead of a loop), and saving the canvas.renderAll() until after the loop, with no success. Even tried running a loop to re-position the items after they were placed on screen. Below are images of the issue - correct, and incorrect, respectively.

推荐答案

您似乎从不同顺序加载的图像中看到了竞争状况。

It looks like you have a race condition from the images loading in different orders.

fabric.Image.fromURL()方法正在使用回调函数,该函数会在加载图像后触发,因此不能保证您拥有该内部函数以您调用它的相同顺序触发。但是,您使用 curObject 每次调用该函数时都向上递增,这假定它们是按顺序调用的。并且 objRef 可以在图像加载时重新分配给新对象,这就是x / y / rotate值关闭的原因(使用

The fabric.Image.fromURL() method is using a callback function, which fires after the image has loaded, so you're not guaranteed to have that inner function fire in the same order you called it. But you're using curObject to increment upwards each time the function is called, which assumes they're called in order. And the objRef can get re-assigned to a new object by the time the image loads, which would be why the x/y/rotate values are off (using the values from the other objects in the array).

因此,在图像处理完后,不要使用 img.set()加载后,使用 Image.fromURL()方法的第三个参数传递您的属性:

So, instead of using img.set() after the image had loaded, use the third parameter of the Image.fromURL() method to pass in your attributes:

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;
  }
}

这篇关于fabricjs图像在画布上的位置不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆