可拖曳項目是指工作區中顯示的物件,可以拖曳及放置。這些類別會實作 IDraggable
介面。
您幾乎不會想在 Blockly 中新增可拖曳項目 (例如 multiselect 外掛程式,或變更現有物件處理拖曳的方式),因為您無法在 Blockly 中新增已算繪的物件。工作區中只能有方塊、泡泡和工作區註解。
職責
執行拖曳作業時,可拖曳項目有幾項責任:
導入作業
如要建立新的可拖曳項目,您必須實作 IRenderedElement
和 IDraggable
介面。這會讓 Blockly 知道物件可見且可拖曳。
class MyDraggable extends IRenderedElement, IDraggable {}
傳回根 SVG 元素
getRootSvg
方法會傳回根層級 SVG 元素 (通常是「群組」),其中包含構成可拖曳檢視區塊的所有其他元素。
getSvgRoot() {
return this.rootSvg;
}
可退回的移動裝置
isMovable
方法會傳回可拖曳項目目前是否可移動 (因為您可能想暫時停用物件的拖曳功能)。如果 isMovable
傳回 false
,則會改為拖曳工作區。
isMovable() {
return true;
}
退貨位置
getRelativeToSurfaceXY
方法會傳回 Coordinate
,指定工作區座標中可拖曳項目的左上角位置。
工作區座標的原點位於工作區的絕對左側和絕對頂端。而且不會隨著工作區縮放或移動而改變。
getRelativeToSurfaceXY() {
return this.loc;
}
開始拖曳
startDrag
方法會初始化可拖曳項目的拖曳作業。這個方法不會移動可拖曳項目。但您應儲存完成拖曳作業所需的任何資料或建構任何物件。包括在呼叫 revertDrag
時,還原拖曳作業所需的任何資料。
此外,SVG 元素也應變更為工作區的拖曳圖層,因此會顯示在任何其他元素上方。
此外,這個函式也會接收事件,您可以用來檢查按下的按鍵。舉例來說,這樣您就能以不同方式處理拖曳作業 (例如在拖曳時按下 Shift 鍵)。
startDrag(e) {
// Save the original location so we can revert the drag.
this.startLoc = this.getRelativeToSurfaceXY();
// Disable resizing the workspace for performance.
this.workspace.setResizesEnabled(false);
// Put the element on the drag layer.
this.workspace.getLayerManager()?.moveToDragLayer(this);
// Fire a drag event...
// etc...
}
拖曳
drag
方法實際上會移動可拖曳的物件。newLoc
位於工作區座標中,且也會傳遞事件,您可以使用該事件檢查按下的按鍵。
drag(newLoc, e) {
this.moveTo(newLoc);
}
還原拖曳
revertDrag
方法會將可拖曳項目傳回拖曳開始時的位置。舉例來說,如果可拖曳項目放置在禁止移動的拖曳目標上,就會發生這種情況。
revertDrag() {
// Move back to the position that was stored in `startDrag`.
this.moveTo(this.startLoc);
}
結束拖曳
endDrag
方法會清除拖曳作業,釋放所有儲存的資料或物件,並將可拖曳項目傳回原始圖層。
如果呼叫 revertDrag
,系統一律會在 revertDrag
後呼叫 endDrag
。
endDrag() {
// Put the element back on its original layer (in this case BLOCK).
this.workspace
.getLayerManager()
?.moveOffDragLayer(this, Blockly.layers.BLOCK);
// Allow the workspace to start resizing again.
this.workspace.setResizesEnabled(true);
}
選取
系統偵測到拖曳動作時,會根據選取的元素決定要拖曳的元素。
ISelectable
如要選取可拖曳的項目,該項目必須實作 ISelectable
介面。
class MyDraggable implements ISelectable {
constructor(workspace) {
this.id = Blockly.utils.idGenerator.genUid();
this.workspace = workspace;
}
select() {
// Visually indicate this draggable is selected.
}
unselect() {
// Visually indicate this draggable is not selected.
}
}
設定選取範圍
呼叫 Blockly.common.setSelected()
即可設定所選元素。通常您會想在收到使用者的 pointerdown
事件時執行這項操作。
constructor() {
this.initSvg();
Blockly.browserEvents.conditionalBind(
this.getSvgRoot(),
'pointerdown',
this,
() => Blockly.common.setSelected(this));
}
相容性
可拖曳項目可以實作其他介面,以便與 Blockly 中的其他系統互動。
可刪除
您可以實作 IDeleteable
介面,讓垃圾桶或其他刪除目標處置可拖曳項目。
class MyDraggable implements IDeletable {
isDeletable() {
return true;
}
dispose() {
// Dispose of any references to data or SVG elements.
}
setDeleteStyle() {
// Visually indicate that the draggable is about to be deleted.
}
}
可複製
您可以實作 ICopyable
介面來複製可拖曳項目,並定義 IPaster
來貼上項目。
如要進一步瞭解如何複製及貼上,請參閱「複製及貼上」一文。