Система событий браузера и обёртки Babylon.js

Система событий в 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;
};

В данном примере объект сцены можно захватывать и перетаскивать по экрану с помощью мыши.

Управление событиями с помощью Observables

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-графики, с возможностью кастомизации и оптимизации.