可拖曳

可拖曳是工作區中的已轉譯物件,可拖曳及捨棄。可實作 IDraggable 介面。

在極少數的情況下,您可能會想要新增可封鎖的新可拖曳項目 (例如多選取外掛程式,或是變更現有物件處理拖曳的方式),因為您無法在 Blockly 中新增算繪物件。工作區內唯一能存在的算繪物件是區塊、對話框和工作區註解。

職責

執行拖曳時,拖曳項目會有一些責任:

導入作業

如要建立新的可拖曳項目,您必須實作 IRenderedElementIDraggable 介面。這會讓 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 元素變更為工作區的拖曳層,因此這些元素會位於任何其他元素上方。

它也會擷取已按下按鍵的事件。這可讓您 (例如) 來處理拖曳動作,但移動與一般拖曳不同。

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 以允許貼上。

如要進一步瞭解如何複製貼上,請參閱「複製貼上」。