Element przeciągania to obiekt kontrolera, który koordynuje przeciąganie elementów do przeciągania w odpowiedzi na interakcje użytkownika.
Wdrożenie niestandardowego selektora jest potrzebne w bardzo niewielu przypadkach, ponieważ nie ma zbyt wielu elementów, które można dostosować w ramach koordynacji przeciągania. Wtyczka opcji przewijania implementuje niestandardowy element przeciągania, ponieważ autor chciał dodać przewijanie na krawędzi obszaru roboczego, co zmienia sposób konwertowania 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 na elementach do przeciągania.
- 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);
}
Przeciągnięcie
Metoda onDrag wykonuje przeciąganie. Powinien on obliczyć nową pozycję obszaru roboczego dla elementu przeciąganego na podstawie wartości totalDelta podanej w pikselach.
Powinien też zaktualizować wszystkie obiekty przeciągania, nad którymi znajduje się kursor.
- Funkcja
wouldDeletepowinna być zawsze wywoływana przed wywołaniem innych funkcji obsługiwanych przez obiekt docelowy przeciągania. - Funkcja
onDragExitpowinna być zawsze wywoływana w starym docelowym obiekcie przeciągania przed wywołaniem funkcjionDragEnterw nowym docelowym obiekcie przeciągania. - Funkcja
onDragOverpowinna być wywoływana poonDragEnterpierwszym najechaniu kursorem na element do przeciągania oraz po każdym kolejnym wywołaniu funkcjionDrag, gdy element do przeciągania jest nadal podświetlony.
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;
}
Zakończ przeciąganie
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 również usunąć element przeciągany.
onDroppowinna być zawsze wywoływana przed innymi metodami.- Jeśli element do przeciągania uniemożliwia przeciąganie, należy wywołać funkcję
revertDrag. - Funkcja
endDragpowinna być wywoływana po odwróceniu przeciągania, ale przed usunięciem. - Funkcja
disposepowinna być wywoływana, jeśli docelowy element przeciągania jest obszarem usuwania.
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 elementu przeciągania możesz go używać, przekazując go do opcji konfiguracji.
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,
},
});