Динамическое изменение ограничений

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

Ограничения через функцию

Вместо передачи статического объекта с границами (restrict) можно использовать функцию, которая возвращает объект с текущими параметрами:

interact('.draggable').draggable({
  modifiers: [
    interact.modifiers.restrictRect({
      restriction: function (target, element, interaction) {
        if (interaction.rect.left < 100) {
          return { left: 0, top: 0, right: 500, bottom: 500 };
        } else {
          return { left: 50, top: 50, right: 800, bottom: 600 };
        }
      },
      endOnly: true
    })
  ]
});

В этом примере ограничения автоматически подстраиваются под положение элемента, благодаря функции restriction. Функция получает следующие аргументы:

  • target — DOM-элемент, к которому применён интеракт;
  • element — элемент, фактически обрабатываемый движком;
  • interaction — объект текущего взаимодействия (drag, resize, etc.), содержащий актуальные данные.

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

Ограничения по родительскому элементу

Interact.js позволяет ограничивать движение внутри родительского контейнера с помощью restrictRect и параметра restriction: 'parent'. Для динамических интерфейсов часто требуется менять родителя на лету:

interact('.draggable').draggable({
  modifiers: [
    interact.modifiers.restrictRect({
      restriction: function (target, element, interaction) {
        const currentParent = element.closest('.active-container');
        return currentParent;
      },
      endOnly: true
    })
  ]
});

Здесь closest('.active-container') возвращает актуальный контейнер, который может изменяться в зависимости от состояния приложения.

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

Для элементов с возможностью изменения размеров (resizable) ограничения можно задавать аналогично:

interact('.resizable').resizable({
  modifiers: [
    interact.modifiers.restrictSize({
      min: function (target, element, interaction) {
        return { width: 100, height: 50 };
      },
      max: function (target, element, interaction) {
        const parentRect = element.parentElement.getBoundingClientRect();
        return { width: parentRect.width, height: parentRect.height };
      }
    })
  ],
  edges: { left: true, right: true, bottom: true, top: true }
});

Особенности:

  • min и max могут быть функциями, возвращающими актуальные размеры на основе контекста DOM;
  • это позволяет изменять допустимые размеры при динамическом изменении контейнера или других элементов интерфейса.

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

Динамическая сетка (snap) позволяет адаптировать шаги перемещения:

interact('.draggable').draggable({
  modifiers: [
    interact.modifiers.snap({
      targets: function (x, y, interaction) {
        if (interaction.rect.left < 200) {
          return [interact.snappers.grid({ x: 20, y: 20 })];
        } else {
          return [interact.snappers.grid({ x: 50, y: 50 })];
        }
      },
      range: Infinity,
      relativePoints: [{ x: 0, y: 0 }]
    })
  ]
});

Использование функции для targets позволяет менять шаг сетки в зависимости от позиции или состояния интерфейса, обеспечивая гибкую адаптацию UX.

Динамическое включение и отключение модификаторов

Interact.js поддерживает возможность включать и отключать модификаторы на лету через метод modifiers. Например, можно временно отменять ограничение при выполнении специальных условий:

interact('.draggable').draggable({
  modifiers: [
    interact.modifiers.restrictRect({ restriction: 'parent', endOnly: true })
  ]
})
.on('dragmove', function (event) {
  if (event.client.x > 500) {
    event.interaction.modifiers = []; // отключаем ограничения
  }
});

Это даёт возможность реагировать на действия пользователя и изменять правила поведения без пересоздания интерактора.

Применение динамических ограничений для сложных интерфейсов

Динамические ограничения полезны в следующих сценариях:

  • Интерактивные панели и дашборды, где контейнеры меняют размеры;
  • Редакторы изображений и макетов, где сетка и границы изменяются в зависимости от масштабирования;
  • Игровые интерфейсы, где области допустимого перемещения зависят от состояния уровня или позиции других объектов.

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

  • Использовать функции для restriction, min, max и snap.targets, чтобы ограничения автоматически подстраивались под состояние интерфейса.
  • Динамически определять родителя через closest или подобные методы DOM, если контейнеры могут меняться.
  • При необходимости отключать модификаторы через event.interaction.modifiers, чтобы временно снять ограничения.
  • Следить за производительностью: частое вычисление ограничений для большого числа элементов может требовать оптимизации.

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