Fabricjs 选择或悬停基于鼠标在内部对象的对象边界矩形上的位置
Fabricjs selection or hover based on mouse location on object bounding rectangle for inner objects
我想基于边界矩形实现 selection,但采用不同的方法。
场景: 如果我在对象内部绘制对象,比如先是文本,然后在其上绘制矩形,然后是椭圆,然后是三角形。现在我应该能够 select 文本或矩形或椭圆或相反的顺序。
当我开始悬停三角形的边界矩形时,selection 或活动对象应该是三角形,但是当我将鼠标移到椭圆的边界矩形上时,当前对象应该显示为椭圆等等,而不管顺序如何我已经在 canvas.
上添加了对象
我尝试使用 perPixelTargetFind
和以下解决方案 ,这两种解决方案都无法满足我的要求。
我正在使用 FabricJS 版本 3.6.3
提前致谢。
首先你需要设置perPixelTargetFind: true
和targetFindTolerance:5
。
现在你将面临选择的问题。
问题: 如果您按下鼠标并在空白处拖动 space,则对象被选中。
解决方法:找到了解决方法。我调试了结构的机制以获取当前鼠标指针位置上的对象。有一个函数 _collectObjects
检查 intersectsWithRect
(与当前对象的 boundingRect 点相交),isContainedWithinRect
(点是否在 boundingRect 内),containsPoint
(当前鼠标指针指向当前对象位置)。所以你需要覆盖 _collectObjects 函数并删除 containsPoint
检查。那行得通。
覆盖函数:
_collectObjects: function(e) {
var group = [],
currentObject,
x1 = this._groupSelector.ex,
y1 = this._groupSelector.ey,
x2 = x1 + this._groupSelector.left,
y2 = y1 + this._groupSelector.top,
selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),
selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),
allowIntersect = !this.selectionFullyContained,
isClick = x1 === x2 && y1 === y2;
// we iterate reverse order to collect top first in case of click.
for (var i = this._objects.length; i--; ) {
currentObject = this._objects[i];
if (!currentObject || !currentObject.selectable || !currentObject.visible) {
continue;
}
if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||
currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2))
) {
group.push(currentObject);
// only add one object if it's a click
if (isClick) {
break;
}
}
}
if (group.length > 1) {
group = group.filter(function(object) {
return !object.onSelect({ e: e });
});
}
return group;
}
我想基于边界矩形实现 selection,但采用不同的方法。
场景: 如果我在对象内部绘制对象,比如先是文本,然后在其上绘制矩形,然后是椭圆,然后是三角形。现在我应该能够 select 文本或矩形或椭圆或相反的顺序。 当我开始悬停三角形的边界矩形时,selection 或活动对象应该是三角形,但是当我将鼠标移到椭圆的边界矩形上时,当前对象应该显示为椭圆等等,而不管顺序如何我已经在 canvas.
上添加了对象我尝试使用 perPixelTargetFind
和以下解决方案 3.6.3
提前致谢。
首先你需要设置perPixelTargetFind: true
和targetFindTolerance:5
。
现在你将面临选择的问题。
问题: 如果您按下鼠标并在空白处拖动 space,则对象被选中。
解决方法:找到了解决方法。我调试了结构的机制以获取当前鼠标指针位置上的对象。有一个函数 _collectObjects
检查 intersectsWithRect
(与当前对象的 boundingRect 点相交),isContainedWithinRect
(点是否在 boundingRect 内),containsPoint
(当前鼠标指针指向当前对象位置)。所以你需要覆盖 _collectObjects 函数并删除 containsPoint
检查。那行得通。
覆盖函数:
_collectObjects: function(e) {
var group = [],
currentObject,
x1 = this._groupSelector.ex,
y1 = this._groupSelector.ey,
x2 = x1 + this._groupSelector.left,
y2 = y1 + this._groupSelector.top,
selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),
selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),
allowIntersect = !this.selectionFullyContained,
isClick = x1 === x2 && y1 === y2;
// we iterate reverse order to collect top first in case of click.
for (var i = this._objects.length; i--; ) {
currentObject = this._objects[i];
if (!currentObject || !currentObject.selectable || !currentObject.visible) {
continue;
}
if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||
currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2))
) {
group.push(currentObject);
// only add one object if it's a click
if (isClick) {
break;
}
}
}
if (group.length > 1) {
group = group.filter(function(object) {
return !object.onSelect({ e: e });
});
}
return group;
}