A-Frame是什么

A-Frame是Mozilla 开源 web
虚拟现实框架,他能够非常方便的创建VR视口,载入部分格式的模型,设置照相机等,这为对计算机图形学不是很了解的同学,减轻了好多负担。我分别用了threeJS和A-Frame.js做了两个小项目,全英文文档看的好累,就顺便翻译了部分文档,之后会分享threeJS与模型导出与加载的一些坑。

A-Frame让你构建场景,仅仅通过HTML ,然而对你使用JavaScript,three.js,和其他的WebAPI没有限制,A-Frame使用一个采用的是一个实体-组件-系统的模式,使得他更加 的结构化,可延展,并且他不但是开源的,免费的,并且还是一个有着受欢迎的社区和完善工具与组件的生态系统。

Begin Example

以我的webVR自主装修馆为例,如何构建出图中模型屋的场景?真的很简单

<head><title>模板文件</title><meta name="keywords" content=""><meta name="description" content=""><!--引入aframe.js  -->   <script src="static/js/bundle/aframe.js"></script>
</head>
<!--场景标签 他代表了整个场景的开始 是全局根物体,所有的实体(entity)都包含在场景里-->
<a-scene><!--<a-assets>使用资源管理系统来缓存资源,为了更好的性能,这个标签内的资源将会预加载缓存起来--> <a-assets><!--<a-asset-item>加载各种资源 比如3D模型或者材质  --> <a-asset-item id="floor-obj" src="fox.obj"></a-asset-item><!-- 加载图片  --><img src="static/img/f1.jpg" id="f1-texture" alt=""> <img src="static/img/sky_sphere.jpg" id='sky-box' alt=""><!--加载视频  --> <video id="video" src="video.mp4"></video></a-assets><!--相机  --> <a-camera fov="80"><a-cursor></a-cursor></a-camera><!--materialchange__floor 组件名,material材质与属性细节 obj-model模型obj文件    --><a-entity materialchange__floor material="src: #f1-texture;  metalness: 0.6;repeat:25;" id="floor" obj-model="obj: #floor-obj;"></a-entity><a-video src="#video"></a-video><!--天空盒  --> <a-sky color="#EEEEFF" material="src: #sky-box"></a-sky>
</a-scene>

entity-component-system

A-Frame采用实体-组件-系统模式,使用这个框架的时候,我们把灯光,模型,材质等都当做是一个实体,就是我们呈现在视觉上的主要元素,而component,组件类似vue,封装可重用的代码,为项目添加功能,从而组装成一个系统

enrity 实体

A-Frame表现一个实体通过<a-entity>元素,作为定义在entity-component-system中的一个部分,这些实体是一个占位符,让我们来插入组件,并提供他的外观,行为和功能;

在A-Frame中,实体们的本质就是附加上位置,旋转和大小的组件

Example 例子

<a-entity geometry="primitive: box" material="color: red"light="type: point; intensity: 2.0" id="mario">
var el = document.querySelector('#mario');

如例所示,我们可以绑定组件给实体,让他渲染或者做些什么,我们可以通过几何(geometry)组件和材质(material)组件定义他形状与外观,可以使用灯光组件让他发出灯光;我们可以通过DOM API轻松的得到一个实体,一旦我们拿到了这个实体,我们就能去控制他一些详细的属性和方法。

Properties 属性

components

<a-entity>.components是附加在实体上的一个组件对象,这给我们一个途径去取得这个实体的组件,包括每一个组件的数据,状态和方法;

例如,如我我们要去取得threeJS里的照相机或者材质,我们可以这么去做:

var camera = document.querySelector('a-entity[camera]').components.camera.camera;
var material = document.querySelector('a-entity[material]').components.material.material;

或者一个组件所暴露的API

document.querySelector('a-entity[sound]').components.sound.pause();

isPlaying

实体是否处于active或者playing状态,如果我们pause这个实体,那么isPlaying将处于false状态

object3D

<a-entity>.object3D is a reference to the entity’s three.js Object3D representation. More specifically, object3D will be a THREE.Group object that may contain different types of THREE.Object3Ds such as cameras, meshes, lights, or sounds:

