THREE.JS入门教程(5)你应当知道的十件事


Posted in Javascript onJanuary 24, 2013

Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D。但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习。
0.简介
嗨,这是我的第一篇关于如何写出好的代码的文章。和很多开发者一样,我通过实践学习,但同时我也向其他更有经验的开发者们学习。在过去的几个月中,我在canvas标签上花了很多时间,我想如果把这段时间学到的关于WebGL和JavaScript的小技巧都写下来,一定很有意思。有一些很具体,有一些却很笼统,希望你们喜欢!
1.尽快写一个原型
让我们从简单的开始。现在你有个绝妙的注意,那么你应该尽快就程序里最复杂的部分写一个原型,看看这项技术是否可以实现你的想法。WebGL很强大,因为它可以直接操纵显卡里的GPU,但是也别忘了你需要通过JavaScript才能访问显卡,这比显卡内部运算的效率可是低多了。事实上,你的天才想法很可能被这种简单事情击败。
2.使用THREE.JS处理3D
就像我的朋友Hakim一样,我也完全理解我们正使用的技术的底层细节。理解表面之下的东西是很重要的,但是如果你使用three.js,它为你免去了如此多的烦恼。你可以将它用于Canvas,WebGL还有SVG,你也应该找到哪种方式合适你的需求。
3.避免SetInterval
这对所有使用JavaScript创建动画的人来说,都是很重要的一点。为什么?假定你设定每20毫秒后执行一次某个函数,而这个函数需要执行超过20毫秒的时间,那么20ms之后,浏览器不会在乎,而是直接开始下一次执行。至少你可以使用SetTimeout来设置,在某个函数执行完之后,再次执行它。

事实上,有一个更加新潮却还是半成品的函数,叫做requestAnimationFrame,它很棒。它很类似于setTimeOut函数,除了在这两个方面:当标签页失去焦点时,它就不再运行了;现在这个函数还是依赖于浏览器的,标准以后还有可能变化。如果你想要更多的信息,可以访问Paul Irish的博客。
4.使用倒序循环
这是个不错的小技巧,可以让你的循环更快。使用倒序,而且使用while循环。比如,这个循环:

for(var a = 0; a < arr.length; a++) { 
// 做一些什么 
}

它的执行效率不如下面这个循环:
// 假设数组arr存在 
var aLength = arr.length; 
while(aLength--) { 
// 做一些什么 
}

这可能没帮你省多少开销,因为执行的效率主要还是依赖于你在循环体里面干了什么。但如果你想程序的不必要开销减少到最后一个字节,后一个循环肯定赢。

实话说,主要影响程序执行效率的还是数组缓存的长度。你可以(也确实应该)去看看JSPerf去了解这一点,以及其他影响JavaScript性能的因素。
5.使用纹理
在WebGL里面把物体的任意一个细节都画出来看上去很诱人,但是,如果有可能的话,你应当注意一下你是否能够使用纹理,因为它能够极大地提高性能。在某些特定的情况下,比如阴影或者模糊效果,你也许不得不使用纹理,但在其他时候,你也应该时时关注你是否可以使用纹理。
6.使用缓存
这一点我在自己的试验力试了很多,在帧循环中,你应当避免引用变量、对象或者其他任何东西。基于这点原因,很值得把你的模型、顶点全部缓存起来,这样在渲染动画的时候你就可以快速地访问到它们。
7.禁用选中
我爱这一小段代码,我把它放到任何包含Canvas或WebGL的页面中。

// 禁用鼠标选中DOM元素 
document.onselectstart = function() { 
return false; 
};

你也可能只想在Canvas控件中禁用选中。这段是我在那些Canvas占据了整个屏幕的项目中使用的代码。
8.避免在JavaScript中定义CSS
现在,在JavaScript中定义CSS简直太方便了,尤其是你使用JQuery的时候
// 尽量不要这样做 
$("#someid").css({ 
position: 'relative', 
height: '30px', 
width: '300px', 
backgroundColor: '#A020F0' 
});

问题是这样做之后,你的JavaScript代码中很快就充斥着各种类型的CSS定义,而你同时又使用*.css文件来定义CSS,潜在的问题很难被发现。更好的方法是:使用class模块化CSS,而且只在JavaScript中定义那些不能预知的CSS类。
9.在对象中定义回调函数
我爱下面这段代码,这绝不是我自己想出来的,但它是如此整洁美观。如果你有一大堆回调函数要用,你也许会这样用的:
$("#someid").click(function() { 
// 回调函数 
// 返回false在JQuery中会阻止消息的传递和默认行为的放生 
return false; 
});

或者,你会回调一个在代码其他地方定义的松散的函数,比如这样
$("#someid").click(mySuperFunction); 
function mySuperFunction(event) { 
// 在这里做很多事情 
return false; 
}

这样做会有一些问题。第一段代码中,你在某个事件上绑定了匿名函数,你很难将该函数再从事件上解除下来。你当然可以解除某个事件上的所有函数,但你可能在它上面绑定了多个函数,而你只想解除一个。在第二种情况下,你的函数名污染了全局变量空间,代码的可维护性降低了。所以,考虑这样做:
$("#someid").click(callbacks.mySuperFunction); 
// 所有的回调函数都在callbacks对象中 
var callbacks = { 
mySuperFunction:function(event) { 
// 更多地工作 
return false; 
} 
} 
// 解除某个函数的绑定 
$("#someid").unbind('click', callbacks.mySuperFunction);

