A-Frame.js 学习&文档翻译(一)实体

A-Frame是什么

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

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

Begin Example

A-Frame.js 学习&文档翻译(一)实体_第1张图片

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


    模板文件
    
    
       
    

 

   
  
     
    
    
     
    
     
    
  
    
  
  
  
  
   
  

entity-component-system

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

enrity 实体

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

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

Example 例子

var el = document.querySelector('#mario');

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

Properties 属性

components

.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

.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: ,
  mesh: 
}

我们可以管理实体的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事件,例如,我们能够触发一个事件去触发一个动画。

// 
//   
// 
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)的和默认的

// 
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将会正常运行

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

getDOMAttribute (componentName)

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

与getAttribute的输出做一个比较:

// 
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()

// 
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 学习&文档翻译(一)实体_第2张图片

你可能感兴趣的:(three.js,webgl)