Создайте новый тип значка

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

Мы рекомендуем создать подкласс абстрактного класса Icon , поскольку он уже предоставляет реализации по умолчанию многих методов в интерфейсе IIcon .

class MyIcon extends Blockly.icons.Icon {
  // The constructor should always take in the source block so that svg elements
  // can be properly created.
  constructor(sourceBlock) {
    super(sourceBlock);
  }
}

Укажите тип значка

Метод getType возвращает значение, представляющее тип значка. Он используется для регистрации значка для сериализации и получения значка из getIcon .

JavaScript

  getType() {
    return new Blockly.icons.IconType('my_icon');
  }

Машинопись

  getType(): Blockly.icons.IconType<MyIcon> {
    return new Blockly.icons.IconType<MyIcon>('my_icon');
  }

Создайте представление значка

Вид значка относится к элементам SVG, которые находятся в блоке.

Инициализировать представление

Метод initView позволяет создавать SVG-элементы вашего значка, которые размещаются в блоке. Новые элементы должны быть дочерними элементами элемента this.svgRoot , чтобы они автоматически очищались при уничтожении значка.

Модуль Blockly.utils.dom предоставляет понятный интерфейс для создания экземпляров SVG.

initView(pointerdownListener) {
  if (this.svgRoot) return;  // Already initialized.

  // This adds the pointerdownListener to the svgRoot element.
  // If you do not call `super` you must do this yourself.
  super.initView(pointerdownListener);

  Blockly.utils.dom.createSvgElement(
    Blockly.utils.Svg.CIRCLE,
    {
      'class': 'my-css-class',
      'r': '8',
      'cx': '8',
      'cy': '8',
    },
    this.svgRoot  // Append to the svgRoot.
  );
}

Вернуть размер

Метод getSize возвращает размер значка, чтобы средство визуализации могло сделать блок достаточно широким для него.

Размер указывается в произвольных «единицах рабочего пространства» (которые не меняются при изменении масштаба рабочего пространства).

getSize() {
  return new Blockly.utils.Size(16, 16);
}

Установить порядок

Иконки имеют статический порядок внутри блока. Например, встроенные значки мутаторов всегда отображаются перед значками комментариев, которые отображаются перед значками предупреждений.

Порядок контролируется значением, возвращаемым методом getWeight . Значки с более положительным весом отображаются после значков с меньшим положительным весом.

getWeight() {
  return 10;
}

Реализация поведения при нажатии

Многие значки интерактивны и при нажатии на них что-то делают. Например, при нажатии на все встроенные значки появляются пузырьки . Для реализации этого вы можете использовать метод onClick .

onClick() {
  // Do something when clicked.
}

Реагировать на изменения блокировки

Некоторые значки также хотят реагировать на изменения в блоке, в частности на изменения в редактируемости и свертывании.

Редактируемость

Если ваш значок должен вести себя по-разному в зависимости от того, доступен ли блок для редактирования или нет (например, он не доступен для щелчка, когда блок недоступен для редактирования), реализуйте метод updateEditable . Этот метод вызывается автоматически при изменении редактируемого статуса блока.

updateEditable() {
  if (this.sourceBlock.isEditable()) {
    // Do editable things.
  } else {
    // Do non-editable things.
  }
}

Развал

Некоторые значки отображаются, когда блок свернут, но по умолчанию это не так. Если вы хотите, чтобы ваш значок отображался, переопределите метод isShownWhenCollapsed , чтобы он возвращал true .

isShownWhenCollapsed() {
  return true;
}

А затем переопределить метод updateCollapsed .

updateCollapsed() {
  // By default icons are hidden when the block is collapsed. We want it to
  // be shown, so do nothing.
}

Утилизировать иконку

Иконки должны очищать любые элементы dom или внешние ссылки при их удалении. По умолчанию все, что добавлено к this.svgRoot уничтожается, но другие ссылки необходимо очищать вручную. Это должно быть сделано в методе dispose .

dispose() {
  // Always call super!
  super.dispose();

  this.myBubble?.dispose();
  this.myOtherReference?.dispose();
}