Interact.js предоставляет мощный функционал для
управления интерактивными элементами на странице, включая перемещение,
масштабирование и вращение. Одной из ключевых задач при масштабировании
элементов является сохранение их исходных пропорций. Для этого
используется опция aspectRatio, которая гарантирует, что
ширина и высота элемента будут изменяться согласованно.
aspectRatioОпция aspectRatio задаёт отношение ширины к высоте
элемента. Это отношение может быть:
true сохраняет
исходное соотношение сторон элемента при изменении размеров.16/9 или 1 для квадрата.Пример базового использования:
interact('.resizable')
.resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [
interact.modifiers.aspectRatio({
ratio: true
})
],
listeners: {
move(event) {
let { x, y } = event.target.dataset;
x = (parseFloat(x) || 0) + event.deltaRect.left;
y = (parseFloat(y) || 0) + event.deltaRect.top;
Object.assign(event.target.style, {
width: `${event.rect.width}px`,
height: `${event.rect.height}px`,
transform: `translate(${x}px, ${y}px)`
});
Object.assign(event.target.dataset, { x, y });
}
}
});
В этом примере:
edges задаёт, с каких сторон возможна растяжка.modifiers.aspectRatio({ ratio: true }) сохраняет
исходное соотношение сторон элемента.move обновляются размеры и позиция
элемента.Если необходимо, чтобы элемент всегда масштабировался в определённом
соотношении, можно передать число в ratio. Например, для
прямоугольника 16:9:
interact('.resizable-16-9')
.resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [
interact.modifiers.aspectRatio({
ratio: 16 / 9
})
],
listeners: {
move(event) {
let { x, y } = event.target.dataset;
x = (parseFloat(x) || 0) + event.deltaRect.left;
y = (parseFloat(y) || 0) + event.deltaRect.top;
Object.assign(event.target.style, {
width: `${event.rect.width}px`,
height: `${event.rect.height}px`,
transform: `translate(${x}px, ${y}px)`
});
Object.assign(event.target.dataset, { x, y });
}
}
});
Фиксированное число позволяет контролировать точное соотношение ширины и высоты независимо от исходных размеров элемента.
AspectRatio можно комбинировать с другими модификаторами для ограничения размеров элемента:
modifiers: [
interact.modifiers.restrictSize({
min: { width: 100, height: 100 },
max: { width: 400, height: 400 }
}),
interact.modifiers.aspectRatio({ ratio: true })
]
restrictSize ограничивает минимальные и максимальные
размеры.aspectRatio гарантирует, что пропорции сохраняются даже
при этих ограничениях.Важно учитывать, что порядок модификаторов влияет на поведение.
aspectRatio должен идти после любых ограничивающих
модификаторов, чтобы пропорции корректно применялись к итоговым
размерам.
Пропорцию можно менять во время работы приложения. Для этого можно
обновлять параметр ratio через объект модификаторов:
const aspectModifier = interact.modifiers.aspectRatio({ ratio: 1 });
interact('.dynamic-resizable')
.resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [aspectModifier],
listeners: { move: event => updateSize(event) }
});
// Позже в коде
aspectModifier.ratio = 4 / 3;
Такой подход полезен для приложений, где пользователь может переключать формат, например, между квадратом, 4:3 и 16:9.
При сохранении пропорций важно учитывать текущие трансформации
элемента, например translate или rotate.
Interact.js корректно обновляет размеры и позицию, если в обработчике
move применять event.deltaRect и учитывать
смещения через dataset.
Пример правильного применения с transform:
Object.assign(target.style, {
width: `${event.rect.width}px`,
height: `${event.rect.height}px`,
transform: `translate(${x}px, ${y}px) rotate(${rotation}deg)`
});
Это позволяет сохранить пропорции, позицию и угол вращения одновременно.
ratio: 1.restrictSize), затем сохранение пропорций
(aspectRatio).Использование aspectRatio в Interact.js позволяет
создавать интерфейсы с элементами, которые масштабируются красиво и
предсказуемо, сохраняя свои пропорции в любых условиях.