A-Frame 快速入门


本篇基于A-Frame官方文档1.4.0编写。官方文档跳转


环境搭建

1. 使用node+vite建立可热重载的开发环境

创建vite项目,详见 搭建第一个 Vite 项目

1
npm create vite@latest

进入项目内安装依赖(package.json)

1
npm install

2. 使用cdn引入aframe.js

在index.html中引入aframe.js

1
2
3
4

<head>
<script src="https://aframe.io/releases/1.4.0/aframe.min.js"></script>
</head>

3. 复制运行示例代码

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<script src="https://aframe.io/releases/1.4.0/aframe.min.js"></script>
<title>A-Frame-test-area</title>
</head>
<body>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>

代码处于此处,有修改

执行命令运行项目

1
npm run dev

在浏览器中打开默认端口5173,即可看到效果

img.png

基本场景建立

<a-scene>是A-Frame的根标签,用来容纳所有的实体。同时为3D场景提供了一些基本的配置。

<a-scene> handles all of the setup that is required for 3D: setting up WebGL, the canvas, camera, lights, renderer,
render loop as well as out of the box WebVR support on platforms such as HTC Vive, Oculus Rift, Samsung GearVR, and
smartphones (Google Cardboard).

实体(Entity)

1. 基本体(Primitive)

基本体是A-Frame中的基本元素,可以通过<a-box><a-sphere><a-cylinder><a-plane>等标签创建。
其用法与HTML标签用法相同。可以在其中添加属性,如positionrotationcolor等。

1
2

<a-box color="red"></a-box>

2.

<a-entity>是A-Frame中的通用实体,可以用来创建自定义的实体。
例如上述的a-box基本体,可以通过如下<a-entity>标签创建。

1
2

<a-entity id="box" geometry="primitive: box" material="color: red"></a-entity>

变形(Transforming)

A-Frame 使用右手直角坐标系,其中X轴指向右侧,Y轴指向上方,Z轴指向屏幕外方向(我们)。
img_1.png
A-Frame 的距离单位是米(meters),角度单位是度(degree)

关于角度的判别:

To determine the positive direction of rotation, use the right-hand rule. Point our thumbs down the direction of a
positive axis, and the direction which our fingers curl around the positive direction of rotation.

至此,我们可以通过更改标签的positionrotationscale属性来改变实体的位置、旋转、缩放。

1
2

<a-box color="red" rotation="0 45 45" scale="2 2 2"></a-box>

变形的继承(Parent and Child Transforms)

通过html标签,我们可以实现实体的单继承

1
2
3
4
5
6

<a-scene>
<a-box position="0 2 0" rotation="0 45 45" scale="2 4 2">
<a-sphere position="1 0 3"></a-sphere>
</a-box>
</a-scene>

这个例子中球体作为了盒子的子实体。
球的绝对位置(world position)通过结合自身和父位的position属性计算,本例为1 2 3
相似的对于旋转和缩放,球体将继承父位的旋转和缩放。
如果复位的属性发生改变,子实体的绝对位置也会立即发生改变。

DOM操作

以下操作在浏览器开发者工具中控制台进行
本段实例代码如下

1
2
3
4
5
6
7
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere id=0 class="test" position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder id=1 class="test" position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>

1. 获取实体

使用.querySelector()方法获取一个实体

1
2
var sceneEl = document.querySelector('a-scene');
console.log(sceneEl);

使用.querySelectorAll()方法获取多个实体

1
2
var entities = document.querySelectorAll('a-entity');
console.log(entities);

标签选择、类选择、id选择、属性选择等方法如下

1
2
3
4
5
6
var sceneEl = document.querySelector('a-scene');
var el1 = sceneEl.querySelector('a-box');
var el2 = sceneEl.querySelector('.test');
var el3 = sceneEl.querySelector('#column');
var el4 = sceneEl.querySelector('[color="#4CC3D9"]');
console.log([el1, el2, el3, el4]);

(4) [a-box, a-sphere#ball.test, a-cylinder#column.test, a-box]

2. 获取实体的属性

使用.getAttribute()方法获取实体的属性

1
2
var el = document.querySelector('a-box');
console.log(el.getAttribute('color'));

#4CC3D9

3. 设置实体的属性

使用.setAttribute()方法设置实体的属性

1
2
var el = document.querySelector('a-box');
el.setAttribute('color', '#FFC65D');

事件与组件写法

组件基本写法及使用

components/helloworld.js中写入如下代码以创建组件

1
2
3
4
5
AFRAME.registerComponent('helloworld', {
init: function () {
console.log('Hello, World!');
}
});

index.html中引入插件

1
2
3
4

<head>
<script src="components/helloworld.js"></script>
</head>

至此我们可以向任意实体添加helloworld组件

1
2
3
4

<a-scene>
<a-box position="-1 0.5 -3" ... helloworld></a-box>
</a-scene>

或者通过js代码添加组件

1
2
var ball = document.querySelector('#ball');
ball.setAttribute('helloworld', '');

通过js移除组件

1
ball.removeAttribute('helloworld');

事件

插件架构 Schema

Schema定义了插件的属性。包含了名称类型和默认值。

The schema defines the properties of its component. As an analogy, if we think of a component as a function, then a
component’s properties are like its function arguments. A property has a name (if the component has more than one
property), a default value, and a property type. Property types define how data is parsed if its passed as a string (
i.e., from the DOM).

1
2
3
4
5
6
7
8
9
AFRAME.registerComponent('testschema', {
schema: {
message: {type: 'string', default: 'Aba...Aba.Aba..'},
input: {type: 'string', default: 'none'}
},
init: function () {
console.log(this.data.message + '+' + this.data.input);
}
});

测试:

1
2
3
4
var ball = document.querySelector('#ball');
var box = document.querySelector('a-box');
ball.setAttribute('testschema', 'input:1234');
box.setAttribute('testschema', 'message:hello;input:world');

输出:

1
2
Aba...Aba.Aba..+1234
hello+world

插件生命周期