В A-Frame сцена строится на основе компонентов и сущностей
(<a-entity>), что позволяет создавать сложные
3D-модели с иерархией объектов. Для работы с вложенными объектами модели
важно понимать, как обращаться к дочерним элементам через JavaScript и
как управлять их свойствами.
Каждая <a-entity> может содержать другие сущности.
Это создает иерархическую структуру, в которой
родительский объект может управлять поведением и трансформациями
дочерних элементов. Пример структуры:
<a-scene>
<a-entity id="robot" position="0 0 0">
<a-entity id="head" geometry="primitive: box" material="color: red"></a-entity>
<a-entity id="arm-left" geometry="primitive: cylinder" material="color: blue"></a-entity>
<a-entity id="arm-right" geometry="primitive: cylinder" material="color: green"></a-entity>
</a-entity>
</a-scene>
В этом примере #robot является родителем, а
#head, #arm-left и #arm-right —
дочерними объектами.
querySelectorНаиболее прямой способ доступа к вложенным объектам — использование
стандартного DOM-метода querySelector или
querySelectorAll:
const robot = document.querySelector('#robot');
const head = robot.querySelector('#head');
const leftArm = robot.querySelector('#arm-left');
Ключевой момент: поиск через
querySelector работает по вложенной
иерархии, так что можно ограничить область поиска конкретным
родителем, что особенно полезно для больших моделей.
object3DКаждая <a-entity> имеет свойство
object3D, предоставляющее доступ к объекту
Three.js, который лежит в основе A-Frame. Через
object3D можно изменять позицию, вращение и масштаб
дочерних элементов:
const headMesh = head.object3D;
headMesh.position.set(0, 1.5, 0);
headMesh.rotation.y = Math.PI / 4;
Для поиска дочерних объектов внутри object3D
используется метод getObjectByName:
const leftArmMesh = robot.object3D.getObjectByName('arm-left');
leftArmMesh.rotation.z = Math.PI / 6;
Важно: имя объекта внутри object3D
можно задать через компонент name в A-Frame:
<a-entity id="arm-left" name="arm-left" geometry="primitive: cylinder"></a-entity>
Для сложных моделей удобно создавать группы объектов, которые можно перемещать и трансформировать целиком:
<a-entity id="robot">
<a-entity id="arms" position="0 1 0">
<a-entity id="arm-left" geometry="primitive: cylinder"></a-entity>
<a-entity id="arm-right" geometry="primitive: cylinder"></a-entity>
</a-entity>
</a-entity>
Доступ к отдельной группе через Jav * aScript:
const armsGroup = document.querySelector('#arms');
armsGroup.object3D.position.y += 0.2;
Все дочерние элементы группы будут смещены синхронно, что позволяет эффективно управлять сложными объектами.
A-Frame позволяет добавлять дочерние сущности на лету с помощью Jav * aScript:
const newHand = document.createElement('a-entity');
newHand.setAttribute('geometry', 'primitive: box; height: 0.2; width: 0.5; depth: 0.2');
newHand.setAttribute('material', 'color: yellow');
const robot = document.querySelector('#robot');
robot.appendChild(newHand);
Удаление выполняется стандартным методом
removeChild:
robot.removeChild(newHand);
Эти операции могут применяться к любым вложенным объектам и группам, что делает сцену динамичной и интерактивной.
Для управления визуальными или функциональными свойствами дочерних
объектов удобно использовать методы A-Frame setAttribute и
getAttribute:
const head = document.querySelector('#head');
head.setAttribute('material', 'color', 'blue');
const armColor = leftArm.getAttribute('material').color;
console.log('Цвет левой руки:', armColor);
Особенность: изменения через
setAttribute автоматически обновляют Three.js объект и
рендеринг сцены.
При работе с импортированными моделями, например в формате GLTF,
вложенные объекты становятся частью структуры scene объекта
gltf:
const model = document.querySelector('#gltf-model');
model.addEventListener('model-loaded', () => {
const mesh = model.getObject3D('mesh');
const leftArm = mesh.getObjectByName('Arm_L'); // имя из 3D редактора
leftArm.rotation.x = Math.PI / 8;
});
Ключевой момент: для доступа к вложенным объектам
GLTF необходимо дождаться события model-loaded, иначе
объект еще не создан.
querySelector для поиска по DOM, если
структура A-Frame небольшая и удобна для навигации.object3D.name или из исходной 3D
модели облегчает поиск в object3D.appendChild и
removeChild для вложенных объектов.model-loaded для доступа к объектам.Эти методы позволяют создавать гибкие и масштабируемые сцены с полной управляемостью вложенных объектов, интегрируя сложные трансформации, анимацию и взаимодействие.