A-Frame использует компонентно-ориентированную архитектуру, где события являются ключевым механизмом взаимодействия между сущностями и компонентами. Каждый компонент может отправлять, слушать и обрабатывать события, что позволяет создавать сложные интерактивные сцены без жесткой зависимости между объектами.
В A-Frame сущность (<a-entity>) —
это контейнер для компонентов. События могут быть двух типов:
click, mouseenter, mouseleave и
т.д.), которые A-Frame расширяет для работы с 3D-сценой.hit, spawn, activated
и др.).Каждое событие имеет имя и может содержать объект
detail с произвольными данными.
<a-entity id="box" geometry="primitive: box" material="color: red"></a-entity>
<script>
const box = document.querySelector('#box');
box.addEventListener('click', event => {
console.log('Событие click на кубе', event);
});
box.addEventListener('custom-event', event => {
console.log('Пользовательское событие:', event.detail);
});
box.emit('custom-event', { info: 'Данные события' });
</script>
В примере выше emit используется для генерации
пользовательского события с объектом detail. Событие может
быть перехвачено любым компонентом или сущностью в иерархии сцены.
Компоненты A-Frame позволяют подписываться на события прямо внутри
объекта init или других методов жизненного цикла.
AFRAME.registerComponent('interactive-box', {
init: function () {
this.el.addEventListener('mouseenter', () => {
this.el.setAttribute('material', 'color', 'green');
});
this.el.addEventListener('mouseleave', () => {
this.el.setAttribute('material', 'color', 'red');
});
this.el.addEventListener('activate', e => {
console.log('Событие activate с данными:', e.detail);
});
}
});
Ключевые моменты:
this.el всегда ссылается на сущность,
к которой прикреплён компонент.addEventListener и
removeEventListener позволяют динамически управлять
подпиской на события.emit.A-Frame поддерживает всплытие событий, аналогично DOM-модели:
bubbles: true при
вызове emit.childEl.emit('jump', { height: 2 }, true); // true включает всплытие
parentEl.addEventListener('jump', e => {
console.log('Родительская сущность перехватила событие', e.detail);
});
События можно использовать для синхронизации состояния компонентов:
init — инициализация компонента. События могут
подписываться здесь.update — вызывается при изменении атрибутов компонента.
Можно отправлять события об изменении состояния.remove — отписка от событий при удалении компонента,
чтобы избежать утечек памяти.AFRAME.registerComponent('color-changer', {
init: function () {
this.onCl ick = () => this.el.setAttribute('material', 'color', 'blue');
this.el.addEventListener('click', this.onClick);
},
remove: function () {
this.el.removeEventListener('click', this.onClick);
}
});
detailОбъект detail — основной способ передачи данных в
событиях. Он может содержать любые структуры: числа, строки,
объекты.
el.emit('health-changed', { current: 80, max: 100 });
el.addEventListener('health-changed', e => {
console.log(`Здоровье: ${e.detail.current} / ${e.detail.max}`);
});
Это делает события мощным инструментом для связки компонентов, например, для систем здоровья, очков или состояния объектов сцены.
open-door,
explode.Правильная организация событий позволяет строить сцены с минимальной жесткой связью между сущностями, что повышает масштабируемость и повторное использование компонентов.
enemy-hit, item-collected).detail.remove или при завершении
действия компонента.Эта событийная модель обеспечивает гибкость и контроль над интерактивностью, позволяя создавать сложные VR-сцены с A-Frame, где каждый компонент может автономно реагировать и инициировать действия.