// Gaining access to the internal three.js scene graph.
var groupObject3D = document.querySelector('a-entity').object3D;
console.log(groupObject3D.parent);
console.log(groupObject3D.children);

我们可以获得不同类型的Object3Ds通过object3DMap,

object3DMap

一个实体的object3DMap 是一个对象,这个对象给了我们一个途径去获取不同类型的THREE.object3Ds(例如,相机,材质,灯光,声音)
例如一个绑定了几何和灯光组件的实体,他的object3DMap 应该是下面这个样子


{light: <THREE.Light Object>,mesh: <THREE.Mesh Object>
}

我们可以管理实体的THREE.Object3Ds通过getOrCreateObject3D, setObject3D, and removeObject3D.这些方法

sceneEl

一个实体有对其所属场景元素的引用

var sceneEl = document.querySelector('a-scene');
var entity = sceneEl.querySelector('a-entity');
console.log(entity.sceneEl === sceneEl);  // >> true.

Methods 方法

addState (stateName) 添加状态

addState将会给这个实体添加一个状态,这个方法可以触发stateadded 事件,并且我们可以检查到是否我们处于这个状态内

entity.addEventListener('stateadded', function (evt) {if (evt.detail.state === 'selected') {console.log('Entity now selected!');}
});
entity.addState('selected');
entity.is('selected');  // >> true

emit (name, detail, bubbles) 触发事件

emit触发一个在实体上定制的DOM事件,例如,我们能够触发一个事件去触发一个动画。

// <a-entity>
//   <a-animation attribute="rotation" begin="rotate" to="0 360 0"></a-animation>
// </a-entity>
entity.emit('rotate');

我们同样能够传递事件的细节或者数据通过第二个参数

entity.emit('collide', { target: collidingEntity });

这个事件是默认冒泡的,我们可以让他不要冒泡通过设置第三个参数为false

entity.emit('sink', null, false);

flushToDOM (recursive) 刷新DOM

flushToDOM 将会手动序列化一个实体组件的数据并且更新DOM,更多详细内容见 component-to-DOM serialization.

getAttribute (componentName) 获取属性

getAttribute 检索解析组件的属性,包含混入(mixin)的和默认的

// <a-entity geometry="primitive: box; width: 3">
entity.getAttribute('geometry');
// >> {primitive: "box", depth: 2, height: 2, translate: "0 0 0", width: 3, ...}
entity.getAttribute('geometry').primitive;
// >> "box"
entity.getAttribute('geometry').height;
// >> 2
entity.getAttribute('position');
// >> {x: 0, y: 0, z: 0}

如果组件名是一个没有注册的组件,getAttribute将会正常运行

// <a-entity data-position="0 1 1">
entity.getAttribute('data-position');
// >> "0 1 1"

getDOMAttribute (componentName)

getDOMAttribute只会检索解析显式定义在DOM的属性或者通过setAttribute设置的属性,如果componentName是已经注册的组件,getDOMAttribute将只会返回定义在HTML的组件数据,以一个数组对象的形式,他是不包括混合值和默认值的

与getAttribute的输出做一个比较:

// <a-entity geometry="primitive: box; width: 3">
entity.getDOMAttribute('geometry');
// >> { primitive: "box", width: 3 }
entity.getDOMAttribute('geometry').primitive;
// >> "box"
entity.getDOMAttribute('geometry').height;
// >> undefined
entity.getDOMAttribute('position');
// >> undefined

getObject3D (type)

getObject3D looks up a child THREE.Object3D referenced by type on object3DMap.

