Snappable

Snappable — это плагин для библиотеки Shopify Draggable, предназначенный для управления точками привязки при перетаскивании элементов. Он позволяет объектам “прилипать” к заранее определённым зонам, создавая эффект аккуратного и контролируемого позиционирования, что особенно полезно для интерфейсов типа сеток, канбан-досок или редакторов контента.


Подключение и инициализация Snappable

Чтобы использовать Snappable, необходимо подключить основной пакет Draggable и соответствующий плагин. В JavaScript это выглядит так:

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

const container = document.querySelector('.container');

const draggable = new Draggable(container, {
  draggable: '.item',
  plugins: [Plugins.Snappable],
  snappable: {
    targets: ['.snap-target'],
    range: 30
  }
});

Пояснение ключевых параметров:

  • targets — селекторы элементов, к которым может “прилипнуть” перетаскиваемый объект.
  • range — радиус в пикселях, в пределах которого происходит привязка.

В примере выше, когда .item подносится на расстояние 30px к .snap-target, происходит автоматическая привязка.


Настройка поведения Snappable

Snappable поддерживает несколько важных опций для тонкой настройки:

  1. targets Определяет зоны, к которым элементы будут “прилипать”. Можно передавать селекторы CSS или DOM-элементы.

    snappable: {
      targets: [document.querySelectorAll('.snap-target')]
    }
  2. range Контролирует чувствительность привязки. Чем меньше значение, тем ближе элемент должен быть к цели, чтобы закрепиться.

  3. snapCenter Позволяет задавать центр привязки:

    • true — элемент будет привязываться по центру цели.
    • false — привязка происходит по ближайшему краю.
    snappable: {
      targets: ['.snap-target'],
      snapCenter: true
    }
  4. onSnap и onUnsnap События, позволяющие выполнять действия при срабатывании привязки или её отмене:

    draggable.on('snap:start', (event) => {
      console.log('Начало привязки', event);
    });
    
    draggable.on('snap:stop', (event) => {
      console.log('Привязка завершена', event);
    });

Примеры практического применения

  1. Сетка элементов
<div class="grid">
  <div class="grid-item"></div>
  <div class="grid-item snap-target"></div>
</div>
new Draggable(document.querySelector('.grid'), {
  draggable: '.grid-item',
  plugins: [Plugins.Snappable],
  snappable: {
    targets: ['.snap-target'],
    range: 20,
    snapCenter: true
  }
});

Элементы при перетаскивании будут автоматически “прилипать” к ячейкам сетки.

  1. Перетаскивание карточек на доске
const boardDraggable = new Draggable(document.querySelectorAll('.column'), {
  draggable: '.card',
  plugins: [Plugins.Snappable],
  snappable: {
    targets: document.querySelectorAll('.column'),
    range: 50
  }
});

Карточки можно будет аккуратно переставлять между колонками, не требуя идеальной точности позиционирования.


События Snappable

Snappable предоставляет набор событий для контроля привязки:

  • snap:move — вызывается при движении элемента в пределах радиуса привязки.
  • snap:start — срабатывает в момент начала привязки.
  • snap:stop — срабатывает, когда привязка завершена.
  • snap:unsnap — вызывается, если элемент удаляется из области привязки.

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

draggable.on('snap:move', ({ over, dragEvent }) => {
  over.classList.add('highlight');
});

draggable.on('snap:unsnap', ({ over }) => {
  over.classList.remove('highlight');
});

Оптимизация работы Snappable

  • Для больших интерфейсов рекомендуется ограничивать range минимально необходимым значением, чтобы снизить нагрузку на браузер.
  • Использование делегирования через селекторы позволяет динамически добавлять новые элементы без пересоздания Draggable.
  • Комбинирование Snappable с другими плагинами, например Sortable, позволяет создавать полноценные интерактивные интерфейсы с перемещением и привязкой элементов одновременно.

Snappable превращает обычное перетаскивание в точное и управляемое позиционирование, делая интерфейс более удобным и визуально аккуратным.