В библиотеке Two.js управление визуальной областью сцены реализуется через манипуляции с группами, масштабом и смещением элементов. В отличие от 3D-библиотек, Two.js ориентирован на 2D-графику, поэтому зум и панорамирование достигаются изменением координат и масштабов объектов, а не камерой в привычном 3D-смысле.
Масштаб сцены управляется через свойство scale объектов
или групп. Если требуется увеличить всю сцену, оптимально использовать
контейнер Two.Group, включив в него все элементы.
// Создание сцены
const two = new Two({ width: 800, height: 600 }).appendTo(document.body);
// Создание группы для всей сцены
const sceneGroup = two.makeGroup();
// Добавление элементов в группу
const circle = two.makeCircle(400, 300, 50);
const rect = two.makeRectangle(200, 150, 100, 50);
sceneGroup.add(circle, rect);
// Увеличение сцены в 2 раза
sceneGroup.scale = 2;
two.update();
Особенности масштабирования:
scale — одно значение, которое применяется и к X, и к
Y. Для разнонаправленного увеличения можно использовать
scaleX и scaleY.// Масштабирование относительно центра сцены
sceneGroup.translation.set(two.width / 2, two.height / 2);
sceneGroup.scale = 1.5;
Панорамирование реализуется через смещение группы с элементами,
используя свойство translation.
// Сдвиг сцены на 100px вправо и 50px вниз
sceneGroup.translation.set(100, 50);
two.update();
Ключевые моменты:
translation задает позицию центра
группы относительно верхнего левого угла холста.Two.Tween или встроенный цикл рендеринга Two.js.// Плавное увеличение с одновременным сдвигом
two.bind('update', function(frameCount) {
sceneGroup.scale = 1 + 0.01 * Math.sin(frameCount * 0.05);
sceneGroup.translation.x = 400 + 50 * Math.sin(frameCount * 0.03);
sceneGroup.translation.y = 300 + 50 * Math.cos(frameCount * 0.03);
});
two.play();
Для интерактивного управления часто используют события мыши и колесо
прокрутки. Например, колесо мыши может управлять scale, а
перетаскивание мыши — translation.
let isDragging = false;
let lastX = 0;
let lastY = 0;
two.renderer.domElement.addEventListener('mousedown', e => {
isDragging = true;
lastX = e.clientX;
lastY = e.clientY;
});
two.renderer.domElement.addEventListener('mouseup', () => {
isDragging = false;
});
two.renderer.domElement.addEventListener('mousemove', e => {
if (isDragging) {
const dx = e.clientX - lastX;
const dy = e.clientY - lastY;
sceneGroup.translation.x += dx;
sceneGroup.translation.y += dy;
lastX = e.clientX;
lastY = e.clientY;
two.update();
}
});
two.renderer.domElement.addEventListener('wheel', e => {
const zoomFactor = 1.1;
if (e.deltaY < 0) {
sceneGroup.scale *= zoomFactor; // увеличение
} else {
sceneGroup.scale /= zoomFactor; // уменьшение
}
two.update();
});
Для удобного зума важно учитывать точку фокуса. По
умолчанию scale увеличивает сцену относительно центра
группы. Чтобы зум происходил относительно позиции курсора, применяют
преобразования координат:
function zoomAtPoint(group, zoom, px, py) {
const scaleFactor = zoom / group.scale;
const dx = (group.translation.x - px) * (scaleFactor - 1);
const dy = (group.translation.y - py) * (scaleFactor - 1);
group.scale = zoom;
group.translation.x += dx;
group.translation.y += dy;
two.update();
}
px и py — координаты курсора.Для удобства работы с большим количеством объектов часто применяют ограничения на масштаб и смещение:
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
// В обработчике колеса
sceneGroup.scale = clamp(sceneGroup.scale, 0.5, 3);
// В обработчике мыши
sceneGroup.translation.x = clamp(sceneGroup.translation.x, 0, two.width);
sceneGroup.translation.y = clamp(sceneGroup.translation.y, 0, two.height);
Ограничения предотвращают выход сцены за пределы видимой области и чрезмерное увеличение.
Two.js позволяет анимировать свойства группы напрямую через цикл обновления:
let t = 0;
two.bind('update', function() {
t += 0.01;
sceneGroup.scale = 1 + 0.5 * Math.sin(t);
sceneGroup.translation.x = 400 + 100 * Math.cos(t);
sceneGroup.translation.y = 300 + 100 * Math.sin(t);
});
two.play();
bind('update', callback) — основной способ обновления
сцены каждый кадр.Эти методы обеспечивают гибкое и плавное управление видимой областью сцены, позволяя создавать интерактивные приложения с масштабируемыми и перемещаемыми объектами.