В A-Frame каждый компонент работает в контексте
сущности (entity) и сцены (scene). Понимание
того, как получать доступ к этим объектам, критично для создания
интерактивных и динамических VR-приложений.
entity) и контекст компонентаКаждый компонент в A-Frame привязан к конкретной сущности. Ссылка на
эту сущность доступна через свойство this.el.
Пример:
AFRAME.registerComponent('log-position', {
init: function () {
console.log('Сущность:', this.el);
console.log('Позиция:', this.el.getAttribute('position'));
}
});
Здесь this.el возвращает DOM-элемент
сущности, к которой привязан компонент. С помощью методов
getAttribute и setAttribute можно
читать и изменять свойства сущности, такие как позиция,
вращение, масштаб, материалы и другие атрибуты.
Компоненты могут взаимодействовать друг с другом,
получая доступ к другим компонентам той же сущности через
this.el.components.
Пример:
AFRAME.registerComponent('sync-scale', {
init: function () {
const materialComp = this.el.components.material;
if (materialComp) {
console.log('Цвет материала:', materialComp.color);
}
}
});
Важный момент: доступ к компоненту через
this.el.components.<componentName> возможен только
после того, как компонент был инициализирован. Для гарантии правильного
порядка используется событие loaded:
this.el.addEventListener('loaded', () => {
const geometryComp = this.el.components.geometry;
console.log('Тип геометрии:', geometryComp.data.primitive);
});
Сцена в A-Frame представлена элементом <a-scene> и
является корневым контейнером всех сущностей. Доступ к
сцене из компонента осуществляется через свойство
this.el.sceneEl.
Пример:
AFRAME.registerComponent('scene-info', {
init: function () {
console.log('Сцена:', this.el.sceneEl);
console.log('Количество сущностей в сцене:', this.el.sceneEl.children.length);
}
});
С помощью this.el.sceneEl можно:
id или
class:const otherEntity = this.el.sceneEl.querySelector('#box1');
const box = document.createElement('a-box');
box.setAttribute('position', { x: 0, y: 1, z: -3 });
this.el.sceneEl.appendChild(box);
this.el.sceneEl.addEventListener('enter-vr', () => {
console.log('Пользователь вошёл в VR');
});
Помимо стандартного querySelector, A-Frame предоставляет
утилиты:
this.el.sceneEl.querySelectorAll('[component-name]') —
выбор всех сущностей с указанным компонентом.AFRAME.scenes[0] — доступ к первой сцене на странице
(полезно при мультисценовых приложениях).Пример динамического взаимодействия:
AFRAME.registerComponent('highlight-targets', {
init: function () {
const targets = this.el.sceneEl.querySelectorAll('.target');
targets.forEach(target => {
target.setAttribute('material', 'color', 'yellow');
});
}
});
Компоненты могут изменять атрибуты сущности напрямую:
this.el.setAttribute('position', { x: 2, y: 3, z: -5 });
this.el.setAttribute('rotation', { x: 0, y: 45, z: 0 });
А также использовать tick для постоянного обновления
состояния:
AFRAME.registerComponent('rotate-continuous', {
tick: function (time, timeDelta) {
const rotation = this.el.getAttribute('rotation');
this.el.setAttribute('rotation', {
x: rotation.x,
y: rotation.y + timeDelta * 0.05,
z: rotation.z
});
}
});
Многие действия в A-Frame происходят после полной загрузки сцены или
ресурсов. Для надежного доступа к сущности или сцене используется
событие loaded:
this.el.addEventListener('loaded', () => {
const scene = this.el.sceneEl;
console.log('Сцена загружена, готово к манипуляции');
});
Аналогично можно использовать события компонентов, например
model-loaded для <a-entity> с
3D-моделью.
this.el — доступ к текущей сущности компонента.this.el.sceneEl — доступ к сцене.this.el.components — доступ к другим компонентам той же
сущности.querySelector и querySelectorAll — поиск
других сущностей в сцене.loaded гарантирует, что все элементы и
компоненты уже доступны.Эти инструменты позволяют строить динамичные, интерактивные VR-сцены, где компоненты не ограничиваются собственными данными, а могут управлять всей сценой и взаимодействовать с другими сущностями.