Пользовательские перетаскиваемые объекты

Перетаскиваемый объект — это визуализированный объект, существующий в рабочей области и доступный для перетаскивания. Он реализует интерфейс IDraggable .

Добавление нового перетаскиваемого объекта в Blockly может потребоваться лишь в редких случаях (например, при использовании плагина множественного выбора или для изменения способа обработки перетаскивания существующим объектом), поскольку в Blockly нельзя добавлять новые отрисованные объекты. В рабочей области могут существовать только отрисованные объекты — блоки, пузыри и комментарии.

Обязанности

При выполнении перетаскивания перетаскиваемые объекты выполняют несколько функций:

Выполнение

Чтобы создать новый перетаскиваемый объект, необходимо реализовать интерфейсы IRenderedElement и IDraggable . Это сообщит Blockly, что ваш объект видим и его можно перетаскивать.

class MyDraggable extends IRenderedElement, IDraggable {}

Вернуть корневой элемент SVG

Метод getRootSvg возвращает корневой элемент SVG (обычно группу ), который содержит все остальные элементы, составляющие вид для перетаскивания.

getSvgRoot() {
  return this.rootSvg;
}

Возврат подвижности

Метод isMovable возвращает, является ли перетаскиваемый объект в данный момент перемещаемым (поскольку вы можете временно отключить перетаскивание объекта). Если isMovable возвращает false рабочая область будет перетаскиваться.

isMovable() {
  return true;
}

Возврат позиции

Метод getRelativeToSurfaceXY возвращает Coordinate , указывающую местоположение верхнего начального угла перетаскиваемого объекта в координатах рабочего пространства.

Координаты рабочего пространства имеют начало в абсолютно левом и абсолютно верхнем положениях рабочего пространства. Они не меняются при масштабировании или перемещении рабочего пространства.

getRelativeToSurfaceXY() {
  return this.loc;
}

Старт перетаскивания

Метод startDrag инициализирует перетаскивание перетаскиваемого объекта. Этот метод не перемещает перетаскиваемый объект. Однако вам следует сохранить все данные или создать объекты, необходимые для завершения перетаскивания. Это включает в себя все данные, которые могут потребоваться для отмены перетаскивания при вызове метода revertDrag .

Он также должен изменить элементы SVG так, чтобы они находились на слое перетаскивания рабочей области, и располагались выше любых других элементов.

Он также принимает событие, которое можно использовать для проверки нажатий клавиш. Это позволяет (например) обрабатывать перетаскивание при переключении передач иначе, чем обычное перетаскивание.

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...
}

Тащить

Метод drag фактически перемещает перетаскиваемый объект. newLoc находится в координатах рабочего пространства, а также передаётся событие, которое можно использовать для проверки нажатий клавиш.

drag(newLoc, e) {
  this.moveTo(newLoc);
}

Откат перетаскиваний

Метод revertDrag возвращает перетаскиваемый объект в положение, в котором он находился в начале перетаскивания. Это происходит, например, если перетаскиваемый объект оказывается на цели перетаскивания , которая препятствует его перемещению.

revertDrag() {
  // Move back to the position that was stored in `startDrag`.
  this.moveTo(this.startLoc);
}

Конец перетаскивания

Метод endDrag завершает перетаскивание, освобождая все сохраненные данные или объекты и возвращая перетаскиваемый объект на исходный уровень.

endDrag всегда вызывается после revertDrag , если вызывается 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);
}

Выбор

Перетаскиваемый элемент определяется элементом, выбранным при обнаружении перетаскивания.

Выбираемый

Чтобы быть выбранным, перетаскиваемый объект должен реализовывать интерфейс 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.
  }
}

Выбор набора

Выбранный элемент можно установить с помощью вызова Blockly.common.setSelected() . Обычно это нужно делать в ответ на событие pointerdown от пользователя.

  constructor() {
    this.initSvg();

    Blockly.browserEvents.conditionalBind(
      this.getSvgRoot(),
      'pointerdown',
      this,
      () => Blockly.common.setSelected(this));
  }

Совместимость

Ваш перетаскиваемый объект может реализовывать дополнительные интерфейсы, чтобы иметь возможность взаимодействовать с другими системами в Blockly.

Удаляемый

Вы можете реализовать интерфейс IDeleteable , чтобы разрешить удаление перетаскиваемого объекта с помощью корзины или других объектов удаления.

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.
  }
}

Копируемый

Вы можете реализовать интерфейс ICopyable , чтобы разрешить копирование перетаскиваемого объекта, и определить IPaster , чтобы разрешить его вставку.

Дополнительную информацию о копировании и вставке см. в разделе Копировать и вставить .