Snap - привязка к точкам

Snap — это мощный механизм в Interact.js, позволяющий привязывать элементы к заранее определённым координатам или сетке. Он широко используется для создания интерфейсов с drag-and-drop, где важна точность размещения элементов.

Настройка Snap

Snap активируется через метод interactable.snap(), который принимает объект с настройками. Основные параметры:

  • targets – массив точек или функций, к которым элемент будет привязываться.
  • range – радиус действия привязки. Если элемент попадает в радиус точки, его позиция корректируется.
  • relativePoints – смещение привязки относительно размеров элемента. Полезно для центрирования.
  • offset – смещение для всей системы snap.
  • endOnly – если true, привязка применяется только в конце перемещения.

Пример базовой настройки:

interact('.draggable').draggable({
  listeners: {
    move(event) {
      event.target.style.transform =
        `translate(${event.pageX}px, ${event.pageY}px)`;
    }
  }
})
.snap({
  targets: [
    { x: 100, y: 100 },
    { x: 200, y: 200 },
    { x: 300, y: 300 }
  ],
  range: 20,
  relativePoints: [{ x: 0.5, y: 0.5 }],
});

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

Snap к сетке

Для привязки к сетке используется встроенный метод interact.createSnapGrid(). Этот способ позволяет задать равномерное распределение точек без ручного перечисления каждой координаты.

interact('.draggable').draggable({
  listeners: {
    move(event) {
      let x = event.pageX;
      let y = event.pageY;
      event.target.style.transform = `translate(${x}px, ${y}px)`;
    }
  }
})
.snap({
  targets: [
    interact.createSnapGrid({ x: 50, y: 50 })
  ],
  range: 25
});

Здесь элемент будет автоматически притягиваться к ближайшей точке сетки с шагом 50 пикселей, если находится в радиусе 25 пикселей.

Snap и относительные точки элемента

Параметр relativePoints позволяет контролировать, какая часть элемента будет «цепляться» к точке. Например, если задать { x: 0, y: 0 }, привязка произойдёт по верхнему левому углу, { x: 0.5, y: 0.5 } — по центру.

.snap({
  targets: [
    { x: 150, y: 150 },
  ],
  range: 30,
  relativePoints: [{ x: 0, y: 0 }]
});

В этом случае верхний левый угол элемента будет проверяться на попадание в область snap.

Snap с динамическими точками

Функции могут использоваться в targets для динамического вычисления привязки. Функция должна возвращать объект с координатами x и y.

.snap({
  targets: [
    function(x, y) {
      return { x: x - x % 50, y: y - y % 50 };
    }
  ],
  range: 25
});

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

endOnly: привязка только по завершении перемещения

Параметр endOnly контролирует момент применения snap:

.snap({
  targets: [
    { x: 100, y: 100 },
    { x: 200, y: 200 }
  ],
  range: 20,
  endOnly: true
});

Если endOnly = true, элемент свободно перемещается в процессе drag, а корректировка позиции выполняется только при отпускании.

Настройка визуальной обратной связи

Interact.js позволяет комбинировать snap с inertia и listeners, чтобы создавать интуитивно понятные интерфейсы. Например, можно менять цвет или тень элемента при попадании в радиус snap, сигнализируя пользователю о привязке.

listeners: {
  move(event) {
    let target = event.target;
    let snap = interact.getSnap(event);
    if (snap) {
      target.style.boxShadow = "0 0 10px green";
    } else {
      target.style.boxShadow = "";
    }
  }
}

Практические советы

  • Для сетки используйте interact.createSnapGrid, это проще, чем перечислять все точки вручную.
  • При сложных интерфейсах с множеством точек snap лучше ограничивать радиус, чтобы элементы не прыгали неожиданно.
  • Параметр relativePoints помогает корректно выравнивать элементы с нестандартными размерами.
  • endOnly рекомендуется при использовании inertia, чтобы привязка выглядела естественно.

Snap в Interact.js предоставляет полный контроль над точками привязки и позволяет создавать интерфейсы с высокой точностью и плавной анимацией перемещений. Использование сетки, динамических функций и относительных точек делает библиотеку гибкой и мощной для любого drag-and-drop сценария.