走进网页虚拟现实WebVR
最近几年,虚拟现实VR的概念火了一把,各种VR概念的游戏、设备、视频受到人们的广泛关注。笔者在逛商场的时候也经常会看到有VR设备体验的地方让游人体验一把,各种酷炫的头盔和酷炫的设备着实抓人眼球。但是作为一个前端工作者,我们肯定也希望在我们的网页里也能看到这么酷炫的效果,不经意间在网上发现了一个网页虚拟现实框架A-Frame,分享一下笔者的使用心得。
介绍
A-Frame是Mozilla发布的一个全新的开源框架,旨在帮助开发者开发在浏览器中运行的高性能响应式的VR体验。只需要在页面中引入aFrame.min.js
就能够集成支持VR页面所需要的组件了。
优点
基于DOM
我们可以使用传统的JavaScript DOM API来操纵A-Frame场景来添加逻辑,行为和功能。同时,A-Frame是基于DOM的,现在一些流行的框架能够基于A-Frame工作,比如React、Vue、jQuery和Angular。
实体组件系统
A-Frame是一个基于three.js的实体组件系统。在A-Frame里一切都是实体,我们插入组件,可以随意撰写外观,行为和功能集成。
丰富的生态系统
A-Frame配备了多个组件,但由于A-Frame在其核心部分是完全可扩展的,社区已经为生态系统填充了许多组件,如物理,粒子系统,音频可视化和Leap Motion控件。这个生态系统是A-Frame的命脉。开发人员可以构建一个组件并发布它,然后其他人可以使用该组件并直接从HTML使用,甚至不必知道任何JavaScript。
强大的可视化检查器
可视化编辑器用于检查和编辑A框架场景的可视化工具。与浏览器的DOM检查器类似,您可以进入任何A-Frame场景,本地或Web上,然后点击ctrl+alt+i
键盘。
这将打开视觉检查器,我们可以在其中进行更改。可以在视觉上移动和放置物体,用组件的属性随意的挪动物体,或者围绕相机平移以查看场景的不同视图。
组件
介绍了这么多,让我们来看一下A-Frame是如何来构造组件的。
a-scene
一个场景是由a-scene创建的,是全景渲染的根对象,所有的元素都需要放在a-scene这个组件里。它会处理3D所需的所有设置:设置WebGL、画布、相机、灯光、渲染器、渲染循环以及开启及时的WebVR支持。
a-sky
每一个场景都需要一个背景,a-sky
标签用来设置场景的背景,可以直接放置src为全景图片,或者直接渲染color值。
1 |
|
如果直接渲染了color值,那么整个背景就会变成该颜色;如果设置全景图片,可以左右移动来查看。效果链接戳这里。
a-box
我们通过a-box
标签来生成一个长方体,有一下几个重要的属性:
- width:宽度
- height:高度
- depth:深度
- color:颜色
- position:位置
- rotation:旋转
- scale:缩放
1 |
|
最后生成一个长1高1深1颜色为红色的长方体:
a-assets
但是如果仅仅是红色的外观那么就太单调了。A-Frame允许我们给组件设置纹理图片,虽然可以直接给组件设置src属性,不过不推荐这种做法,推荐通过资源管理系统a-assets
。
一般在游戏等视觉体验丰富的场景中,由于有着大量的图片、模型、声音等资源,都会对这些资源进行一个预加载处理,确保在渲染的时候不会出现缺失的现象。
我们把这些资源放到a-assets
也是为了进行预加载。我们可以存放以下资源:
<a-asset-item>
:其他资产,如3D模型和材料<audio>
:声音文件<img>
:图像纹理<video>
:视频纹理
我们通过给资源标志一个唯一的id,然后在组件的src中引用这个id来进行调用。
1 |
|
这样我们的长方体就变成了一个带有图案纹理的长方体。
a-light
我们可以通过使用a-light来改变场景的亮度。默认情况下,如果我们没有指定任何指示灯,A-Frame将添加环境光和定向光。如果A-Frame没有为我们添加灯,场景将是黑色的。一旦我们添加了我们自己的灯,默认的照明设置将被删除,并替换为我们的设置。
我们还会添加一个点光源,点光源就像灯泡; 我们可以将它们放在场景周围,点光源对实体的影响取决于它与实体的距离。
1 |
|
我们给环境一个黄色照明的光源,最后的效果是这样的。
a-animation
我们可以使用A-Frame的内置动画系统<a-animation>
向盒子添加动画。我们可以将<a-animation>
元素作为实体的子代。让我们把盒子上下摆动来给场景添加一些动作。
1 |
|
一些属性说明:
- attribute:需要把哪个属性作为动画
- to:属性到某个值
- direction:方向,alternate表示来回
- dur:时间间隔
- repeat:重复次数
a-text
在A-Frame中还可以添加文本组件<a-text>
。
1 |
|
最后添加文字的效果,效果链接戳这里。
a-cylinder
圆筒原型是多功能的,可用于创建不同种类的形状:
1 |
|
a-cone
用于创造一个椎体。
1 |
|
使用JS和DOM
在A-Frame中也有DOM元素,通过querySelector()和querySelectorAll()方法来提供元素的遍历,查询,查找和选择。这个很像jQuery中的选择器。
querySelector
如果我们想抓住一个元素,我们使用querySelector()返回那一个元素。比如我们来抓住场景元素:
1 |
|
如果元素具有ID,则可以使用ID选择器(即,#
1 |
|
querySelectorAll
如果我们要抓取一组元素,我们使用querySelector()哪个返回一个元素数组。我们可以查询元素名称、类名、属性名:
1 |
|
如果我们抓住了一组使用的实体querySelectorAll(),我们可以循环使用它们for。我们围绕场景中的每个元素循环遍历。
1 |
|
createElement
要创建一个实体,我们可以使用document.createElement。这将给我们一个空白的实体:
1 |
|
但是,在将实体附加到我们的场景之前,该实体将不会被初始化或者成为场景的一部分。
appendChild
要向DOM添加实体,我们可以使用.appendChild(element)。具体来说,我们想把它添加到我们的场景中。我们抓住现场,创建实体,并将实体附加到我们的场景。
1 |
|
请注意,这appendChild()方法是浏览器中的异步操作。在实体完成附加到DOM之前,我们不能对实体执行许多操作(如调用.getAttribute())。如果我们需要查询刚被追加的实体上的一个属性,我们可以监听loaded该实体上的事件,或者将逻辑放在A-Frame组件中,以便一旦它被准备好就执行:
removeChild
要从DOM中移除实体,因此从场景中删除一个实体,我们removeChild(element)从父元素调用。如果我们有一个实体,我们必须要用它的parent(parentNode)去除实体。
1 |
|
setAttribute
要更新组件,我们可以使用setAttribute()方法。更新组件需要几种形式。如果组件是单属性组件,则setAttribute其行为与通常情况相同:
1 |
|
但是如果是单属性,它可以处理该值的特殊解析。例如,position组件是单属性组件,但其属性类型解析器允许它占用一个对象:
1 |
|
要设置或替换多属性组件的组件数据,我们可以传递注册组件的属性名称,并将属性对象传递为value:
1 |
|
removeAttribute
从DOM中删除属性或者分离组件,调用组件的remove生命周期方法。
1 |
|
本网所有内容文字和图片,版权均属谢小飞所有,任何媒体、网站或个人未经本网协议授权不得转载、链接、转贴或以其他方式复制发布/发表。如需转载请关注公众号【前端壹读】后回复【转载】。