[英]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.