Система событий в Babylon.js является важной частью взаимодействия с пользователем и других объектов в сцене. Она основана на стандартной системе событий браузера, но с учётом особенностей 3D-графики и интеграции с объектами сцены. Для понимания и эффективного использования системы событий Babylon.js необходимо разобраться в её принципах работы и механизмах.
Babylon.js использует стандартный механизм событий JavaScript,
основанный на объекте Event, но адаптирован для работы с
3D-сценами. В библиотеке имеется набор обёрток и инструментов, которые
позволяют удобно обрабатывать события взаимодействия с объектами сцены,
а также с самим холстом, на котором выводится графика.
Одним из важнейших элементов в 3D-сцене является камера. В Babylon.js камера может быть настроена на восприятие множества событий, таких как движение, вращение, масштабирование и взаимодействие с объектами сцены. Для обработки событий с камерой используется система событий, которая позволяет слушать такие действия, как:
Пример регистрации события на камеру:
scene.onPointerD own = function (evt, pickResult) {
if (pickResult.hit) {
var mesh = pickResult.pickedMesh;
console.log('Mesh clicked: ' + mesh.name);
}
};
Здесь используется событие onPointerDown, которое
срабатывает при нажатии кнопки мыши на объект сцены. В функции
обработчика доступны как сам объект, так и информация о том, был ли
объект нажат.
Сцена в Babylon.js — это центральный элемент, который управляет всеми объектами, камерами и освещением. Система событий сцены позволяет обрабатывать взаимодействие с ней в реальном времени, такие как изменение времени, добавление или удаление объектов, а также обработку кликов или касаний.
Некоторые из часто используемых событий сцены включают:
onBeforeRenderObservable — срабатывает перед каждым
кадром рендера сцены.onAfterRenderObservable — срабатывает сразу после
рендеринга сцены.onKeyboardObservable — событие для обработки нажатий
клавиш.Пример использования события для обработки нажатий клавиш:
scene.onKeyboardObservable.add(function (kbInfo) {
if (kbInfo.type === BABYLON.KeyboardEventTypes.KEYDOWN) {
switch (kbInfo.event.key) {
case 'W':
camera.position.z += 0.1;
break;
case 'S':
camera.position.z -= 0.1;
break;
}
}
});
В этом примере событие onKeyboardObservable отслеживает
нажатие клавиш и перемещает камеру вдоль оси Z, если нажаты клавиши W
или S.
Каждый объект сцены может быть подписан на различные события, такие как наведение, клик, касание и другие. Это позволяет создавать интерактивные элементы, которые реагируют на действия пользователя.
В Babylon.js для обработки взаимодействий с объектами сцены
используются методы, основанные на механизме ActionManager.
С помощью ActionManager можно назначать различные действия
на объекты при их пересечении с курсором, клике, наведении и т.д.
Пример обработки клика на объекте сцены:
var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { diameter: 1 }, scene);
sphere.actionManager = new BABYLON.ActionManager(scene);
sphere.actionManager.registerAction(new BABYLON.ExecuteCodeAction(
BABYLON.ActionManager.OnPickTrigger, function () {
console.log("Sphere clicked!");
}
));
В этом примере создаётся сфера, и на неё регистрируется событие, которое срабатывает при клике на объект. Когда пользователь нажимает на сферу, в консоль выводится сообщение.
В современных веб-приложениях, особенно на мобильных устройствах, также необходимо учитывать события касания. Babylon.js автоматически обрабатывает события касания и конвертирует их в события указателя, что позволяет использовать один и тот же механизм для обработки мыши и касания.
Для добавления обработчиков касания используются те же методы, что и для обработки событий мыши. В отличие от стандартных событий, события касания связаны с несколькими точками взаимодействия.
Пример:
scene.onPointerObservable.add(function (pointerInfo) {
if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERTAP) {
var pickedMesh = pointerInfo.pickInfo.pickedMesh;
if (pickedMesh) {
console.log('Mesh tapped: ' + pickedMesh.name);
}
}
});
Этот код будет отслеживать касания экрана и выводить информацию о том, какой объект был выбран при касании.
Кроме стандартных событий указателя и касания, Babylon.js включает
более сложные системы взаимодействия с объектами. Например, система
Picking, которая позволяет не только узнать, какой объект
был выбран, но и манипулировать его свойствами.
Для реализации более сложных интерактивных эффектов можно использовать события, связанные с курсором, такие как перемещение, захват и перемещение объектов сцены.
Пример захвата объекта и его перемещения с помощью мыши:
var pickedMesh;
scene.onPointerD own = function (evt, pickResult) {
if (pickResult.hit) {
pickedMesh = pickResult.pickedMesh;
}
};
scene.onPointerM ove = function (evt) {
if (pickedMesh) {
var pickInfo = scene.pick(evt.clientX, evt.clientY);
if (pickInfo.hit) {
pickedMesh.position = pickInfo.pickedPoint;
}
}
};
scene.onPointe rUp = function () {
pickedMesh = null;
};
В данном примере объект сцены можно захватывать и перетаскивать по экрану с помощью мыши.
Babylon.js активно использует паттерн Observable, что позволяет динамически подписываться и отписываться от различных событий. Это даёт возможность гибко управлять обработкой событий и оптимизировать производительность, подписываясь на события только в случае необходимости.
Пример использования Observable для подписки на события:
var onPointerMoveObser ver = scene.onPointerObservable.add(function (pointerInfo) {
console.log('Pointer moved to: ' + pointerInfo.event.clientX + ', ' + pointerInfo.event.clientY);
});
В данном случае событие подписано на перемещение указателя мыши по
сцене. Важно помнить, что при использовании Observables можно легко
отписаться от события, вызвав метод remove().
Babylon.js поддерживает работу с несколькими событиями одновременно, что позволяет легко создавать сложные взаимодействия. Например, можно комбинировать обработку нажатий клавиш и событий мыши для управления объектами на сцене.
Пример объединения событий клавиатуры и мыши:
scene.onKeyboardObservable.add(function (kbInfo) {
if (kbInfo.type === BABYLON.KeyboardEventTypes.KEYDOWN) {
switch (kbInfo.event.key) {
case 'A':
camera.rotation.y -= 0.1;
break;
case 'D':
camera.rotation.y += 0.1;
break;
}
}
});
scene.onPointerObservable.add(function (pointerInfo) {
if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERMOVE) {
var mesh = pointerInfo.pickInfo.pickedMesh;
if (mesh) {
mesh.rotation.x += 0.01;
}
}
});
В этом примере одновременно управляются вращение камеры с помощью клавиш и изменение угла наклона объектов на сцене с помощью мыши.
Для улучшения производительности в сложных сценах Babylon.js использует концепцию “пакетов событий”. Это позволяет минимизировать количество операций, связанных с обработкой событий, и повысить общую производительность. В частности, можно управлять частотой обновления событий и фильтровать их по типу.
Пример оптимизации:
scene.onBeforeRenderObservable.add(() => {
// Обработка только каждого третьего кадра
if (scene.frameId % 3 === 0) {
// Логика обновления
}
});
Таким образом, Babylon.js предоставляет гибкую систему событий, адаптированную под специфические нужды 3D-графики, с возможностью кастомизации и оптимизации.