Element do przeciągania to renderowany obiekt, który znajduje się w obszarze roboczym i można go przeciągać i upuścić. Implementują one interfejs IDraggable
.
W Blockly rzadko kiedy dodaje się nowe elementy, które można przeciągać (np. w wtyczce do wielokrotnego wyboru lub w przypadku zmiany sposobu obsługi przeciągania przez istniejący obiekt), ponieważ nie można dodawać do Blockly nowych renderowanych obiektów. Jedynymi renderowanymi obiektami, które mogą znajdować się w obszarze roboczym, są bloki, dymki i komentarze do obszaru roboczego.
Podmiot odpowiedzialny
Elementy, które można przeciągać, mają kilka obowiązków podczas przeciągania:
- Przenoszenie elementów SVG do warstwy przeciągania.
- Tłumaczenie elementów SVG.
- Wywoływanie zdarzeń ruchu.
Implementacja
Aby utworzyć nowy element, który można przeciągać, musisz zaimplementować interfejsy IRenderedElement
i IDraggable
. Dzięki temu Blockly wie, że obiekt jest widoczny i można go przeciągać.
class MyDraggable extends IRenderedElement, IDraggable {}
Zwracanie głównego elementu SVG
Metoda getRootSvg
zwraca główny element SVG (zwykle grupę), który zawiera wszystkie pozostałe elementy tworzące widok elementu, który można przeciągać.
getSvgRoot() {
return this.rootSvg;
}
Return movability
Metoda isMovable
zwraca informację, czy element, który można przeciągać, jest obecnie przesuwalny (możesz chcieć tymczasowo wyłączyć przeciąganie obiektu). Jeśli isMovable
zwróci wartość false
, obszar roboczy zostanie przeciągnięty.
isMovable() {
return true;
}
Pozycja zwrotu
Metoda getRelativeToSurfaceXY
zwraca wartość Coordinate
określającą położenie górnego lewego rogu elementu, który można przeciągać, we współrzędnych obszaru roboczego.
Współrzędne obszaru roboczego mają punkt początkowy w lewym górnym rogu obszaru roboczego. Nie zmieniają się one, gdy obszar roboczy jest skalowany lub przenoszony.
getRelativeToSurfaceXY() {
return this.loc;
}
Rozpocznij przeciąganie
Metoda startDrag
inicjuje przeciąganie elementu, który można przeciągać. Ta metoda nie przesuwa elementu, który można przeciągać. Musisz jednak przechowywać wszystkie dane lub tworzyć wszystkie obiekty, które są potrzebne do zakończenia przeciągania. Obejmuje to wszystkie dane, które będą potrzebne do przywrócenia stanu sprzed przeciągnięcia, jeśli zostanie wywołana funkcja revertDrag
.
Powinien też przenieść elementy SVG do warstwy przeciągania obszaru roboczego, aby znajdowały się nad innymi elementami.
Przyjmuje też zdarzenie, którego możesz użyć do sprawdzenia, czy klawisze zostały naciśnięte. Dzięki temu możesz na przykład traktować przeciąganie z naciśniętym klawiszem Shift inaczej niż zwykłe przeciąganie.
startDrag(e) {
// Save the original location so we can revert the drag.
this.startLoc = this.getRelativeToSurfaceXY();
// Disable resizing the workspace for performance.
this.workspace.setResizesEnabled(false);
// Put the element on the drag layer.
this.workspace.getLayerManager()?.moveToDragLayer(this);
// Fire a drag event...
// etc...
}
Przeciągnięcie
Metoda drag
przenosi obiekt, który można przeciągać. Współrzędne newLoc
są podane we współrzędnych obszaru roboczego. Przekazywane jest też zdarzenie, za pomocą którego możesz sprawdzić, czy klawisze zostały naciśnięte.
drag(newLoc, e) {
this.moveTo(newLoc);
}
Cofanie przeciągania
Metoda revertDrag
przywraca element, który można przeciągać, do pozycji, w której znajdował się na początku przeciągania. Dzieje się tak na przykład, gdy element, który można przeciągać, zostanie upuszczony na obszar docelowy przeciągania, który uniemożliwia ruch.
revertDrag() {
// Move back to the position that was stored in `startDrag`.
this.moveTo(this.startLoc);
}
Zakończ przeciąganie
Metoda endDrag
czyści przeciąganie, zwalniając wszystkie zapisane dane lub obiekty i przywracając element do przeciągania do pierwotnej warstwy.
endDrag
jest zawsze wywoływana po revertDrag
, jeśli revertDrag
jest wywoływana.
endDrag() {
// Put the element back on its original layer (in this case BLOCK).
this.workspace
.getLayerManager()
?.moveOffDragLayer(this, Blockly.layers.BLOCK);
// Allow the workspace to start resizing again.
this.workspace.setResizesEnabled(true);
}
Zaznaczenie
Element, który jest przeciągany, jest określany przez element wybrany po wykryciu przeciągnięcia.
ISelectable
Aby można było wybrać element, który można przeciągać, musi on implementować interfejs ISelectable
.
class MyDraggable implements ISelectable {
constructor(workspace) {
this.id = Blockly.utils.idGenerator.genUid();
this.workspace = workspace;
}
select() {
// Visually indicate this draggable is selected.
}
unselect() {
// Visually indicate this draggable is not selected.
}
}
Ustawianie wyboru
Wybrany element można ustawić, wywołując
Blockly.common.setSelected()
. Zwykle warto to zrobić w odpowiedzi na pointerdown
zdarzenie od użytkownika.
constructor() {
this.initSvg();
Blockly.browserEvents.conditionalBind(
this.getSvgRoot(),
'pointerdown',
this,
() => Blockly.common.setSelected(this));
}
Zgodność
Element przeciągany może implementować dodatkowe interfejsy, aby mógł wchodzić w interakcje z innymi systemami w Blockly.
Możliwe do usunięcia
Możesz zaimplementować interfejs IDeleteable
, aby umożliwić usuwanie elementów, które można przeciągać, do kosza lub innych miejsc docelowych usuwania.
class MyDraggable implements IDeletable {
isDeletable() {
return true;
}
dispose() {
// Dispose of any references to data or SVG elements.
}
setDeleteStyle() {
// Visually indicate that the draggable is about to be deleted.
}
}
Można skopiować
Możesz zaimplementować interfejs ICopyable
, aby umożliwić kopiowanie elementu, który można przeciągać, i zdefiniować interfejs IPaster
, aby umożliwić jego wklejanie.
Więcej informacji o kopiowaniu i wklejaniu znajdziesz w artykule Kopiowanie i wklejanie.