Element możliwy do przeciągania to wyrenderowany obiekt znajdujący się w obszarze roboczym, który można przeciągać i upuszczać. Implementują interfejs IDraggable
.
W niewielu przypadkach możesz chcieć dodać do Blockly nowy element z możliwością przeciągania (np. wtyczkę multiselect lub zmianę sposobu obsługi przeciągania istniejącego obiektu), ponieważ do Blockly nie można dodawać nowych renderowanych obiektów. Jedyne wyrenderowane obiekty, które mogą istnieć w obszarze roboczym, to bloki, dymki i komentarze do obszaru roboczego.
Podmiot odpowiedzialny
Podczas przeciągania obiektów do przeciągania jest przypisana kilka kwestii:
- Przenoszenie elementów SVG do warstwy przeciągania.
- Tłumaczę elementy SVG.
- Uruchamiam zdarzenia ruchu.
Implementacja
Aby utworzyć nowy element przeciągalny, musisz zaimplementować interfejsy IRenderedElement
i IDraggable
. Poinformuje to Blockly, że obiekt jest widoczny i można go przeciągnąć.
class MyDraggable extends IRenderedElement, IDraggable {}
Zwraca główny element SVG
Metoda getRootSvg
zwraca główny element svg (zwykle grupę), w którym znajdują się wszystkie pozostałe elementy tworzące widok elementu dającego się przeciągnąć.
getSvgRoot() {
return this.rootSvg;
}
Możliwość przesuwania zwrotu
Metoda isMovable
zwraca, czy przeciąganie obiektu można obecnie przenosić (ponieważ możesz 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 element Coordinate
określający lokalizację górnego rogu początkowego elementu przeciąganego we współrzędnych obszaru roboczego.
Współrzędne obszaru roboczego mają początek w lewej części i na samej górze. Nie zmieniają się one przy skalowaniu lub przenoszeniu obszaru roboczego.
getRelativeToSurfaceXY() {
return this.loc;
}
Rozpocznij przeciąganie
Metoda startDrag
inicjuje przeciąganie elementu. Ta metoda nie przesuwa elementu przeciąganego. Przechowuj jednak dane i twórz obiekty potrzebne do ukończenia przeciągania. Dotyczy to wszystkich danych, które trzeba cofnąć przeciąganie, jeśli wywołana jest funkcja revertDrag
.
Elementy SVG powinny też znajdować się w warstwie przeciągania obszaru roboczego. Dzięki temu powinny znajdować się nad innymi elementami.
Rejestrowane jest też zdarzenie, za pomocą którego możesz sprawdzić, czy wciśnięty został naciśnięty klawisz. Dzięki temu możesz na przykład traktować przeciąganie w inny sposób niż przy normalnym przeciągnięciu.
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...
}
Opór
Metoda drag
faktycznie przenosi obiekt, który można przeciągnąć. Obiekt newLoc
znajduje się we współrzędnych obszaru roboczego, a także przekazane jest zdarzenie, które umożliwia sprawdzenie, czy w danym miejscu są naciśnięte klawisze.
drag(newLoc, e) {
this.moveTo(newLoc);
}
Cofnij przeciągnięcia
Metoda revertDrag
zwraca element, który można przeciągnąć, do pozycji, w której znajdował się na początku przeciągania. Może się tak zdarzyć, jeśli np. element, który można przeciągać, zostanie upuszczony na przeciągany cel, 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 zapisane dane lub obiekty i przywraca element przeciągany do pierwotnej warstwy.
Funkcja endDrag
jest zawsze wywoływana po revertDrag
, jeśli wywoływana jest metoda revertDrag
.
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
Przeciągany element zależy od tego, który został wybrany po wykryciu przeciągnięcia.
ISelectable
Aby można było wybrać element, który można przeciągać, musi on zaimplementować 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.
}
}
Wybierz ustawienia
Wybrany element można ustawić, wywołując metodę Blockly.common.setSelected()
. jest to zwykle działanie w odpowiedzi na zdarzenie pointerdown
użytkownika.
constructor() {
this.initSvg();
Blockly.browserEvents.conditionalBind(
this.getSvgRoot(),
'pointerdown',
this,
() => Blockly.common.setSelected(this));
}
Zgodność
Element do przeciągania może zaimplementować dodatkowe interfejsy, dzięki czemu będzie mógł wchodzić w interakcje z innymi systemami w Blockly.
Możliwe do usunięcia
Możesz zaimplementować interfejs IDeleteable
, aby umożliwić przeniesienie elementudra do kosza lub wyrzucenie go do kosza.
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
, by umożliwić kopiowanie elementu przeciągającego, oraz zdefiniować element IPaster
, który umożliwi jego wklejenie.
Więcej informacji o kopiowaniu wklejanych znajdziesz w artykule Kopiowanie i wklejanie.