如何获取组中对象的画布相对位置?

问题描述 投票:0回答:7

通常,对象相对于画布的位置可以从其

.left
.top
属性中获取,但如果对象位于选择/组中,则这些属性将变得相对于组。有没有办法获得它们相对于画布的位置?

javascript fabricjs
7个回答
39
投票

当对象位于组内时,其相对于画布的坐标将取决于组的原点(以及对象的原点)。

假设我们有这段代码,其中将一个矩形和一个圆添加到一个组中。

var canvas = new fabric.Canvas(document.getElementById('c'));

var rect = new fabric.Rect({
    width: 100,
    height: 100,
    left: 50,
    top: 50,
    fill: 'rgba(255,0,0,0.5)'
});
var circle = new fabric.Circle({
    radius: 50,
    left: 175,
    top: 75,
    fill: '#aac'
});

var group = new fabric.Group([rect, circle],{
    originX: 'center',
    originY: 'center'
});
canvas.add(group);
canvas.renderAll();

以下是可能使组居中的三种情况:

  1. 组的原点设置为中心(如上面的代码):

    如下图所示,

    rect.left
    给出了对象左侧距组中心的距离。
    rect.group.left
    给出了组中心距画布左侧的距离。

    所以矩形距画布左侧的距离 =

    rect.left + rect.group.left
    (http://jsfiddle.net/uue3hcj6/3/)

    enter image description here

  2. 组的原点设置为顶部/左侧(也是默认设置)

    rect.left
    给出了对象左侧距组中心的距离。
    rect.group.left
    给出了组左侧与画布左侧的距离。现在要计算剩余距离,我们必须添加组宽度的一半。

    所以矩形距画布左侧的距离 =

    rect.left + rect.group.left
    +
    rect.group.width/2
    (http://jsfiddle.net/uue3hcj6/6/)

    enter image description here

  3. 组的原点设置为底部/右侧

    rect.left
    给出了对象左侧距组中心的距离。
    rect.group.left
    给出了组右侧与画布左侧的距离。现在要计算总距离,我们必须减去组宽度的一半。

    所以矩形距画布左侧的距离 =

    rect.left + rect.group.left
    -
    rect.group.width/2
    (http://jsfiddle.net/uue3hcj6/7/)

    enter image description here

注意:类似的情况也可能发生在对象上。


3
投票

作为对 Swapnil Jain 答案的补充

top
属性也是如此。

所以:

absoluteLeft = rect.left + rect.group.left - rect.group.width / 2
absoluteTop = rect.top + rect.group.top - rect.group.height / 2

1
投票

有通用的方法来计算画布上任何对象的位置,无论组和原点如何:

const position = fabric.util.transformPoint(
  // you can choose point of object (left/center/right, top/center/bottom)
  object.getPointByOrigin('left', 'top'), 
  object.calcTransformMatrix()
)

0
投票

解决方案是考虑组宽度。

object.left
是相对于组的中心,而不是其左侧,所以我们采用
group.width/2
:

var canvas = new fabric.Canvas(document.getElementById('c'));

var rect = new fabric.Rect({
    width: 100,
    height: 100,
    left: 50,
    top: 50,
    fill: 'rgba(255,0,0,0.5)'
});
var circle = new fabric.Circle({
    radius: 50,
    left: 150,
    top: 75,
    fill: '#aac'
});


canvas.add(rect);
canvas.add(circle);
canvas.renderAll();

function getPOS(){
    var group = canvas.getActiveGroup();
    if (group == null) {
        var pos = rect.left;
    }
    else {
        var pos = rect.group.left + rect.group.width/2 + rect.left;
    }
    alert("Position of rect from left:"+pos);
}

0
投票

必须用另一种方法解决这个问题...... 我必须在 JSON 画布数据中查找图像,所以我的代码是:

let findItemByType = function(source, type, rX, rY)
{
    rX = rX ? rX : 0;
    rY = rY ? rY : 0;
    let objs = [];
    source.forEach(function(item){
        if (item.type === type){
            item.rX = rX + item.left;
            item.rY = rY + item.top;
            objs.push(item);
        }
        else {
            if (item.objects)
            {
                item.rX = rX;
                item.rY = rY;
                let subresult = findItemByType(item.objects, 
                type, 
                item.rX + item.left + item.width / 2, 
                item.rY + item.top + item.height / 2);
                if (subresult){
                    objs = objs.concat(subresult);
                }
            }   
        }
    });
    return objs;
}
let images = findItemByType(canvas.toJSON().objects, "image", 0, 0);

此代码应带来所有图像对象的数组,并且它们应具有 rX 和 rY 属性,即图像的相对位置。


0
投票

一种不需要判断originX originY属性的方法。

const groupCenter = rect.group.getPointByOrigin('center', 'center');
absoluteLeft = rect.left + rect.group.left;
absoluteTop = rect.top + rect.group.top;


0
投票

如果是角度或缩放怎么办?

© www.soinside.com 2019 - 2024. All rights reserved.