如何获取组中对象的canvas-相对位置?
How to get the canvas-relative position of an object that is in a group?
通常一个对象相对于 canvas 的位置可以从它的 .left
和 .top
属性中得到,但是如果对象在 selection/group。有没有办法让他们相对于canvas的位置?
解决方法是考虑组宽度。 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);
}
当对象在组内时,其相对于 canvas 的坐标将取决于组的原点(以及对象的原点)。
假设我们有这段代码,其中添加了一个矩形和一个圆圈。
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();
以下是可以使组居中的三种情况:
组原点设置为中心(如上面的代码所示):
如下图所示,rect.left
给出了对象左侧到组中心的距离。
rect.group.left
给出了组中心距 canvas 左侧的距离。
所以矩形距离 canvas = rect.left + rect.group.left
(http://jsfiddle.net/uue3hcj6/3/)
组原点设置为top/left(也是默认设置)
rect.left
给出了对象左侧与组中心的距离。
rect.group.left
给出了组左侧与 canvas 左侧的距离。现在要计算剩余距离,我们必须加上组宽度的一半。
所以矩形距离 canvas = rect.left + rect.group.left
+ rect.group.width/2
(http://jsfiddle.net/uue3hcj6/6/)
组的原点设置为bottom/right
rect.left
给出了对象左侧与组中心的距离。
rect.group.left
给出了组右侧与 canvas 左侧的距离。现在要计算总距离,我们必须减去组宽度的一半。
所以矩形距离 canvas = rect.left + rect.group.left
- rect.group.width/2
(http://jsfiddle.net/uue3hcj6/7/)
注意:对象也可能有类似情况。
不得不用另一种方法解决这个问题...
我必须在 JSON canvas 数据中找到图像,所以我的代码是:
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 属性,即图像的相对位置。
作为 的补充,top
属性也是如此。
所以:
absoluteLeft = rect.left + rect.group.left - rect.group.width / 2
absoluteTop = rect.top + rect.group.top - rect.group.height / 2
不需要判断originX originY属性的方法
const groupCenter = rect.group.getPointByOrigin('center', 'center');
absoluteLeft = rect.left + rect.group.left;
absoluteTop = rect.top + rect.group.top;
有一种通用的方法可以计算任何对象在 canvas 上的位置,而不考虑组和来源:
const position = fabric.util.transformPoint(
// you can choose point of object (left/center/right, top/center/bottom)
object.getPointByOrigin('left', 'top'),
object.calcTransformMatrix()
)
通常一个对象相对于 canvas 的位置可以从它的 .left
和 .top
属性中得到,但是如果对象在 selection/group。有没有办法让他们相对于canvas的位置?
解决方法是考虑组宽度。 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);
}
当对象在组内时,其相对于 canvas 的坐标将取决于组的原点(以及对象的原点)。
假设我们有这段代码,其中添加了一个矩形和一个圆圈。
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();
以下是可以使组居中的三种情况:
组原点设置为中心(如上面的代码所示):
如下图所示,
rect.left
给出了对象左侧到组中心的距离。rect.group.left
给出了组中心距 canvas 左侧的距离。所以矩形距离 canvas =
rect.left + rect.group.left
(http://jsfiddle.net/uue3hcj6/3/)组原点设置为top/left(也是默认设置)
rect.left
给出了对象左侧与组中心的距离。rect.group.left
给出了组左侧与 canvas 左侧的距离。现在要计算剩余距离,我们必须加上组宽度的一半。所以矩形距离 canvas =
rect.left + rect.group.left
+rect.group.width/2
(http://jsfiddle.net/uue3hcj6/6/)组的原点设置为bottom/right
rect.left
给出了对象左侧与组中心的距离。rect.group.left
给出了组右侧与 canvas 左侧的距离。现在要计算总距离,我们必须减去组宽度的一半。所以矩形距离 canvas =
rect.left + rect.group.left
-rect.group.width/2
(http://jsfiddle.net/uue3hcj6/7/)
注意:对象也可能有类似情况。
不得不用另一种方法解决这个问题... 我必须在 JSON canvas 数据中找到图像,所以我的代码是:
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 属性,即图像的相对位置。
作为 top
属性也是如此。
所以:
absoluteLeft = rect.left + rect.group.left - rect.group.width / 2
absoluteTop = rect.top + rect.group.top - rect.group.height / 2
不需要判断originX originY属性的方法
const groupCenter = rect.group.getPointByOrigin('center', 'center');
absoluteLeft = rect.left + rect.group.left;
absoluteTop = rect.top + rect.group.top;
有一种通用的方法可以计算任何对象在 canvas 上的位置,而不考虑组和来源:
const position = fabric.util.transformPoint(
// you can choose point of object (left/center/right, top/center/bottom)
object.getPointByOrigin('left', 'top'),
object.calcTransformMatrix()
)