Ограничения и валидация жестов

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


Ограничения позиции (Restricting Position)

Для элементов, которые можно перетаскивать, часто требуется ограничить область перемещения. Interact.js предоставляет несколько способов ограничения:

interact('.draggable')
  .draggable({
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent', // ограничение родительским элементом
        endOnly: true // ограничение применяется только при завершении перетаскивания
      })
    ],
    inertia: true
  });

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

  • restriction – задаёт границы перемещения. Может быть:

    • 'parent' – элемент не выходит за пределы родителя;
    • DOM-элемент или CSS-селектор – ограничение определённым блоком;
    • объект с координатами {top, left, bottom, right} – кастомные границы.
  • endOnly – если true, ограничения применяются только после окончания перетаскивания, что обеспечивает более плавное движение.

  • inertia – добавляет физическую инерцию, что делает движение более естественным.


Ограничения по размеру и масштабу

При работе с элементами, поддерживающими масштабирование и изменение размера, важно контролировать минимальные и максимальные размеры:

interact('.resizable')
  .resizable({
    edges: { left: true, right: true, bottom: true, top: true },
    modifiers: [
      interact.modifiers.restrictSize({
        min: { width: 100, height: 50 },
        max: { width: 500, height: 300 }
      })
    ],
    inertia: true
  });
  • restrictSize – гарантирует, что размеры элемента останутся в заданных пределах.
  • min и max – объекты, задающие минимальную и максимальную ширину и высоту.
  • Применение inertia к resizable-элементам создаёт эффект плавного расширения/сжатия при резком движении курсора.

Валидация жестов с помощью listeners и preventDefault

Interact.js позволяет фильтровать жесты до их применения через обработчики событий move, start, end:

interact('.draggable')
  .draggable({
    listeners: {
      start(event) {
        if (!event.target.classList.contains('allowed')) {
          event.interaction.stop(); // отменяет действие
        }
      },
      move(event) {
        const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx;
        const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy;

        if (x < 0 || y < 0) return; // ограничение движения влево и вверх

        event.target.style.transform = `translate(${x}px, ${y}px)`;
        event.target.setAttribute('data-x', x);
        event.target.setAttribute('data-y', y);
      }
    }
  });
  • event.interaction.stop() – прерывает текущее взаимодействие.
  • event.dx / event.dy – смещения по осям, используются для вычисления новой позиции.
  • Можно комбинировать ограничения CSS и JS для более сложной логики.

Ограничение угла поворота и направления жеста

Для жестов вращения и сложных трансформаций можно ограничивать угол поворота и направление:

interact('.rotatable')
  .gesturable({
    listeners: {
      move(event) {
        let rotation = (parseFloat(event.target.getAttribute('data-rotation')) || 0) + event.da;

        // Ограничение угла от -45 до 45 градусов
        rotation = Math.max(-45, Math.min(45, rotation));

        event.target.style.transform = `rotate(${rotation}deg)`;
        event.target.setAttribute('data-rotation', rotation);
      }
    }
  });
  • event.da – изменение угла в текущем движении.
  • Применение функции Math.max/Math.min позволяет ограничить диапазон поворота.
  • Можно расширять проверку до сложной валидации, например, запрет движения по определённой траектории.

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

Interact.js поддерживает множественные модификаторы одновременно, что даёт точный контроль над поведением:

interact('.draggable-resizable')
  .draggable({
    modifiers: [
      interact.modifiers.restrictRect({ restriction: 'parent' }),
      interact.modifiers.snap({ targets: [interact.createSnapGrid({ x: 50, y: 50 })] })
    ]
  })
  .resizable({
    modifiers: [
      interact.modifiers.restrictSize({ min: { width: 100, height: 100 } }),
      interact.modifiers.aspectRatio({ ratio: 'preserve' })
    ]
  });
  • snap – прилипание к сетке или линиям.
  • aspectRatio – сохраняет пропорции при изменении размера.
  • Комбинация ограничений и валидации позволяет создавать интерфейсы с высокой степенью контроля.

Динамическая валидация

Можно изменять ограничения на лету, реагируя на состояние приложения или пользовательский ввод:

function updateRestriction(newRestriction) {
  interact('.draggable').draggable({
    modifiers: [
      interact.modifiers.restrictRect({ restriction: newRestriction })
    ]
  });
}

// Например, смена области перемещения при смене вкладки
updateRestriction(document.querySelector('.new-area'));
  • Поддержка динамического обновления ограничений делает Interact.js гибким для интерактивных приложений.

Ключевые рекомендации по ограничениям и валидации

  • Всегда использовать модификаторы для ограничения позиции и размера, чтобы предотвратить неожидаемые смещения.
  • Комбинировать модификаторы с проверкой в listeners для более сложной логики.
  • Применять inertia только там, где это улучшает UX, иначе элемент может выйти за пределы допустимой области.
  • Для поворотов и жестов использовать ограничение угла и направления для предсказуемого поведения.
  • Для сложных интерфейсов применять динамическое обновление ограничений на основе состояния приложения.

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