THREE.JS入門教程(5)你應(yīng)當(dāng)知道的十件事
更新時間:2013年01月24日 11:06:33 作者:
Three.js是一個偉大的開源WebGL庫,WebGL允許JavaScript操作GPU,在瀏覽器端實現(xiàn)真正意義的3D,本文會讓你了解一下使用THREE.JS處理3D/避免SetInterval/使用倒序循環(huán)等等,感興趣的朋友可以了解下哦
Three.js是一個偉大的開源WebGL庫,WebGL允許JavaScript操作GPU,在瀏覽器端實現(xiàn)真正意義的3D。但是目前這項技術(shù)還處在發(fā)展階段,資料極為匱乏,愛好者學(xué)習(xí)基本要通過Demo源碼和Three.js本身的源碼來學(xué)習(xí)。
0.簡介
嗨,這是我的第一篇關(guān)于如何寫出好的代碼的文章。和很多開發(fā)者一樣,我通過實踐學(xué)習(xí),但同時我也向其他更有經(jīng)驗的開發(fā)者們學(xué)習(xí)。在過去的幾個月中,我在canvas標(biāo)簽上花了很多時間,我想如果把這段時間學(xué)到的關(guān)于WebGL和JavaScript的小技巧都寫下來,一定很有意思。有一些很具體,有一些卻很籠統(tǒng),希望你們喜歡!
1.盡快寫一個原型
讓我們從簡單的開始?,F(xiàn)在你有個絕妙的注意,那么你應(yīng)該盡快就程序里最復(fù)雜的部分寫一個原型,看看這項技術(shù)是否可以實現(xiàn)你的想法。WebGL很強大,因為它可以直接操縱顯卡里的GPU,但是也別忘了你需要通過JavaScript才能訪問顯卡,這比顯卡內(nèi)部運算的效率可是低多了。事實上,你的天才想法很可能被這種簡單事情擊敗。
2.使用THREE.JS處理3D
就像我的朋友Hakim一樣,我也完全理解我們正使用的技術(shù)的底層細節(jié)。理解表面之下的東西是很重要的,但是如果你使用three.js,它為你免去了如此多的煩惱。你可以將它用于Canvas,WebGL還有SVG,你也應(yīng)該找到哪種方式合適你的需求。
3.避免SetInterval
這對所有使用JavaScript創(chuàng)建動畫的人來說,都是很重要的一點。為什么?假定你設(shè)定每20毫秒后執(zhí)行一次某個函數(shù),而這個函數(shù)需要執(zhí)行超過20毫秒的時間,那么20ms之后,瀏覽器不會在乎,而是直接開始下一次執(zhí)行。至少你可以使用SetTimeout來設(shè)置,在某個函數(shù)執(zhí)行完之后,再次執(zhí)行它。
事實上,有一個更加新潮卻還是半成品的函數(shù),叫做requestAnimationFrame,它很棒。它很類似于setTimeOut函數(shù),除了在這兩個方面:當(dāng)標(biāo)簽頁失去焦點時,它就不再運行了;現(xiàn)在這個函數(shù)還是依賴于瀏覽器的,標(biāo)準(zhǔn)以后還有可能變化。如果你想要更多的信息,可以訪問Paul Irish的博客。
4.使用倒序循環(huán)
這是個不錯的小技巧,可以讓你的循環(huán)更快。使用倒序,而且使用while循環(huán)。比如,這個循環(huán):
for(var a = 0; a < arr.length; a++) {
// 做一些什么
}
它的執(zhí)行效率不如下面這個循環(huán):
// 假設(shè)數(shù)組arr存在
var aLength = arr.length;
while(aLength--) {
// 做一些什么
}
這可能沒幫你省多少開銷,因為執(zhí)行的效率主要還是依賴于你在循環(huán)體里面干了什么。但如果你想程序的不必要開銷減少到最后一個字節(jié),后一個循環(huán)肯定贏。
實話說,主要影響程序執(zhí)行效率的還是數(shù)組緩存的長度。你可以(也確實應(yīng)該)去看看JSPerf去了解這一點,以及其他影響JavaScript性能的因素。
5.使用紋理
在WebGL里面把物體的任意一個細節(jié)都畫出來看上去很誘人,但是,如果有可能的話,你應(yīng)當(dāng)注意一下你是否能夠使用紋理,因為它能夠極大地提高性能。在某些特定的情況下,比如陰影或者模糊效果,你也許不得不使用紋理,但在其他時候,你也應(yīng)該時時關(guān)注你是否可以使用紋理。
6.使用緩存
這一點我在自己的試驗力試了很多,在幀循環(huán)中,你應(yīng)當(dāng)避免引用變量、對象或者其他任何東西?;谶@點原因,很值得把你的模型、頂點全部緩存起來,這樣在渲染動畫的時候你就可以快速地訪問到它們。
7.禁用選中
我愛這一小段代碼,我把它放到任何包含Canvas或WebGL的頁面中。
// 禁用鼠標(biāo)選中DOM元素
document.onselectstart = function() {
return false;
};
你也可能只想在Canvas控件中禁用選中。這段是我在那些Canvas占據(jù)了整個屏幕的項目中使用的代碼。
8.避免在JavaScript中定義CSS
現(xiàn)在,在JavaScript中定義CSS簡直太方便了,尤其是你使用JQuery的時候
// 盡量不要這樣做
$("#someid").css({
position: 'relative',
height: '30px',
width: '300px',
backgroundColor: '#A020F0'
});
問題是這樣做之后,你的JavaScript代碼中很快就充斥著各種類型的CSS定義,而你同時又使用*.css文件來定義CSS,潛在的問題很難被發(fā)現(xiàn)。更好的方法是:使用class模塊化CSS,而且只在JavaScript中定義那些不能預(yù)知的CSS類。
9.在對象中定義回調(diào)函數(shù)
我愛下面這段代碼,這絕不是我自己想出來的,但它是如此整潔美觀。如果你有一大堆回調(diào)函數(shù)要用,你也許會這樣用的:
$("#someid").click(function() {
// 回調(diào)函數(shù)
// 返回false在JQuery中會阻止消息的傳遞和默認(rèn)行為的放生
return false;
});
或者,你會回調(diào)一個在代碼其他地方定義的松散的函數(shù),比如這樣
$("#someid").click(mySuperFunction);
function mySuperFunction(event) {
// 在這里做很多事情
return false;
}
這樣做會有一些問題。第一段代碼中,你在某個事件上綁定了匿名函數(shù),你很難將該函數(shù)再從事件上解除下來。你當(dāng)然可以解除某個事件上的所有函數(shù),但你可能在它上面綁定了多個函數(shù),而你只想解除一個。在第二種情況下,你的函數(shù)名污染了全局變量空間,代碼的可維護性降低了。所以,考慮這樣做:
$("#someid").click(callbacks.mySuperFunction);
// 所有的回調(diào)函數(shù)都在callbacks對象中
var callbacks = {
mySuperFunction:function(event) {
// 更多地工作
return false;
}
}
// 解除某個函數(shù)的綁定
$("#someid").unbind('click', callbacks.mySuperFunction);
這樣做整潔又干凈,而且避免了上面提到的兩個問題。
10.鏈?zhǔn)饺\算符
我完全是從Paul Irish的《JQuery,你應(yīng)該知道的11件事》中學(xué)到這個的。這非常好用,你也應(yīng)該會喜歡。我們經(jīng)常這樣做:
// 根據(jù)a的值為numberBasedOnA賦值
// 如果a大于5,則賦值200,否則賦值38
var numberBasedOnA = a > 5 ? 200 : 38;
但如果你想這樣做,比如,當(dāng)值為多少時如何,當(dāng)值大于多少時如何,當(dāng)值更加大的時候如何,明白嗎?在這種情況下,鏈?zhǔn)饺\算符非常好用:
var numberBasedOnA =
a < 5 ? 200 :
a < 7 ? 38 :
a < 11 ? 15 :
a < 15 ? 49 :
64;
// 比這樣做更有效率
// when a >=15
0.簡介
嗨,這是我的第一篇關(guān)于如何寫出好的代碼的文章。和很多開發(fā)者一樣,我通過實踐學(xué)習(xí),但同時我也向其他更有經(jīng)驗的開發(fā)者們學(xué)習(xí)。在過去的幾個月中,我在canvas標(biāo)簽上花了很多時間,我想如果把這段時間學(xué)到的關(guān)于WebGL和JavaScript的小技巧都寫下來,一定很有意思。有一些很具體,有一些卻很籠統(tǒng),希望你們喜歡!
1.盡快寫一個原型
讓我們從簡單的開始?,F(xiàn)在你有個絕妙的注意,那么你應(yīng)該盡快就程序里最復(fù)雜的部分寫一個原型,看看這項技術(shù)是否可以實現(xiàn)你的想法。WebGL很強大,因為它可以直接操縱顯卡里的GPU,但是也別忘了你需要通過JavaScript才能訪問顯卡,這比顯卡內(nèi)部運算的效率可是低多了。事實上,你的天才想法很可能被這種簡單事情擊敗。
2.使用THREE.JS處理3D
就像我的朋友Hakim一樣,我也完全理解我們正使用的技術(shù)的底層細節(jié)。理解表面之下的東西是很重要的,但是如果你使用three.js,它為你免去了如此多的煩惱。你可以將它用于Canvas,WebGL還有SVG,你也應(yīng)該找到哪種方式合適你的需求。
3.避免SetInterval
這對所有使用JavaScript創(chuàng)建動畫的人來說,都是很重要的一點。為什么?假定你設(shè)定每20毫秒后執(zhí)行一次某個函數(shù),而這個函數(shù)需要執(zhí)行超過20毫秒的時間,那么20ms之后,瀏覽器不會在乎,而是直接開始下一次執(zhí)行。至少你可以使用SetTimeout來設(shè)置,在某個函數(shù)執(zhí)行完之后,再次執(zhí)行它。
事實上,有一個更加新潮卻還是半成品的函數(shù),叫做requestAnimationFrame,它很棒。它很類似于setTimeOut函數(shù),除了在這兩個方面:當(dāng)標(biāo)簽頁失去焦點時,它就不再運行了;現(xiàn)在這個函數(shù)還是依賴于瀏覽器的,標(biāo)準(zhǔn)以后還有可能變化。如果你想要更多的信息,可以訪問Paul Irish的博客。
4.使用倒序循環(huán)
這是個不錯的小技巧,可以讓你的循環(huán)更快。使用倒序,而且使用while循環(huán)。比如,這個循環(huán):
復(fù)制代碼 代碼如下:
for(var a = 0; a < arr.length; a++) {
// 做一些什么
}
它的執(zhí)行效率不如下面這個循環(huán):
復(fù)制代碼 代碼如下:
// 假設(shè)數(shù)組arr存在
var aLength = arr.length;
while(aLength--) {
// 做一些什么
}
這可能沒幫你省多少開銷,因為執(zhí)行的效率主要還是依賴于你在循環(huán)體里面干了什么。但如果你想程序的不必要開銷減少到最后一個字節(jié),后一個循環(huán)肯定贏。
實話說,主要影響程序執(zhí)行效率的還是數(shù)組緩存的長度。你可以(也確實應(yīng)該)去看看JSPerf去了解這一點,以及其他影響JavaScript性能的因素。
5.使用紋理
在WebGL里面把物體的任意一個細節(jié)都畫出來看上去很誘人,但是,如果有可能的話,你應(yīng)當(dāng)注意一下你是否能夠使用紋理,因為它能夠極大地提高性能。在某些特定的情況下,比如陰影或者模糊效果,你也許不得不使用紋理,但在其他時候,你也應(yīng)該時時關(guān)注你是否可以使用紋理。
6.使用緩存
這一點我在自己的試驗力試了很多,在幀循環(huán)中,你應(yīng)當(dāng)避免引用變量、對象或者其他任何東西?;谶@點原因,很值得把你的模型、頂點全部緩存起來,這樣在渲染動畫的時候你就可以快速地訪問到它們。
7.禁用選中
我愛這一小段代碼,我把它放到任何包含Canvas或WebGL的頁面中。
復(fù)制代碼 代碼如下:
// 禁用鼠標(biāo)選中DOM元素
document.onselectstart = function() {
return false;
};
你也可能只想在Canvas控件中禁用選中。這段是我在那些Canvas占據(jù)了整個屏幕的項目中使用的代碼。
8.避免在JavaScript中定義CSS
現(xiàn)在,在JavaScript中定義CSS簡直太方便了,尤其是你使用JQuery的時候
復(fù)制代碼 代碼如下:
// 盡量不要這樣做
$("#someid").css({
position: 'relative',
height: '30px',
width: '300px',
backgroundColor: '#A020F0'
});
問題是這樣做之后,你的JavaScript代碼中很快就充斥著各種類型的CSS定義,而你同時又使用*.css文件來定義CSS,潛在的問題很難被發(fā)現(xiàn)。更好的方法是:使用class模塊化CSS,而且只在JavaScript中定義那些不能預(yù)知的CSS類。
9.在對象中定義回調(diào)函數(shù)
我愛下面這段代碼,這絕不是我自己想出來的,但它是如此整潔美觀。如果你有一大堆回調(diào)函數(shù)要用,你也許會這樣用的:
復(fù)制代碼 代碼如下:
$("#someid").click(function() {
// 回調(diào)函數(shù)
// 返回false在JQuery中會阻止消息的傳遞和默認(rèn)行為的放生
return false;
});
或者,你會回調(diào)一個在代碼其他地方定義的松散的函數(shù),比如這樣
復(fù)制代碼 代碼如下:
$("#someid").click(mySuperFunction);
function mySuperFunction(event) {
// 在這里做很多事情
return false;
}
這樣做會有一些問題。第一段代碼中,你在某個事件上綁定了匿名函數(shù),你很難將該函數(shù)再從事件上解除下來。你當(dāng)然可以解除某個事件上的所有函數(shù),但你可能在它上面綁定了多個函數(shù),而你只想解除一個。在第二種情況下,你的函數(shù)名污染了全局變量空間,代碼的可維護性降低了。所以,考慮這樣做:
復(fù)制代碼 代碼如下:
$("#someid").click(callbacks.mySuperFunction);
// 所有的回調(diào)函數(shù)都在callbacks對象中
var callbacks = {
mySuperFunction:function(event) {
// 更多地工作
return false;
}
}
// 解除某個函數(shù)的綁定
$("#someid").unbind('click', callbacks.mySuperFunction);
這樣做整潔又干凈,而且避免了上面提到的兩個問題。
10.鏈?zhǔn)饺\算符
我完全是從Paul Irish的《JQuery,你應(yīng)該知道的11件事》中學(xué)到這個的。這非常好用,你也應(yīng)該會喜歡。我們經(jīng)常這樣做:
復(fù)制代碼 代碼如下:
// 根據(jù)a的值為numberBasedOnA賦值
// 如果a大于5,則賦值200,否則賦值38
var numberBasedOnA = a > 5 ? 200 : 38;
但如果你想這樣做,比如,當(dāng)值為多少時如何,當(dāng)值大于多少時如何,當(dāng)值更加大的時候如何,明白嗎?在這種情況下,鏈?zhǔn)饺\算符非常好用:
復(fù)制代碼 代碼如下:
var numberBasedOnA =
a < 5 ? 200 :
a < 7 ? 38 :
a < 11 ? 15 :
a < 15 ? 49 :
64;
// 比這樣做更有效率
// when a >=15
相關(guān)文章
JavaScript中日期的相關(guān)操作方法總結(jié)
這篇文章主要介紹了JavaScript中日期的相關(guān)操作方法總結(jié),是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-10-10JavaScript高級程序設(shè)計(第3版)學(xué)習(xí)筆記3 js簡單數(shù)據(jù)類型
數(shù)據(jù)類型是編程語言的磚瓦,是所有你能想象到的復(fù)雜抽象的基礎(chǔ),在現(xiàn)代編程語言中,除了語言本身內(nèi)置的一些簡單數(shù)據(jù)類型外,基本上都提供了用于自定義數(shù)據(jù)類型的語言機制(在C中也可以利用結(jié)構(gòu)體來實現(xiàn)),這些機制在一定程度上也決定了該語言的流行度和生命力2012-10-10Javascript實例項目放大鏡特效的實現(xiàn)流程
商城網(wǎng)站包括APP端中把鼠標(biāo)光標(biāo)移動到預(yù)覽圖上就會看到這部分商品圖片放大了,這就是JavaScript實現(xiàn)的放大鏡特效,今天我們也來實現(xiàn)一波2021-11-11javascript中FOREACH數(shù)組方法使用示例
本文給大家介紹的是Array.prototype.forEach()的使用方法示例,希望對大家學(xué)習(xí)javascript能夠有所幫助。2016-03-03