Do przeciągania

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:

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.