Benutzerdefinierte Ziehpunkte

Ein Dragger ist ein Controllerobjekt, das das Ziehen von Dragable-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 Element aufrufen, das verschoben werden kann
  • Berechnen der Position, an die das anklickbare Element in Arbeitsbereichskoordinaten verschoben werden soll.
  • Methoden für Zielobjekte für das Ziehen auf alle Zielobjekte für das Ziehen aufrufen, die sich im Hover befinden.

Implementierung

Wenn Sie einen benutzerdefinierten Dragger erstellen möchten, müssen Sie die IDragger-Schnittstelle 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 Ziehen initialisiert. Es sollten alle Daten gespeichert werden, die zum Ausführen des Ziehens 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 anklickbare Element sollte anhand der totalDelta berechnet werden, die in Pixelkoordinaten angegeben ist.

Außerdem sollten alle Ziehziele aktualisiert werden, die sich im Hovering-Zustand befinden.

  • wouldDelete sollte immer vor dem Aufrufen anderer Hooks für das Ziel des Ziehens 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 der Mauszeiger zum ersten Mal auf das Ziehziel bewegt wird, und bei jedem weiteren Aufruf von onDrag, wenn der Mauszeiger sich noch auf dem Ziehziel befindet.
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. Es sollte das Element informieren, dass das Ziehen beendet wurde, und alle Elemente, die sich im Hovering-Zustand befinden, dass das Element 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 Rückgängigmachen des Ziehens, 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 Konfigurationsoptionen ü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,
  },
});