Инверсия при изменении размера

В Interact.js изменение размера элементов реализуется через метод resizable, который позволяет задавать направления изменения (edges) и ограничения по минимальным и максимальным размерам (restrictSize). Одной из важных особенностей является обработка инверсий — ситуации, когда элемент «переворачивается» при перетягивании за противоположные края.

Основные концепции инверсии

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

  • flipEnabled — ключевой параметр, включающий отслеживание инверсии и автоматическое изменение направления перетаскивания.
  • invert — внутренняя логика, которая позволяет элементу не «сжиматься в ноль», а плавно продолжать изменение размера в противоположную сторону.

Настройка инверсии

Для активации поддержки инверсий используется конфигурация при инициализации resizable:

interact('.resizable-element')
  .resizable({
    edges: { left: true, right: true, bottom: true, top: true },
    modifiers: [
      interact.modifiers.restrictEdges({
        outer: 'parent',
        endOnly: true
      }),
      interact.modifiers.restrictSize({
        min: { width: 50, height: 50 },
        max: { width: 500, height: 500 }
      })
    ],
    invert: true
  })
  .on('resizemove', event => {
    const { x, y } = event.deltaRect;
    event.target.style.width  = `${event.rect.width}px`;
    event.target.style.height = `${event.rect.height}px`;
    event.target.style.transform = `translate(${x}px, ${y}px)`;
  });

Ключевые моменты конфигурации:

  • edges — задает стороны элемента, за которые можно тянуть. Включение всех сторон важно для полной поддержки инверсий.
  • modifiers.restrictEdges — предотвращает выход элемента за пределы родителя при инверсии.
  • modifiers.restrictSize — фиксирует минимальные и максимальные размеры, предотвращая некорректные отрицательные значения.
  • invert: true — активирует внутреннюю обработку случаев, когда элемент «пересекает» исходные координаты.

Логика событий при инверсии

Событие resizemove при инверсии генерируется аналогично стандартному изменению размера, но с дополнительными особенностями:

  • deltaRect — содержит смещение и размеры элемента с учетом инверсии. При «перевороте» положительные значения могут становиться отрицательными, что позволяет корректно вычислять новые координаты.
  • event.rect — всегда возвращает актуальные размеры элемента после применения инверсии.
  • transform — для визуального сдвига элемента необходимо применять смещения по оси X и Y, иначе элемент будет визуально «скакать» при переходе через исходные координаты.

Управление ограничениями при инверсии

Инверсии особенно чувствительны к ограничениям размеров. Если минимальные и максимальные значения заданы некорректно, элемент может:

  • «залипать» на нуле ширины или высоты, создавая визуальный баг;
  • пересекать границы родителя при инверсии, если не применены restrictEdges.

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

modifiers: [
  interact.modifiers.restrictSize({ min: { width: 80, height: 80 } }),
  interact.modifiers.restrictEdges({ outer: 'parent' })
]

Применение на практике

Типичный сценарий с полной поддержкой инверсий выглядит так:

  1. Инициализация элемента с resizable и включением всех сторон (edges).
  2. Применение модификаторов restrictSize и restrictEdges.
  3. Включение параметра invert: true.
  4. Обновление стилей width, height и transform в событии resizemove.

Такой подход обеспечивает:

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

Советы по оптимизации

  • Использовать deltaRect для трансформации вместо прямого сложения координат. Это уменьшает вероятность «скачков» элемента при быстром изменении размеров.
  • Ставить разумные ограничения минимальных размеров, особенно если элемент может инвертироваться по обеим осям.
  • Тестировать на всех сторонах элемента, так как инверсии могут проявляться по-разному при изменении разных краев одновременно.

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