Создание собственных модификаторов

Interact.js предоставляет мощный механизм для работы с drag & drop, resize и gestures. Одной из ключевых особенностей библиотеки является возможность создания собственных модификаторов, которые позволяют гибко контролировать поведение интерактивных элементов. Модификаторы — это функции, которые изменяют координаты или размеры объекта перед их применением к элементу.


Структура модификатора

Собственный модификатор в Interact.js представляет собой объект с основными свойствами:

{
  // Уникальное имя модификатора
  name: 'myModifier',

  // Функция подготовки, вызывается один раз при инициализации модификатора
  start: function (arg) {},

  // Основная функция, выполняющая корректировку координат или размеров
  set: function (arg) { return arg; },

  // Функция, вызываемая после применения модификатора, для чистки или логирования
  stop: function (arg) {}
}
  • start используется для инициализации состояния модификатора перед началом взаимодействия.
  • set выполняет основную логику трансформации, принимает объект arg с текущими координатами и возвращает объект с изменёнными значениями.
  • stop позволяет завершить работу модификатора, например, сбросить временные данные.

Аргументы функции set

Функция set получает объект с ключевыми свойствами:

  • x — текущая позиция по оси X
  • y — текущая позиция по оси Y
  • rect — объект с размерами и положением элемента
  • edges — объект с информацией о границах при ресайзе (top, left, bottom, right)
  • delta — изменение координат с предыдущего шага
  • interaction — объект текущего взаимодействия, содержащий методы и состояние drag/resize

Функция должна возвращать объект с координатами или размерами, которые будут применены к элементу:

set: function (arg) {
  return {
    x: arg.x + 10, // смещение по X
    y: arg.y       // без изменений по Y
  };
}

Примеры собственных модификаторов

Ограничение перемещения по сетке

Модификатор для привязки элемента к сетке с шагом 20px:

const snapToGrid = {
  name: 'snapToGrid',

  set: function (arg) {
    const gridSize = 20;
    return {
      x: Math.round(arg.x / gridSize) * gridSize,
      y: Math.round(arg.y / gridSize) * gridSize
    };
  }
};

interact('.draggable')
  .draggable({
    modifiers: [snapToGrid]
  });

Ограничение движения по оси

Модификатор, который позволяет двигать элемент только по оси X:

const restrictX = {
  name: 'restrictX',

  set: function (arg) {
    return {
      x: arg.x,
      y: 0
    };
  }
};

interact('.draggable')
  .draggable({
    modifiers: [restrictX]
  });

Ограничение размеров при ресайзе

Модификатор, который ограничивает ширину элемента:

const limitWidth = {
  name: 'limitWidth',

  set: function (arg) {
    const maxWidth = 300;
    const minWidth = 100;

    return {
      width: Math.min(Math.max(arg.rect.width, minWidth), maxWidth),
      height: arg.rect.height
    };
  }
};

interact('.resizable')
  .resizable({
    modifiers: [limitWidth],
    edges: { left: true, right: true, bottom: true, top: true }
  });

Использование нескольких модификаторов одновременно

Interact.js позволяет комбинировать несколько модификаторов. Они применяются последовательно в порядке объявления:

interact('.draggable')
  .draggable({
    modifiers: [
      snapToGrid,
      restrictX
    ]
  });

В этом примере сначала координаты будут привязаны к сетке, а затем ограничены по оси X. Порядок важен, так как каждый модификатор получает результат предыдущего.


Доступ к внутреннему состоянию взаимодействия

Модификаторы могут использовать объект interaction для получения информации о состоянии drag/resize:

  • interaction.prevEvent — предыдущий drag/resizе-событие
  • interaction.startCoords — начальная точка взаимодействия
  • interaction.interactable — объект, к которому применено взаимодействие

Это позволяет создавать сложные динамические модификаторы, учитывающие скорость движения, направление или предыдущее положение.


Рекомендации по написанию собственных модификаторов

  • Всегда возвращать новый объект, не изменяя исходный аргумент напрямую.
  • Минимизировать вычисления в set, чтобы избежать тормозов при быстром drag/resize.
  • При необходимости использовать start и stop для хранения временного состояния.
  • Комбинировать модификаторы для создания сложного поведения вместо написания одного монолитного модификатора.
  • Тестировать модификатор на разных элементах и сценариях, чтобы убедиться в корректной работе.

Продвинутые возможности

  • Можно создавать модификаторы для жестов, которые изменяют масштаб или вращение.
  • Поддерживаются асинхронные вычисления, например для получения данных с сервера или анимации, но их использование требует аккуратного контроля состояния.
  • Можно использовать существующие модификаторы Interact.js в качестве шаблонов для новых, комбинируя snap, restrict, aspectRatio и другие встроенные модификаторы.

Собственные модификаторы делают Interact.js невероятно гибким инструментом для создания уникального интерактивного поведения на веб-страницах, позволяя полностью контролировать перемещение, изменение размеров и жесты.