这样做整洁又干净,而且避免了上面提到的两个问题。
10.链式三元运算符
我完全是从Paul Irish的《JQuery,你应该知道的11件事》中学到这个的。这非常好用,你也应该会喜欢。我们经常这样做:
// 根据a的值为numberBasedOnA赋值 
// 如果a大于5,则赋值200,否则赋值38 
var numberBasedOnA = a > 5 ? 200 : 38;

但如果你想这样做,比如,当值为多少时如何,当值大于多少时如何,当值更加大的时候如何,明白吗?在这种情况下,链式三元运算符非常好用:
var numberBasedOnA = 
a < 5 ? 200 : 
a < 7 ? 38 : 
a < 11 ? 15 : 
a < 15 ? 49 : 
64; 
// 比这样做更有效率 
// when a >=15
Javascript 相关文章推荐
JavaScript 脚本将当地时间转换成其它时区
Mar 19 Javascript
jQuery技巧大放送 学习jquery的朋友可以看下
Oct 14 Javascript
JQuery最佳实践之精妙的自定义事件
Aug 11 Javascript
myFocus slide3D v1.1.0 使用方法与下载
Jan 12 Javascript
Node.js 的异步 IO 性能探讨
Oct 08 Javascript
jquery动态添加删除(tr/td)
Feb 09 Javascript
AngularJS教程之MVC体系结构详解
Aug 16 Javascript
jQuery输入框密码的显示隐藏【代码分享】
Apr 29 jQuery
es6 super关键字的理解与应用实例分析
Feb 15 Javascript
toString.call()通用的判断数据类型方法示例
Aug 28 Javascript
js获取图片的base64编码并压缩
Dec 05 Javascript
vue 在服务器端直接修改请求的接口地址
Dec 19 Vue.js
THREE.JS入门教程(4)创建粒子系统
Jan 24 #Javascript
THREE.JS入门教程(3)着色器-下
Jan 24 #Javascript
THREE.JS入门教程(2)着色器-上
Jan 24 #Javascript
THREE.JS入门教程(1)THREE.JS使用前了解
Jan 24 #Javascript
(跨浏览器基础事件/浏览器检测/判断浏览器)经验代码分享
Jan 24 #Javascript
jQuery ajax(复习)—Baidu ajax request分离版
Jan 24 #Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
Jan 23 #Javascript
You might like
基于PHP服务端图片生成缩略图的方法详解
2013/06/20 PHP
在PHP中输出JS语句以及乱码问题的解决方案
2019/02/13 PHP
基于node.js的快速开发透明代理
2010/12/25 Javascript
基于jquery实现的移入页面上空文本框时,让它变为焦点,移出清除焦点
2011/07/26 Javascript
解析ScrollPic在ie8下只滚动一遍,然后变为空白 ie6,ie7,chrome,firefox正常
2013/06/26 Javascript
jquery垂直公告滚动实现代码
2013/12/08 Javascript
在百度知道团队中快速审批新成员的js脚本
2014/02/02 Javascript
封装好的javascript前端分页插件pagination
2016/01/04 Javascript
简单讲解jQuery中的子元素过滤选择器
2016/04/18 Javascript
JavaScript 保护变量不被随意修改的实现代码
2017/09/27 Javascript
JavaScript 数组去重并统计重复元素出现的次数实例
2017/12/14 Javascript
jq.ajax+php+mysql实现关键字模糊查询(示例讲解)
2018/01/02 Javascript
基于vue实现网站前台的权限管理(前后端分离实践)
2018/01/13 Javascript
解决Vue不能检测数组或对象变动的问题
2018/02/24 Javascript
Node.js中的cluster模块深入解读
2018/06/11 Javascript
echarts实现折线图的拖拽效果
2019/12/19 Javascript
原生javascript的ajax请求及后台PHP响应操作示例
2020/02/24 Javascript
解决VUEX的mapState/...mapState等取值问题
2020/07/24 Javascript
[02:44]DOTA2英雄基础教程 钢背兽
2013/12/19 DOTA
pyqt4教程之实现半透明的天气预报界面示例
2014/03/02 Python
在Python程序中操作文件之isatty()方法的使用教程
2015/05/24 Python
PyQt5多线程刷新界面防假死示例
2019/12/13 Python
Python动态导入模块:__import__、importlib、动态导入的使用场景实例分析
2020/03/30 Python
python使用hdfs3模块对hdfs进行操作详解
2020/06/06 Python
Django静态文件加载失败解决方案
2020/08/26 Python
Python文件名匹配与文件复制的实现
2020/12/11 Python
美国女性运动零售品牌:Lady Foot Locker
2017/05/12 全球购物
美国折扣宠物药房:Total Pet Supply
2018/05/27 全球购物
英国儿童设计师服装和玩具购物网站:Zac & Lulu
2020/10/19 全球购物
Android面试宝典
2013/08/06 面试题
广州迈达威.net面试题目
2012/03/10 面试题
深圳茁壮笔试题
2015/05/28 面试题
幼儿园教师培训制度
2014/01/16 职场文书
决心书范文
2014/03/11 职场文书
消防标语大全
2014/06/07 职场文书
使用 Apache Dubbo 实现远程通信(微服务架构)
2022/02/12 Servers