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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29829475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 11:08:07  来源:igfitidea点击:

How to get the canvas-relative position of an object that is in a group?

javascriptfabricjs

提问by Jasper van den Bosch

Normally an object's position relative to the canvas can be gotten from it's .leftand .topattributes, but these become relative to the group if the object is in a selection/group. Is there a way to get their position relative to the canvas?

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

回答by Swapnil Jain

When an object is inside a group, its coordinates relative to the canvas will depend on the origin of the group (and origin of the object as well).

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

Lets say we have this code which has a rect and a circle added to a group.

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

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();

Below are the three cases possible for centering the group:

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

  1. Origin of group set to center(as in the code above):

    As shown in the figure below, rect.leftgives us distance of left of object from center of the group. rect.group.leftgives us the distance of center of group from left of canvas.

    So distance of rect from left of canvas = rect.left + rect.group.left(http://jsfiddle.net/uue3hcj6/3/)

    enter image description here

  2. Origin of group is set to top/left (also the default setting)

    rect.leftgives us distance of left of object from center of the group. rect.group.leftgives us the distance of left of group from left of canvas. Now to calculate the remaining distance, we have to add half of width of the group.

    So distance of rect from left of canvas = rect.left + rect.group.left+ rect.group.width/2(http://jsfiddle.net/uue3hcj6/6/)

    enter image description here

  3. Origin of group is set to bottom/right

    rect.leftgives us distance of left of object from center of the group. rect.group.leftgives us the distance of right of group from left of canvas. Now to calculate the total distance, we have to subtract the half of width of the group.

    So distance of rect from left of canvas = rect.left + rect.group.left- rect.group.width/2(http://jsfiddle.net/uue3hcj6/7/)

    enter image description here

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

    如下图所示,rect.left为我们提供了对象左侧与组中心的距离。 rect.group.left给了我们组中心到画布左侧的距离。

    所以从画布左侧的矩形距离 = rect.left + rect.group.left( http://jsfiddle.net/uue3hcj6/3/)

    在此处输入图片说明

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

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

    所以从画布左侧的矩形距离 = rect.left + rect.group.left+ rect.group.width/2( http://jsfiddle.net/uue3hcj6/6/)

    在此处输入图片说明

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

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

    所以从画布左侧的矩形距离 = rect.left + rect.group.left- rect.group.width/2( http://jsfiddle.net/uue3hcj6/7/)

    在此处输入图片说明

Note: Similar cases are possible for object as well.

注意:对象也可能出现类似情况。

回答by Jasper van den Bosch

The solution is to take into account the group width. The object.leftis relative to the group's center, not it's left side, so we take group.width/2:

解决方案是考虑组宽度。在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);
}

回答by Fuat ?engül

Had to solve this issue with another approach... I had to find images in JSON canvas data, so my code is:

不得不用另一种方法解决这个问题……我不得不在 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);

This code should bring an array of all image objects and they should have rX and rY attributes which is relative positions of images.

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