Trascinabili personalizzati

Un elemento trascinabile è un oggetto sottoposto a rendering che esiste nell'area di lavoro e può essere trascinato e rilasciato. Implementano l'interfaccia IDraggable.

Esistono pochissime circostanze in cui è consigliabile aggiungere un nuovo elemento trascinabile a Blockly (ad es. il plug-in di selezione multipla o la modifica del modo in cui un oggetto esistente gestisce i trascinamenti), perché non puoi aggiungere nuovi oggetti sottoposti a rendering a Blockly. Gli unici oggetti sottoposti a rendering che possono esistere all'interno di un workspace sono blocchi, bolle e commenti del workspace.

Responsabilità

Gli elementi trascinabili hanno diverse responsabilità durante l'esecuzione dei trascinamenti:

Implementazione

Per creare un nuovo elemento trascinabile, devi implementare le interfacce IRenderedElement e IDraggable. In questo modo, Blockly sa che l'oggetto è visibile e può essere trascinato.

class MyDraggable extends IRenderedElement, IDraggable {}

Restituisce l'elemento SVG principale

Il metodo getRootSvg restituisce l'elemento SVG radice (in genere un gruppo) che contiene tutti gli altri elementi che compongono la visualizzazione per l'elemento trascinabile.

getSvgRoot() {
  return this.rootSvg;
}

Return movability

Il metodo isMovable restituisce un valore che indica se l'elemento trascinabile è attualmente spostabile (poiché potresti voler disattivare temporaneamente il trascinamento di un oggetto). Se isMovable restituisce false, viene trascinato lo spazio di lavoro.

isMovable() {
  return true;
}

Posizione di ritorno

Il metodo getRelativeToSurfaceXY restituisce un Coordinate che specifica la posizione dell'angolo superiore iniziale del componente trascinabile nelle coordinate dello spazio di lavoro.

Le coordinate dello spazio di lavoro hanno un'origine nella parte superiore e sinistra assolute dello spazio di lavoro. Inoltre, non cambiano quando lo spazio di lavoro viene scalato o spostato.

getRelativeToSurfaceXY() {
  return this.loc;
}

Inizia le gare di accelerazione

Il metodo startDrag inizializza un trascinamento sull'elemento trascinabile. Questo metodo non sposta l'elemento trascinabile. ma devi archiviare tutti i dati o costruire tutti gli oggetti che ti servono per completare il trascinamento. Sono inclusi tutti i dati necessari per annullare il trascinamento se viene chiamato revertDrag.

Inoltre, deve spostare gli elementi SVG nel livello di trascinamento dell'area di lavoro, in modo che si trovino sopra qualsiasi altro elemento.

Prende anche un evento, che puoi utilizzare per verificare i tasti premuti. In questo modo, ad esempio, puoi trattare un trascinamento durante lo spostamento in modo diverso da un trascinamento normale.

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...
}

Trascina

Il metodo drag sposta effettivamente l'oggetto trascinabile. newLoc si trova nelle coordinate dello spazio di lavoro ed è stato passato anche un evento che puoi utilizzare per controllare i tasti premuti.

drag(newLoc, e) {
  this.moveTo(newLoc);
}

Annulla i trascinamenti

Il metodo revertDrag riporta l'elemento trascinabile nella posizione in cui si trovava all'inizio del trascinamento. Ciò si verifica se, ad esempio, l'elemento trascinabile viene rilasciato su un target di trascinamento che impedisce il movimento.

revertDrag() {
  // Move back to the position that was stored in `startDrag`.
  this.moveTo(this.startLoc);
}

Termina trascinamenti

Il metodo endDrag pulisce un trascinamento, rilasciando eventuali dati o oggetti archiviati e riportando l'elemento trascinabile al suo livello originale.

endDrag viene sempre chiamato dopo revertDrag se revertDrag viene chiamato.

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);
}

Selezione

L'elemento trascinato è determinato dall'elemento selezionato quando viene rilevato un trascinamento.

ISelectable

Per essere selezionato, un elemento trascinabile deve implementare l'interfaccia 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.
  }
}

Imposta selezione

L'elemento selezionato può essere impostato chiamando Blockly.common.setSelected(). In genere, questa operazione viene eseguita in risposta a un evento pointerdown dell'utente.

  constructor() {
    this.initSvg();

    Blockly.browserEvents.conditionalBind(
      this.getSvgRoot(),
      'pointerdown',
      this,
      () => Blockly.common.setSelected(this));
  }

Compatibilità

L'elemento trascinabile può implementare interfacce aggiuntive in modo da poter interagire con altri sistemi in Blockly.

Eliminabile

Puoi implementare l'interfaccia IDeleteable per consentire l'eliminazione dell'elemento trascinabile tramite il cestino o altre destinazioni di eliminazione.

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.
  }
}

Copiabile

Puoi implementare l'interfaccia ICopyable per consentire la copia dell'elemento trascinabile e definire un IPaster per consentirne l'incollatura.

Per ulteriori informazioni su come copiare e incollare, vedi Copia e incolla.