Сохранение пропорций

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

В Interact.js сохранение пропорций реализуется с помощью конфигурации modifiers. Основной инструмент для этой цели — модификатор aspectRatio.

interact('.resize-element')
  .resizable({
    edges: { left: true, right: true, bottom: true, top: true },
    modifiers: [
      interact.modifiers.aspectRatio({
        ratio: 'preserve', // сохраняет исходное соотношение ширины к высоте
        // можно задать точное число, например ratio: 16/9
      })
    ],
    inertia: true
  })
  .on('resizemove', function (event) {
    const { width, height } = event.rect;
    event.target.style.width = `${width}px`;
    event.target.style.height = `${height}px`;
  });

Ключевые моменты:

  • edges определяет, какие грани элемента активны для масштабирования. Для сохранения пропорций можно масштабировать одновременно по диагонали, выбирая несколько граней.
  • modifiers.aspectRatio с опцией ratio: 'preserve' автоматически вычисляет соотношение ширины к высоте при первой активации ресайза.
  • Можно указать конкретное соотношение, например ratio: 4/3, если требуется фиксированная пропорция независимо от исходного размера.

Комбинирование сохранения пропорций с ограничениями размеров

В большинстве проектов необходимо не только сохранить пропорции, но и ограничить минимальный и максимальный размер элемента. Для этого используется модификатор restrictSize вместе с aspectRatio.

interact('.resize-element')
  .resizable({
    edges: { left: true, right: true, bottom: true, top: true },
    modifiers: [
      interact.modifiers.aspectRatio({ ratio: 'preserve' }),
      interact.modifiers.restrictSize({
        min: { width: 100, height: 100 },
        max: { width: 800, height: 600 }
      })
    ],
    inertia: true
  })
  .on('resizemove', event => {
    const { width, height } = event.rect;
    event.target.style.width = `${width}px`;
    event.target.style.height = `${height}px`;
  });

Особенности работы:

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

Динамическое изменение соотношения при интерактивном масштабировании

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

interact('.resize-element')
  .resizable({
    edges: { left: true, right: true, bottom: true, top: true },
    modifiers: [
      interact.modifiers.aspectRatio({
        ratio: function (target) {
          // вычисление пропорции на основе данных элемента
          const width = target.offsetWidth;
          const height = target.offsetHeight;
          return width / height;
        }
      })
    ],
    inertia: true
  })
  .on('resizemove', event => {
    const { width, height } = event.rect;
    event.target.style.width = `${width}px`;
    event.target.style.height = `${height}px`;
  });

Преимущества:

  • Позволяет адаптироваться под элементы с разными исходными размерами.
  • Можно реализовать условное изменение пропорций при масштабировании в зависимости от текущего состояния интерфейса.

Масштабирование по диагонали для сохранения пропорций

Чтобы сохранить пропорции при масштабировании, важно учитывать направление изменения размера. На практике рекомендуется:

  • Масштабировать элемент по диагонали, активируя одновременно верхнюю и правую грани (top: true, right: true) или нижнюю и левую.
  • Избегать изменения только по одной оси, так как это нарушит пропорции, если модификатор не установлен.
edges: { top: true, left: true } // изменение по диагонали

При этом aspectRatio корректно пересчитывает размеры, предотвращая искажения.


Интеграция с трансформациями и CSS

Interact.js позволяет использовать сохранение пропорций в сочетании с CSS-трансформациями, например scale() или transform. При этом важно:

  • Обновлять стили width и height элемента, а не только transform, чтобы aspectRatio корректно вычислял размеры.
  • Если используется transform: scale, пропорции остаются, но реальные размеры элемента могут отличаться, что важно для событий клика и drag.

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

  • Для изображений лучше всего использовать ratio: 'preserve', чтобы масштабирование не искажало графику.
  • Для фиксированных блоков интерфейса удобнее задавать числовое соотношение, например 16/9, чтобы элементы оставались унифицированными.
  • Комбинация aspectRatio + restrictSize обеспечивает полное управление размером и пропорциями, предотвращая выход элемента за допустимые границы.

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