2

我想实现基于边界矩形的选择,但采用不同的方法。

场景:如果我在对象内部绘制对象,例如第一个文本,然后在其上绘制矩形,然后是椭圆,然后是三角形。现在我应该能够选择文本或矩形或椭圆或相反的顺序。当我开始悬停三角形的边界矩形时,选择或活动对象应该是三角形,但是当我将鼠标移到椭圆的边界矩形上时,当前对象应该显示为椭圆等等,无论我添加对象的顺序如何在画布上。

我尝试使用perPixelTargetFind并遵循解决方案Fabricjs - 仅通过边框选择,这两种解决方案都无法满足我的要求。我正在使用 FabricJS 版本3.6.3

提前致谢。在此处输入图像描述

4

1 回答 1

0

首先你需要设置perPixelTargetFind: truetargetFindTolerance:5。现在你将面临选择的问题。

问题:如果您按下鼠标并在空白处拖动,则该对象被选中。

解决方案:找到了一种方法来做到这一点。我通过结构的机制进行了调试,以获取当前鼠标指针位置上的对象。有一个函数_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;
    }
于 2021-03-26T06:53:28.473 回答