Dragger

Ein Dragger ist ein Controllerobjekt, das das Ziehen von Zum-Ziehen-Objekten in Reaktion auf Nutzerinteraktionen koordiniert.

Es gibt nur sehr wenige Fälle, in denen Sie einen benutzerdefinierten Dragger implementieren möchten, da es nicht viel gibt, was Sie an der Koordinierung eines Drag-Vorgangs anpassen möchten. Das Plug-in „scroll-options“ implementiert einen benutzerdefinierten Ziehpunkt, da am Rand des Arbeitsbereichs gescrollt werden soll. Dadurch ändert sich die Art und Weise, wie Pixelkoordinaten in Arbeitsbereichskoordinaten umgewandelt werden.

Zuständigkeiten

Der Nutzer, der die Drag-and-drop-Aktion ausführt, hat mehrere Aufgaben:

  • Drag-Methoden für das ziehbare Element aufrufen
  • Berechnen der Position, zu der sich das anklickbare Element in Arbeitsbereichskoordinaten bewegen soll.
  • Methoden für Zielobjekte für das Ziehen auf alle Zielobjekte für das Ziehen aufrufen, die sich im Hover befinden.

Implementierung

Zum Erstellen eines benutzerdefinierten Draggers müssen Sie die Schnittstelle IDragger implementieren.

class MyDragger implements IDragger {
  // Takes in the draggable being dragged and the workspace the drag
  // is occurring in.
  constructor(draggable, workspace);
}

Sie können auch die vordefinierte Blockly.dragging.Dragger als Unterklasse verwenden, die bereits die grundlegenden Aufgaben übernimmt.

Ziehen starten

Mit der Methode onDragStart wird ein Drag-Vorgang initialisiert. Er sollte alle Daten speichern, die zum Ausführen des Drag-Vorgangs erforderlich sind. Außerdem sollte startDrag für das Element aufgerufen werden, das verschoben wird.

onDragStart(e) {
  this.startLoc = this.draggable.getRelativeToSurfaceXY();

  this.draggable.startDrag(e);
}

Strömungswiderstand

Die Methode onDrag führt ein Ziehen aus. Die neue Workspace-Position für das Element, das verschoben werden kann, sollte anhand der totalDelta berechnet werden, die in Pixelkoordinaten angegeben ist.

Außerdem sollten alle Drag-Ziele aktualisiert werden, über die der Mauszeiger bewegt wird.

  • wouldDelete sollte immer vor anderen Hooks für das Ziehziel aufgerufen werden.
  • onDragExit muss immer für das alte Ziehziel aufgerufen werden, bevor onDragEnter für das neue Ziehziel aufgerufen wird.
  • onDragOver sollte nach onDragEnter aufgerufen werden, wenn das Ziehziel zum ersten Mal auf das Ziehziel bewegt wird, und bei jedem weiteren Aufruf von onDrag, bei dem das Ziehziel noch immer über dem Ziehziel bewegt wurde.
onDrag(e, totalDelta) {
  // Update the draggable location.
  const delta = this.pixelsToWorkspaceUnits(totalDelta);
  const newLoc = Coordinate.sum(this.startLoc, delta);
  this.draggable.drag(newLoc, e);

  // Call wouldDeleteDraggable.
  if (isDeletable(this.draggable)) {
    this.draggable.setDeleteStyle(
      // Checks that the drag target is an `IDeleteArea` and calls `wouldDelete`
      // on it.
      this.wouldDeleteDraggable(e, this.draggable),
    );
  }

  const newDragTarget = this.workspace.getDragTarget(e);
  if (this.dragTarget !== newDragTarget) {
    // Call `onDragExit` then `onDragEnter`.
    this.dragTarget?.onDragExit(this.draggable);
    newDragTarget?.onDragEnter(this.draggable);
  }
  // Always call `onDragOver`
  newDragTarget?.onDragOver(this.draggable);
  this.dragTarget = newDragTarget;
}

Ziehen beenden

Mit der Methode onEndDrag wird ein Ziehen beendet. Das ziehbare Element sollte darüber informiert werden, dass der Ziehpunkt beendet wurde und dass das Ziehziel, das sich in der Position befindet, abgelegt wurde. Außerdem sollte das Element gelöscht werden, wenn das Ziel des Ziehens ein Löschbereich ist.

  • onDrop muss immer vor anderen Methoden aufgerufen werden.
  • revertDrag sollte aufgerufen werden, wenn das Ziehziel das Ziehen verhindert.
  • endDrag sollte nach dem Zurücksetzen des Ziehvorgangs, aber vor dem Entfernen aufgerufen werden.
  • dispose sollte aufgerufen werden, wenn das Ziel des Ziehens ein Löschbereich ist.
onDragEnd(e) {
  // Call `onDrop` first.
  const dragTarget = this.workspace.getDragTarget(e);
  if (dragTarget) {
    this.dragTarget?.onDrop(this.draggable);
  }

  // Then revert the drag (if applicable).
  if (this.shouldReturnToStart(e, this.draggable)) {
    this.draggable.revertDrag();
  }

  // Then end the drag.
  this.draggable.endDrag(e);

  // Then delete the draggable (if applicable).
  if (
    isDeletable(this.draggable) &&
    this.wouldDeleteDraggable(e, this.draggable)
  ) {
    this.draggable.dispose();
  }
}

Anmeldung

Ihre Dragger-Klasse muss registriert sein, damit sie erstellt werden kann, wenn Ziehen erkannt wird.

// Note that the type is BLOCK_DRAGGER even though draggers drag more than
// blocks. The name is for backwards compatibility.
Blockly.registry.register(registry.Type.BLOCK_DRAGGER, 'MY_DRAGGER', MyDragger);

Nutzung

Nachdem Sie Ihren benutzerdefinierten Dragger implementiert haben, können Sie ihn verwenden, indem Sie ihn an Ihre Injektionskonfigurationsstruktur übergeben.

const myWorkspace = Blockly.inject('blocklyDiv', {
  plugins: {
    // Note that we pass this to blockDragger even though draggers drag more
    // than blocks. The name is for backwards compatibility.
    blockDragger: MyDragger,
  },
});