Przeciąganie

Element dragger to obiekt kontrolera, który koordynuje przeciąganie elementów do przeciągania w odpowiedzi na interakcje użytkownika.

W niewielu przypadkach warto stosować niestandardowy element przeciągania, ponieważ nie ma zbyt wiele elementów, które można dostosować w ramach koordynacji przeciągania. Wtyczka przewijana implementuje niestandardowy element przeciągania, ponieważ chciał dodać przewijanie na krawędzi obszaru roboczego, co zmienia sposób konwersji współrzędnych pikseli na współrzędne obszaru roboczego.

Podmiot odpowiedzialny

Osoba wykonująca przeciąganie ma kilka obowiązków:

  • Wywoływanie metod przeciągania elementu.
  • Obliczanie pozycji, do której należy przesunąć element przeciągalny w układzie współrzędnych obszaru roboczego.
  • wywoływanie metod docelowego elementu do przeciągania w przypadku dowolnego podświetlonego docelowego elementu do przeciągania.

Implementacja

Aby utworzyć niestandardowy element przeciągania, musisz zaimplementować interfejs IDragger.

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

Możesz też utworzyć podklasę wbudowanej klasy Blockly.dragging.Dragger, która już spełnia podstawowe obowiązki.

Rozpocznij przeciąganie

Metoda onDragStart inicjuje przeciąganie. Powinien on przechowywać wszystkie dane potrzebne do wykonania przeciągania. Powinien też wywoływać metodę startDrag obiektu draggable, który jest przeciągany.

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

  this.draggable.startDrag(e);
}

Opór

Metoda onDrag wykonuje przeciąganie. Nowa pozycja obszaru roboczego, którą można przeciągać, powinna być obliczana na podstawie parametru totalDelta, który jest podawany we współrzędnych pikselowych.

Powinien też zaktualizować wszystkie obiekty przeciągania, nad którymi znajduje się kursor.

  • Funkcję wouldDelete należy zawsze wywoływać przed wywołaniem innych punktów zaczepienia na elemencie przeciągania.
  • Funkcja onDragExit powinna być zawsze wywoływana w starym obiekcie do przeciągania przed wywołaniem funkcji onDragEnter w nowym obiekcie do przeciągania.
  • Funkcja onDragOver powinna być wywoływana po onDragEnter pierwszym najechaniu kursorem na element do przeciągania oraz po każdym kolejnym wywołaniu funkcji onDrag, gdy element do przeciągania jest nadal najeżdżany kursorem.
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;
}

Końcowe przeciągnięcia

Metoda onEndDrag kończy przeciąganie. Powinien on powiadomić obiekt, że przeciąganie zostało zakończone, a wszystkie obiekty, nad którymi znajduje się przeciągany obiekt, że został on upuszczony. Jeśli docelowy element jest obszarem do usuwania, należy też usunąć element przeciągany.

  • Metoda onDrop powinna być zawsze wywoływana przed innymi metodami.
  • Jeśli element do przeciągania uniemożliwia przeciąganie, należy wywołać funkcję revertDrag.
  • Funkcja endDrag powinna być wywoływana po cofnięciu przeciągania, ale przed usunięciem.
  • Jeśli docelowy element przeciągania jest obszarem usuwania, należy wywołać funkcję dispose.
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();
  }
}

Rejestracja

Klasa obiektu przeciągania musi zostać zarejestrowana, aby można ją było utworzyć po wykryciu przeciągania.

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

Wykorzystanie

Po zaimplementowaniu niestandardowego obiektu Dragger możesz go używać, przekazując go do struktury konfiguracji wstrzyknięcia.

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