AFRAME.registerComponent('example-mesh', {init: function () {var el = this.el;el.getOrCreateObject3D('mesh', THREE.Mesh);el.getObject3D('mesh');  // Returns THREE.Mesh that was just created.}
});

getOrCreateObject3D (type, Constructor)

If the entity does not have a THREE.Object3D registered under type, getOrCreateObject3D will register an instantiated THREE.Object3D using the passed Constructor. If the entity does have an THREE.Object3D registered under type, getOrCreateObject3D will act as getObject3D:

AFRAME.registerComponent('example-geometry', {update: function () {var mesh = this.el.getOrCreateObject3D('mesh', THREE.Mesh);mesh.geometry = new THREE.Geometry();}
});

pause ()

pause()将会停止任何动画或者组件定义的动态行为,当我们停止一个实体的时候,它将会停止他的动画,并且调取这个实体上每个组件的Component.pause(),这个组件决定了发生什么当停止的时候,常常我们会移去事件监听,一个实体被pause后,他的子实体也会被pause()

// <a-entity id="spinning-jumping-ball">
entity.pause();

play ()

play()将会开始在动画或者组件中定义的动态行为,当DOM附加上一个实体的时候,这就好自动调用他,当一个实体play(),这个实体的子实体被调用play()

entity.pause();
entity.play();

例如,当播放声音的时候,这个声音组件会调用play()

setAttribute (attr, value, componentAttrValue)

如果属性不是已经注册的组件或者是单属性组件,我们将会这样来设置属性

entity.setAttribute('visible', false);

虽然attr是注册的组件的名字,它可能需要对值做特殊的解析,例如,这个位置组件是一个单属性组件,但是他的属性解析器允许他为一个对象

entity.setAttribute('position', { x: 1, y: 2, z: 3 });

设置多属性组件数据,我们可以将注册组件的名称作为attr传递,并将属性对象作为value传递:

entity.setAttribute('light', {type: 'spot',distance: 30,intensity: 2.0
});

Updating Multi-Property Component Data 更新多属性组件数据

为了更新多属性组件的单个属性,我们可以将注册组件的名称作为attr传递,属性名作为第二个参数,并且将属性值设置为第三个参数:

// All previous properties for the material component (besides the color)  will be unaffected.
entity.setAttribute('material', 'color', 'crimson');

setObject3D (type, obj)

setObject3D will register the passed obj, a THREE.Object3D, as type under the entity’s object3DMap. A-Frame adds obj as a child of the entity’s root object3D.

AFRAME.registerComponent('example-orthogonal-camera', {
update: function () {

this.el.setObject3D('camera', new THREE.OrthogonalCamera());

}
});

removeAttribute (attr, propertyName)

如果attr是注册组件的名称,除了要从DOM中删除属性,removeAttribute还将从实体中分离组件,调用组件的删除生命周期方法。

entity.removeAttribute('goemetry');  // Detach the geometry component.
entity.removeAttribute('sound');  // Detach the sound component.

如果给定propertyName,removeAttribute将重置propertyName指定的属性的属性值为属性的默认值:

entity.setAttribute('material', 'color', 'blue');  // The color is blue.
entity.removeAttribute('material', 'color');  // Reset the color to the default value, white.

removeObject3D (type)

removeObject3D removes the object specified by type from the entity’s THREE.Group and thus from the scene. This will update the entity’s object3DMap, setting the value of the type key to null. This is generally called from a component, often within the remove handler:

AFRAME.registerComponent('example-light', {update: function () {this.el.setObject3D('light', new THREE.Light());// Light is now part of the scene.// object3DMap.light is now a THREE.Light() object.},remove: function () {this.el.removeObject3D('light');// Light is now removed from the scene.// object3DMap.light is now null.}
});

removeState (stateName)

removeState将从实体中弹出一个状态。这将会触发stateremoved事件,我们可以检查它的删除状态。

entity.addEventListener('stateremoved', function (evt) {if (evt.detail.state === 'selected') {console.log('Entity no longer selected.');}
});
entity.addState('selected');
entity.is('selected');  // >> true
entity.removeState('selected');
entity.is('selected');  // >> false

Events 事件

A-Frame.js 学习文档翻译(一)实体相关推荐

  1. html5游戏引擎-Pharse.js学习笔记(一)

    2019独角兽企业重金招聘Python工程师标准>>> 1.前言 前几天随着flappy bird这样的小游戏的火爆,使我这种也曾了解过html5技术的js业余爱好者也开始关注游戏开 ...

  2. ArcGIS JS 学习笔记4 实现地图联动

    原文:ArcGIS JS 学习笔记4 实现地图联动 1.开篇 守望屁股实在太好玩了,所以最近有点懒,这次就先写个简单的来凑一下数.这次我的模仿目标是天地图的地图联动. 天地的地图联动不仅地图有联动,而 ...

  3. backbone.js学习笔记

    backbone.js学习笔记 之前只接触过jQuery,看来Backbone是除了jQuery的第二大JS框架... backbone到底是个啥? 其实刚开始我也不知道=_=,我是这周二才听说居然还 ...

  4. 程序员的高速学习法——以JS学习为例,进行图解

    近期一直在忙着学习,感觉做总结的时间太少了,听起来挺好玩儿的,就像<倾城之恋>里面.范柳原说:那时候都忙着谈恋爱了哪里有时间恋爱.  学习和总结也是一样.不能一直忙着学习而导致自己没有时间 ...

  5. node.js学习笔记

    # node.js学习笔记标签(空格分隔): node.js---## 一 内置模块学习 ### 1. http 模块 ``` //1 导入http模块 const http =require('ht ...

  6. node.js学习笔记14—微型社交网站

    node.js学习笔记14-微型社交网站 1.功能分析 微博是以用户为中心,因此需要有注册和登录功能. 微博最核心的功能是信息的发表,这个功能包括许多方面,包括:数据库访问,前端显示等. 一个完整的微 ...

  7. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  8. 学习日报 day03 实体与标识符 变量与数据类型

    学习日报 day03 实体与标识符 变量与数据类型 https://cloud.189.cn/t/ryIZF3Rfqy2q 常见问题 导入外部java文件 如何把java源文件放入到myeclipse ...

  9. js 学习笔记(一)

    前言 网上其实已经有非常多的js学习资料了,但是每个人都有自己的基础,所以往往是有的人讲的深一点,有的人说的浅一点. 就我自身而言,想要匹配自己水平的找些资料,往往是十分的零碎,所以可能今天看到的文章 ...

最新文章

  1. 只需3行代码自动生成高性能模型,支持4项任务,亚马逊发布开源库AutoGluon
  2. tomcat+bean例子
  3. Unity3d 布娃娃系统
  4. okta使用_使用Okta的单点登录保护您的Vert.x服务器
  5. 【转】Path.Combine (合并两个路径字符串)方法的一些使用细节
  6. java 叉号关闭_求助 java 如何编写JFrame窗体右上角红色打叉关闭按钮的事件?
  7. 带你走进EJB--MDB
  8. python输出一行10个_python 如何将一系列数字十个一行输出【】
  9. 明日方舟 长夜临光side story
  10. Jsoup爬虫小案例
  11. 单片机应用系统设计技术——多功能出租车计费器
  12. 网上体育商城的设计与实现毕业设计论文
  13. Word中如何修改脚注的编号方式
  14. mysql汉字按英文字母排序
  15. python建模库介绍:pandas与建模代码的结合,使用Patsy创建模型描述
  16. html中css在哪里写,css可以在html里面写吗
  17. 一条短信致倾家荡产?手机验证码安全吗
  18. 系统集成项目管理工程师有什么用?你真的了解吗
  19. 网络编程中的SO_REUSEADDR和SO_REUSEPORT参数详解
  20. 【编译原理入门】–编译器compiler

热门文章

  1. 常考数据结构与算法-manacher算法
  2. C五:exit()函数作用的程序
  3. 通过几个问题深入分析Vue中的diff原理
  4. 邮件服务器软件EwoMail 1.05 发布
  5. Qtopia-2.2.0 的配置和交叉编译
  6. Oracle 学习笔记:Backup Recovery 常用命令
  7. 系统消息是放客户端还是服务器,系统消息是放客户端还是服务器
  8. Python 获取项目根路径
  9. 【理论】红黑树的实现原理
  10. 跟我一起学编程—《Scratch编程》第21课:打地鼠