簡體   English   中英

FabricJS 選擇處理多個對象

[英]FabricJS selection handling multiple objects

我正在努力處理多個對象的選擇。 所需的行為是每個被單擊的 object 都將被添加到當前選擇中。 與按住 shift 鍵類似,但使用拖動選項的選擇也應添加到現有選擇中。 即使按下 shift 鍵,fabricjs 的當前行為也會創建一個新的選擇。 此外,單擊 canvas 上的空白區域時,不應清除選擇。 只有在單擊作為選擇的一部分的單個 object 時才能取消選擇對象(當拖動選定對象時應保持選中狀態)。 或者通過單擊一個附加按鈕來清除完整的選擇(需要額外的用戶確認)。

我使用“selection:created”和“selection:updated”嘗試了不同的設置,但這要么弄亂了選擇,要么導致了無限循環,因為在更新中修改選擇也會再次觸發更新。

canvas.on("selection:updated", (event) => {
  event.selected.forEach((fabImg) => {
        if (!this.selectedImages.includes(fabImg)) {
          this.selectedImages.push(fabImg);
        }
  });
    var groupSelection = new fabric.ActiveSelection(this.selectedImages);
    canvas.setActiveObject(groupSelection);
});

單擊空白 canvas 時防止清除通過以下方式解決:

var selection = [];
canvas.on("before:selection:cleared", (selected) => {
  selection = this.canvas.getActiveObjects();
});
canvas.on("selection:cleared", (event) => {
  var groupSelection = new fabric.ActiveSelection(selection);
  canvas.setActiveObject(groupSelection);
});

以防萬一其他人感興趣,我最終更改了 fabricjs 代碼中的 3 個函數以實現所需的行為:

canvas.class.js:

_shouldClearSelection: function (e, target) {
    var activeObjects = this.getActiveObjects(),
      activeObject = this._activeObject;

    return (
      (target &&
        activeObject &&
        activeObjects.length > 1 &&
        activeObjects.indexOf(target) === -1 &&
        activeObject !== target &&
        !this._isSelectionKeyPressed(e)) ||
      (target && !target.evented) ||
      (target &&
        !target.selectable &&
        activeObject &&
        activeObject !== target)
    );
  }

剛剛刪除了檢查是否單擊了 object,以在單擊空白處時停止取消選擇。

_isSelectionKeyPressed: function (e) {
    var selectionKeyPressed = false;

    if (this.selectionKey == "always") {
      return true;
    }

    if (
      Object.prototype.toString.call(this.selectionKey) === "[object Array]"
    ) {
      selectionKeyPressed = !!this.selectionKey.find(function (key) {
        return e[key] === true;
      });
    } else {
      selectionKeyPressed = e[this.selectionKey];
    }

    return selectionKeyPressed;
  }

只需添加一個名為“always”的“虛擬”鍵來假裝總是按住 shift 鍵。 在 canvas 定義中添加這個鍵:

this.canvas = new fabric.Canvas("c", {
  hoverCursor: "hand",
  selection: true,
  backgroundColor: "#F0F8FF",
  selectionBorderColor: "blue",
  defaultCursor: "hand",
  selectionKey: "always",
});

在 canvas_grouping.mixin.js 中:

_groupSelectedObjects: function (e) {
    var group = this._collectObjects(e),
      aGroup;

    var previousSelection = this._activeObject;
    if (previousSelection) {
      if (previousSelection.type === "activeSelection") {
        var currentActiveObjects = previousSelection._objects.slice(0);
        group.forEach((obj) => {
          if (!previousSelection.contains(obj)) {
            previousSelection.addWithUpdate(obj);
          }
        });
        this._fireSelectionEvents(currentActiveObjects, e);
      } else {
        aGroup = new fabric.ActiveSelection(group.reverse(), {
          canvas: this,
        });
        this.setActiveObject(aGroup, e);
        var objects = this._activeObject._objects.slice(0);
        this._activeObject.addWithUpdate(previousSelection);
        this._fireSelectionEvents(objects, e);
      }
    } else {
      // do not create group for 1 element only
      if (group.length === 1 && !previousSelection) {
        this.setActiveObject(group[0], e);
      } else if (group.length > 1) {
        aGroup = new fabric.ActiveSelection(group.reverse(), {
          canvas: this,
        });
        this.setActiveObject(aGroup, e);
      }
    }
  }

這將在拖動選擇時擴展現有組,而不是覆蓋現有選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM