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

В Shopify Draggable сенсоры представляют собой объекты, отслеживающие взаимодействие пользователя с элементами на странице. Сенсор фиксирует начальные координаты, движение курсора или пальца, а также события начала, перемещения и завершения взаимодействия. В библиотеке Draggable встроены стандартные сенсоры: MouseSensor, TouchSensor и Sensor для кастомных решений. Основная задача кастомного сенсора — определить, когда элемент должен реагировать на пользовательское действие и передать эту информацию в систему Draggable.

Создание кастомного сенсора

Кастомный сенсор создается через наследование базового класса Sensor. Минимальная реализация требует переопределения методов attach(), detach() и start().

import { Sensor } from '@shopify/draggable';

class CustomSensor extends Sensor {
  attach() {
    this.el.addEventListener('mousedown', this.onMouseDown);
  }

  detach() {
    this.el.removeEventListener('mousedown', this.onMouseDown);
  }

  onMouseD own = (event) => {
    event.preventDefault();
    this.start(event);
  }

  start(event) {
    const position = { x: event.clientX, y: event.clientY };
    this.trigger('start', { sourceEvent: event, position });
  }
}

Ключевые моменты:

  • attach() — регистрирует обработчики событий на элементе.
  • detach() — удаляет обработчики, предотвращая утечки памяти.
  • start(event) — инициирует событие start, передавая координаты и исходное событие.

Передача данных в Draggable

После создания кастомного сенсора его нужно подключить к экземпляру Draggable через конфигурацию sensors. Пример интеграции:

import { Draggable } from '@shopify/draggable';

const draggable = new Draggable(document.querySelectorAll('.draggable'), {
  draggable: '.item',
  sensors: [CustomSensor]
});

draggable.on('drag:start', (event) => {
  console.log('Начало перетаскивания:', event.sourceEvent);
});

События, инициируемые сенсором, автоматически становятся частью жизненного цикла Draggable: drag:start, drag:move, drag:stop.

Расширение функционала кастомного сенсора

Кастомный сенсор может отслеживать дополнительные условия:

  • Ограничение перемещения по оси (x или y)
  • Игнорирование элементов с определенными классами
  • Активация только при долгом нажатии (long press)
  • Взаимодействие с нестандартными устройствами ввода (например, стилусами или датчиками жестов)

Пример ограничения перемещения по оси y:

start(event) {
  const position = { x: 0, y: event.clientY }; // игнорируем x
  this.trigger('start', { sourceEvent: event, position });
}

Работа с несколькими сенсорами

Draggable позволяет подключать несколько сенсоров одновременно. Это полезно для поддержки разных устройств ввода. При этом каждый сенсор должен корректно обрабатывать события, чтобы не возникало конфликтов.

import { MouseSensor, TouchSensor } from '@shopify/draggable';

const draggable = new Draggable(document.querySelectorAll('.draggable'), {
  draggable: '.item',
  sensors: [MouseSensor, TouchSensor, CustomSensor]
});

События от сенсоров будут объединяться в единую систему обработки перетаскивания.

Особенности производительности и оптимизации

Кастомные сенсоры могут генерировать большое количество событий mousemove или touchmove. Для повышения производительности рекомендуется:

  • Использовать requestAnimationFrame для обновления позиции элементов.
  • Ограничивать количество вызовов события trigger().
  • Отключать сенсор, когда перетаскивание не требуется.

Пример оптимизации через requestAnimationFrame:

onMouseM ove = (event) => {
  if (this.raf) cancelAnimationFrame(this.raf);

  this.raf = requestAnimationFrame(() => {
    this.trigger('move', { sourceEvent: event, position: { x: event.clientX, y: event.clientY } });
  });
};

Кастомные сенсоры для сложных интерфейсов

Кастомные сенсоры особенно полезны в случаях:

  • Перетаскивание элементов внутри канвасов или SVG
  • Drag-and-drop с виртуализированными списками
  • Использование жестов multitouch для масштабирования и вращения элементов
  • Поддержка нестандартных устройств ввода (геймпады, трекпады с мультитачем)

Каждый из этих сценариев требует тщательной работы с координатами, событиями и синхронизацией с жизненным циклом Draggable.

Советы по тестированию

  • Проверять работу сенсора на разных устройствах (desktop, mobile, планшеты).
  • Логировать координаты и события start, move, stop.
  • Использовать инструменты разработчика для проверки attach/detach и предотвращения утечек памяти.
  • Проверять совместимость с другими сенсорами, чтобы исключить конфликтные события.

Кастомные сенсоры позволяют полностью контролировать способ, которым элементы реагируют на действия пользователя, расширяя стандартный функционал Shopify Draggable и обеспечивая гибкую интеграцию в сложные интерфейсы.