В интерактивных интерфейсах пользовательские действия часто должны находиться в определённых границах. Перетаскиваемые элементы не должны выходить за пределы контейнера, изменяемые размеры не должны становиться слишком маленькими или слишком большими, а области взаимодействия иногда необходимо привязывать к сетке.
Библиотека Interact.js предоставляет набор механизмов, позволяющих ограничивать действия пользователя. Эти механизмы реализованы через систему modifiers — модификаторов поведения взаимодействия.
Модификаторы применяются к операциям:
Они выполняются на каждом шаге взаимодействия и изменяют координаты или размеры элемента перед тем, как событие будет передано обработчику.
Основные типы ограничений:
Все ограничения в Interact.js реализуются через свойство modifiers, которое передаётся в конфигурацию взаимодействия.
Пример базовой структуры:
interact('.item')
.draggable({
modifiers: [
interact.modifiers.restrict({
restriction: 'parent'
})
]
})
Массив modifiers может содержать несколько
модификаторов, которые применяются последовательно.
Каждый модификатор:
Последовательность обработки:
Модификатор restrict ограничивает положение указателя или элемента внутри определённой области.
interact('.box')
.draggable({
modifiers: [
interact.modifiers.restrict({
restriction: 'parent',
endOnly: true
})
]
})
Параметры:
| параметр | описание |
|---|---|
| restriction | область ограничения |
| endOnly | ограничение применяется только в конце действия |
| elementRect | какая часть элемента участвует в проверке |
Значение restriction может быть:
'parent''self'interact('.box')
.draggable({
modifiers: [
interact.modifiers.restrict({
restriction: {
left: 100,
top: 100,
right: 500,
bottom: 400
}
})
]
})
Объект ограничения содержит координаты:
lefttoprightbottomЭлемент не сможет выйти за указанные границы.
Иногда требуется ограничивать не сам элемент, а положение курсора.
interact('.item')
.draggable({
modifiers: [
interact.modifiers.restrict({
restriction: 'parent',
elementRect: { left: 0, right: 0, top: 1, bottom: 1 }
})
]
})
Параметр elementRect определяет, какая часть элемента
участвует в вычислении ограничения.
Значения:
Модификатор restrictRect работает аналогично
restrict, но ограничивает границы
элемента, а не положение указателя.
interact('.card')
.draggable({
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent'
})
]
})
Отличие:
| restrict | restrictRect |
|---|---|
| ограничивает указатель | ограничивает элемент |
| может позволить элементу выходить частично | не позволяет выходить за границы |
Этот модификатор чаще используется для UI-конструкторов и редакторов.
При изменении размеров элементов важно задавать минимальные и максимальные значения.
Модификатор restrictSize ограничивает размеры.
interact('.panel')
.resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [
interact.modifiers.restrictSize({
min: { width: 100, height: 50 },
max: { width: 600, height: 400 }
})
]
})
Параметры:
| параметр | описание |
|---|---|
| min | минимальные размеры |
| max | максимальные размеры |
Если пользователь пытается уменьшить элемент ниже min,
библиотека автоматически ограничивает размеры.
Иногда необходимо ограничить позиции краёв элемента при изменении размеров.
Модификатор restrictEdges применяется при
resizable.
interact('.window')
.resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [
interact.modifiers.restrictEdges({
outer: 'parent'
})
]
})
Параметры:
| параметр | значение |
|---|---|
| outer | внешняя граница |
| inner | внутренняя граница |
Пример ограничения:
interact.modifiers.restrictEdges({
outer: {
left: 0,
top: 0,
right: 800,
bottom: 600
}
})
Края элемента не смогут выйти за пределы заданной области.
Привязка элементов к сетке используется в редакторах интерфейсов, конструкторах страниц и графических инструментах.
Модификатор snap фиксирует координаты к ближайшей точке сетки.
interact('.item')
.draggable({
modifiers: [
interact.modifiers.snap({
targets: [
interact.snappers.grid({ x: 50, y: 50 })
],
range: Infinity
})
]
})
Параметры:
| параметр | описание |
|---|---|
| targets | массив точек привязки |
| range | радиус активации |
| relativePoints | точки элемента |
interact.snappers.grid({
x: 20,
y: 20
})
Элемент будет перемещаться только кратно:
Можно задавать несколько целей.
interact.modifiers.snap({
targets: [
{ x: 100, y: 100 },
{ x: 300, y: 300 }
],
range: 50
})
Если элемент попадает в радиус 50px, координаты
автоматически корректируются.
Для операций изменения размеров используется snapEdges.
interact('.panel')
.resizable({
modifiers: [
interact.modifiers.snapEdges({
targets: [
interact.snappers.grid({ x: 50, y: 50 })
]
})
]
})
Края элемента будут “прилипать” к сетке.
Это особенно полезно в:
Модификатор snapSize ограничивает размеры к сетке.
interact('.box')
.resizable({
modifiers: [
interact.modifiers.snapSize({
targets: [
interact.snappers.grid({ width: 100, height: 100 })
]
})
]
})
Размеры элемента будут изменяться шагами:
Модификаторы могут применяться одновременно.
Пример:
interact('.widget')
.draggable({
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent'
}),
interact.modifiers.snap({
targets: [
interact.snappers.grid({ x: 20, y: 20 })
]
})
]
})
.resizable({
modifiers: [
interact.modifiers.restrictSize({
min: { width: 100, height: 100 }
})
]
})
Последовательность выполнения модификаторов:
Вместо фиксированной области можно использовать функцию.
interact('.item')
.draggable({
modifiers: [
interact.modifiers.restrict({
restriction: function () {
return document.querySelector('.container')
}
})
]
})
Функция возвращает область ограничения.
Это позволяет:
Иногда требуется ограничивать не центр элемента, а конкретную точку.
Используется relativePoints.
interact.modifiers.snap({
targets: [interact.snappers.grid({ x: 50, y: 50 })],
relativePoints: [
{ x: 0, y: 0 },
{ x: 0.5, y: 0.5 },
{ x: 1, y: 1 }
]
})
Точки означают:
| значение | позиция |
|---|---|
| 0,0 | левый верх |
| 0.5,0.5 | центр |
| 1,1 | правый низ |
Привязка будет проверяться для каждой точки.
Параметр endOnly откладывает ограничение до окончания взаимодействия.
interact.modifiers.restrict({
restriction: 'parent',
endOnly: true
})
Поведение:
Такой подход используется для:
Ограничения применяются и к жестам масштабирования.
interact('.canvas')
.gesturable({
modifiers: [
interact.modifiers.restrictSize({
min: { width: 200, height: 200 },
max: { width: 1000, height: 1000 }
})
]
})
Это предотвращает:
interact('.block')
.draggable({
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent'
}),
interact.modifiers.snap({
targets: [
interact.snappers.grid({ x: 25, y: 25 })
]
})
],
listeners: {
move(event) {
const target = event.target
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
target.style.transform = `translate(${x}px, ${y}px)`
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
}
}
})
Результат:
interact('.resizable')
.resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [
interact.modifiers.restrictEdges({
outer: 'parent'
}),
interact.modifiers.restrictSize({
min: { width: 150, height: 100 }
}),
interact.modifiers.snapSize({
targets: [
interact.snappers.grid({ width: 50, height: 50 })
]
})
],
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 })
}
}
})
Поведение:
Модификаторы выполняются при каждом событии перемещения указателя, поэтому важно учитывать влияние на производительность.
Рекомендации:
endOnly, если возможноОптимально:
1–3 модификатора на взаимодействие
Это обеспечивает плавность даже при высокой частоте событий.
Ограничение действий пользователя используется в различных типах интерфейсов.
| модификатор | назначение |
|---|---|
| restrict | ограничение указателя |
| restrictRect | ограничение элемента |
| restrictEdges | ограничение краёв |
| restrictSize | ограничение размеров |
| snap | привязка координат |
| snapEdges | привязка краёв |
| snapSize | привязка размеров |
Эти инструменты позволяют точно контролировать пользовательские взаимодействия и создавать сложные интерфейсы с предсказуемым поведением.