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 funkcjionDragEnter
w nowym obiekcie do przeciągania. - Funkcja
onDragOver
powinna być wywoływana poonDragEnter
pierwszym najechaniu kursorem na element do przeciągania oraz po każdym kolejnym wywołaniu funkcjionDrag
, 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,
},
});