最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Tween.js使用指南與詳解(最新推薦)

 更新時間:2025年07月09日 14:53:14   作者:sKK07  
Tween.js實現(xiàn)流暢動畫,通過參數(shù)和事件控制復雜效果,支持鏈式調(diào)用與重復,推薦使用transform優(yōu)化性能,避免onUpdate高開銷操作,對tween.js使用相關知識感興趣的朋友一起看看吧

介紹與定位

做3D項目開發(fā)需要運用到大量動畫,由此使用到了Tween插件??梢院唵蔚貙崿F(xiàn)流暢絲滑的動畫效果。通過參數(shù)的配置和事件的監(jiān)聽能實現(xiàn)復雜多變的動畫形式。也可用于普通web項目的動畫上。

安裝

  1. npm 添加依賴
    npm install @tweenjs/tween.js
    
  2. 引入
    • 使用構(gòu)建工具
      import * as TWEEN from '@tweenjs/tween.js'
    • 沒有構(gòu)建工具
        // 如果將 node_modules 作為網(wǎng)站的一部分提供服務,則可以使用 importmap script 標簽從 node_modules 導入。 首先,假設 node_modules 位于網(wǎng)站的根目錄,可以編寫一個導入映射:
      	<script type="importmap">
      		{
      			"imports": {
      				"@tweenjs/tween.js": "/node_modules/@tweenjs/tween.js/dist/tween.esm.js"
      			}
      		}
      	</script>
      	// 其他頁面
      	import * as TWEEN from '@tweenjs/tween.js'
  3. 其他引入——從 CDN 安裝
    //cdnjs:
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/23.1.3/tween.umd.js"></script>
    	// unpkg.com:
    	<script src="https://unpkg.com/@tweenjs/tween.js@^23.1.3/dist/tween.umd.js"></script>

什么是 tween ?tween 是如何工作的?為什么要使用 tween ?

補間(動畫)(來自 in-between)是一個概念,允許以平滑的方式更改對象的屬性。只需告訴它哪些屬性要更改,當動畫結(jié)束運行時它們應該具有哪些最終值,以及這需要多長時間,動畫引擎將負責計算從起始點到結(jié)束點的值。

例如,position 對象擁有 xy 兩個坐標,需要將 x 坐標的值從 100 變成 200

const position = {x: 100, y: 0}
// 首先為位置創(chuàng)建一個補間(tween)
const tween = new TWEEN.Tween(position)
// 然后告訴 tween 我們想要在1000毫秒內(nèi)以動畫的形式改變 x 的位置
tween.to({x: 200}, 1000)

如此就創(chuàng)建好了動畫過程,但是發(fā)現(xiàn)沒有效果是因為它還沒被激活(使用),需要啟動:

// 啟動
tween.start()

此時發(fā)現(xiàn)還是沒有變化,那是因為動畫執(zhí)行了,但是視圖沒有更新,需要在主函數(shù)中調(diào)用 TWEEN.update ,如下使用:

animate()
function animate() {
	// 動畫幀函數(shù),跟設備的刷新頻率有關,每刷新一次調(diào)用一次
	requestAnimationFrame(animate)
	// [...]
	TWEEN.update()
	// [...]
}

如此在更新每幀的時候都會運行補間動畫;經(jīng)過 1 秒(1000 毫秒)后 position.x 將會變成 200。

除非在控制臺中打印出 x 的值,不然看不到它的變化。你可能想要使用 onUpdate 回調(diào):

tween.onUpdate(function (object) {
	console.log(object.x)
})

每次更新補間時都會調(diào)用此函數(shù); 這種情況發(fā)生的頻率取決于許多因素——例如,計算機或設備的速度有多快(以及有多繁忙?。?。

到目前為止,只使用 tweens 將值打印到控制臺,也可以將它用于 three.js 對象的動畫位置之類的事情:

const tween = new TWEEN.Tween(cube.position).to({x: 100, y: 100, z: 100}, 10000).start()
animate()
function animate() {
	requestAnimationFrame(animate)
	TWEEN.update()
	threeRenderer.render(scene, camera)
}

在這種情況下,因為 three.js 渲染器將在渲染之前查看對象的位置,所以不需要使用的 onUpdate 回調(diào)。

由上可見:tween.js 可以鏈式調(diào)用! 每個 tween 函數(shù)都會返回 ``tween` 實例,所以可以重寫下面的代碼:

const tween = new TWEEN.Tween(position)
tween.to({x: 200}, 1000)
tween.start()

改成如下:

const tween = new TWEEN.Tween(position).to({x: 200}, 1000).start()

如此會方便很多,之后的例子也多采用這種方式。

tween.js 的動畫

Tween.js 不會自行運行。需要顯式的調(diào)用 update 方法來告訴它何時運行。推薦的方法是在主動畫循環(huán)中執(zhí)行這個操作。使用 ``requestAnimationFrame` 調(diào)用此循環(huán)以獲得最佳的圖形性能。

比如:

animate()
function animate() {
	requestAnimationFrame(animate)
	// [...]
	TWEEN.update()
	// [...]
}

如果不帶參數(shù)調(diào)用,update 將會判斷當前時間點,以便找出自上次運行以來已經(jīng)過了多長時間。

當然也可以傳遞一個明確的時間參數(shù)給 update 來更新:

TWEEN.update(startTime + 100)

意思是“更新時間 = 開始時間后的 100 毫秒”??梢允褂盟鼇泶_保代碼中的所有時間相關函數(shù)都使用相同的時間值。例如,假設有一個播放器,并希望同步運行補間:

// 創(chuàng)建一個對象,其屬性將被補間
const object = { x: 0 ,y:0};
// 獲取當前時間戳
const startTime = Date.now();
// 創(chuàng)建一個補間動畫,將對象的 x 屬性從 0 漸變到 100,持續(xù)時間為 1000 毫秒
const tween1 = new TWEEN.Tween(object)
    .to({ x: 100 }, 1000)
    .start(startTime);
// 創(chuàng)建另一個補間動畫,將對象的 y 屬性從 0 漸變到 200,持續(xù)時間為 1000 毫秒
const tween2 = new TWEEN.Tween(object)
    .to({ y: 200 }, 1000)
    .start(startTime);
// 手動更新補間動畫,傳入相對于起始時間 500 毫秒后的時間戳
TWEEN.update(startTime + 500);
// 兩者采用了同一開始時間點,所以它們在 500 毫秒后都完成 50% 的動畫。
console.log(object.x); // 輸出應該為 50,因為動畫完成了 50%
console.log(object.y); // 輸出應該為 100,因為動畫完成了 50%

注:必須在 start() 中使用 同一個 開始時間點,在 update() 中使用和 start() 中一樣的時間點并后延對應時間才有效果。

控制一個補間

start 和 stop

到目前為止,我們已經(jīng)了解了 Tween.start 方法,但是還有更多的方法來控制單個補間。也許最重要的一個是 start 對應的方法:stop 。 如果想取消一個補間,只要通過一個單獨的補間調(diào)用這個方法:

tween.stop()

注:停止一個從未開始或已經(jīng)停止的補間沒有任何效果。 沒有錯誤被拋出。

  • start 方法可接受一個 time 參數(shù),應為時間戳。如果使用它,補間直到那個特定的時刻才會開始;否則它將立即開始(即在下一次調(diào)用 TWEEN.update 時,不調(diào)用 update 補間對象的值是 不變的 )。

  • start 方法也可接受第二個 布爾 參數(shù):當為 true 時,使用的補間將從目標對象 中止或完成 的值開始,而不是從 初始值 開始。用于停止一個動畫,然后開啟一個新的動畫,新動畫從上一個動畫結(jié)束的位置開始。

startFromCurrentValues

這是 tween.start(undefined, true) 的別名,使當前使用的補間從目標對象的上一個補間的最后一個值開始,而不是從頭開始。

update

補間有一個 update 方法(不常用)。 這實際上是由 TWEEN.update 調(diào)用的,用于僅使用一個簡單動畫構(gòu)建的補間。

在下面的示例中,第二個參數(shù)告訴新的 Tween 不要將自己添加到默認組TweenTWEEN.Group 的一個實例)。如果補間不與組關聯(lián)(請注意,可以通過將 作為第二個參數(shù)傳遞給構(gòu)造函數(shù)來關聯(lián)組),則補間需要使用其 update 方法手動更新,如下所示:

const tween = new TWEEN.Tween(someObject, false).to(/*...*/).start()
function animate() {
	// 通過自己的update來更新補間。此時使用TWEEN.update(),tween補間不會執(zhí)行。
	tween.update()
	requestAnimationFrame(animate)
}

注: 如果你使用 TWEEN.update() 作為默認控制所有補間的方式,則無需直接調(diào)用 tween.update(),但是建議直接如上例所示 創(chuàng)建自己的補間組 或手動更新補間。 使用組或單獨控制的補間的概念很像避免在 JavaScript 代碼中使用 全局變量 的做法:它可以防止一個組件意外破壞其他一些不相關組件的行為。

chain

當按順序排列不同的補間時,事情會變得更有趣,例如在上一個補間結(jié)束的時候立即啟動另外一個補間。稱此為 鏈接補間 ,它是通過 chain 方法完成的。因此,要使 tweenBtweenA 完成后開始:

tweenA.chain(tweenB)

或者,可以創(chuàng)造一個無限的鏈式,tweenA 完成時開始 tweenB,tweenB 完成時開始 tweenA

tweenA.chain(tweenB)
tweenB.chain(tweenA)

在其他情況下,你可能希望將多個補間鏈接到另一個補間,使它們(鏈接的補間)都同時開始動畫:

tweenA.chain(tweenB, tweenC)

注: 調(diào)用 tweenA.chain(tweenB) 實際上修改了 tweenA,所以 tweenB 總是在 tweenA 完成時啟動。 chain 的返回值只是 tweenA,不是一個新的 tween。類比js中數(shù)組的 concat 方法。

repeat

如果想讓一個補間永遠重復,可以鏈接到自己,但更好的方法是使用 repeat 方法。它接受一個參數(shù),描述第一個補間完成后需要多少次重復:

tween.repeat(10) // 循環(huán)10次
tween.repeat(Infinity) // 無限循環(huán)

若重復參數(shù)值為 n 則補間總次數(shù)為 n+1 。

yoyo

此功能僅在與 repeat 一起使用時才有效。 激活時,補間的行為將 像溜溜球 一樣,即它會在開始值和結(jié)束值之間來回跳動,而不是僅僅從頭開始重復相同的順序:

tween.yoyo(false) // 默認值,動畫只會從開始到結(jié)束值
tween.yoyo(true) // tween 將在起始值和結(jié)束值之間“yoyo”

delay

更復雜的安排可能需要在實際開始運行之前延遲執(zhí)行補間。 可以使用 delay 方法來實現(xiàn):

tween.delay(1000)
tween.start()

將在調(diào)用 start 方法后的 1 秒鐘后開始執(zhí)行。

repeatDelay

通常,delay 時間應用于不同補間的銜接之間,但如果向 repeatDelay 函數(shù)提供了一個值,則該值將確定補間重復(repeat)之間經(jīng)過的總時間。

tween.delay(1000)
tween.repeatDelay(500)
tween.start()

補間的第一次迭代將在一秒后發(fā)生,第二次迭代將在第一次迭代結(jié)束后半秒發(fā)生,第三次迭代將在第二次迭代結(jié)束后半秒發(fā)生,依此類推。如果之想延遲初始迭代但不希望迭代之間有任何延遲,請確保調(diào)用 tween.repeatDelay(0) ,默認就是 0

dynamic

如果 dynamic 設置為 true(默認為 false),則傳遞給 tween.to() 的對象可以在補間動畫的外部進行修改。這可用于在運行時動態(tài)修改補間的結(jié)果。

請參閱 dynamic 示例。在那個例子中,在這兩個場景中,兔子的位置都在動畫期間更新。 兔子的位置恰好是傳遞給狐貍的 tween.to() 方法的對象。 隨著兔子位置的更新,在第一個帶有 .dynamic(false) 的場景中,狐貍向兔子的初始位置移動并且不跟隨兔子,而在第二個帶有 .dynamic(true) 的場景中,狐貍移動到兔子的最終目的地 狐貍因此也被更新,這使得狐貍跟隨兔子。

注: 當 dynamic 設置為 false 時,Tween 復制傳遞給 tween.to() 的對象并且永遠不會修改它(因此從外部更新原始對象不是動態(tài)的)。當 dynamictrue 時,Tween 在動畫期間使用原始對象作為值的來源(每次更新都讀取值,因此可以動態(tài)修改它們) 但要注意,在 dynamic 模式下,Tween 將修改傳遞給 tween.to() 的對象的任何插值數(shù)組,這可能會對也依賴于同一對象的任何外部代碼造成副作用。

pause 和 resume

暫停當前正在運行的動畫?;謴蜁和5膭赢?。

const tween = new TWEEN.Tween(obj).to({ x: 100 }, 1000);
tween.start();
// 一段時間后暫停動畫
setTimeout(() => {
  tween.pause();
}, 300);
// 再過一段時間后恢復動畫
setTimeout(() => {
  tween.resume();
}, 600);

stopChainedTweens

停止所有鏈接在當前 Tween 對象之后的動畫。當使用 chain 方法鏈接多個動畫時,調(diào)用此方法可以終止后續(xù)動畫的執(zhí)行。

const obj = { x: 0 };
const tween1 = new TWEEN.Tween(obj).to({ x: 100 }, 1000);
const tween2 = new TWEEN.Tween(obj).to({ x: 200 }, 1000);
tween1.chain(tween2);
tween1.start();
// 停止鏈接的 tween2 動畫
tween1.stopChainedTweens(); 

控制所有 補間

TWEEN 全局對象中可以找到以下方法,除了 update 之外,通常不需要使用其中的大部分方法。

TWEEN.update(time)

用于更新所有活動的補間。 如果 time 不指定,它將使用當前時間。

TWEEN.getAll and TWEEN.removeAll

用于獲取對活動 tweens 數(shù)組的引用,并分別通過一次調(diào)用將它們從數(shù)組中移除。

TWEEN.add(tween) and TWEEN.remove(tween)

分別用于將補間添加到活動補間列表,或從列表中刪除特定補間。

控制補間集

使用 TWEEN 單例來管理補間可能會導致包含許多組件的大型應用程序出現(xiàn)問題。在這些情況下,可能需要創(chuàng)建更小的補間集。

示例:交叉組件沖突

如果有多個組件使用 TWEEN,并且每個組件都想管理自己的補間集,則可能會發(fā)生沖突。 如果一個組件調(diào)用 TWEEN.update()TWEEN.removeAll(),其他組件的補間也將被更新或刪除。

創(chuàng)建自己的補間集

為了解決這個問題,每個組件都可以創(chuàng)建自己的 TWEEN.Group 實例(這是全局 TWEEN 對象在內(nèi)部使用的實例)。 在實例化新補間時,這些組可以作為第二個可選參數(shù)傳入:

const groupA = new TWEEN.Group()
const groupB = new TWEEN.Group()
const tweenA = new TWEEN.Tween({x: 1}, groupA).to({x: 10}, 100).start()
const tweenB = new TWEEN.Tween({x: 1}, groupB).to({x: 10}, 100).start()
const tweenC = new TWEEN.Tween({x: 1}).to({x: 10}, 100).start()
groupA.update() // 只更新tweenA
groupB.update() // 只更新tweenB
TWEEN.update() // 只更新tweenC
groupA.removeAll() // 只移除tweenA
groupB.removeAll() // 只移除tweenB
TWEEN.removeAll() // 只移除tweenC

這樣,每個組件都可以創(chuàng)建、更新和銷毀自己的補間集。

改變緩動功能(別名:讓它彈)

Tween.js 默認以線性方式執(zhí)行值之間的插值(即緩動),因此變化與經(jīng)過的時間成正比。 也可以使用緩動方法輕松更改此行為。 例如:

tween.easing(TWEEN.Easing.Quadratic.In)

這將導致補間緩慢開始,逐漸加速,然后快速達到其最終值。 相比之下,TWEEN.Easing.Quadratic.Out 開始快速變化,逐漸減速,在接近最終值時會非常慢。

可用的緩動函數(shù):TWEEN.Easing

tween.js 提供了一些現(xiàn)成的緩動功能。它們按照它們表示的方程類型進行分組:線性Linear、二次Quadratic、三次Cubic、四次Quartic、五次Quintic正弦Sinusoidal、指數(shù)Exponential、圓形Circular彈性Elastic、后退Back反彈Bounce,然后按緩動類型:In、OutInOut圖表示例

注: Linear 沒有 In、OutInOut 只有 None

使用自定義緩動功能

不僅可以使用現(xiàn)有的緩動函數(shù),還可以制作自己的函數(shù),只要它遵循一些約定即可:

  1. 它必須接受一個參數(shù):
    k: 緩動過程,或我們的補間所處的時間有多長。允許的值在 [0, 1] 的范圍內(nèi)。
  2. 它必須根據(jù)輸入?yún)?shù)返回一個值。
    無論要更改多少屬性,每次更新時每個補間只調(diào)用一次緩動函數(shù)。 然后將結(jié)果與初始值以及此值和最終值之間的差值(deltas)一起使用,如以下偽代碼所示:
    easedElapsed = easing(k);
    for each property:
    	newPropertyValue = initialPropertyValue + propertyDelta * easedElapsed;

對于更注重性能表現(xiàn)的人來說:只有在補間上調(diào)用 start() 時才會計算 deltas。

因此,假設想要使用自定義緩動函數(shù)來緩動值,將 Math.floor 應用于輸出,因為只會返回整數(shù)部分,從而產(chǎn)生一種階梯式輸出:

function tenStepEasing(k) {
	return Math.floor(k * 10) / 10
}

可以通過簡單地調(diào)用它的緩動方法在補間中使用它,就像之前看到的那樣:查看示例

tween.easing(tenStepEasing)

回調(diào)函數(shù)

能夠在每個補間的生命周期的特定時間運行自己的功能。 當更改屬性不能實現(xiàn)時,通常需要這樣做。

例如,假設正在試圖給一些不能直接訪問屬性的對象設置動畫,需要調(diào)用 setter。 可以使用 update 回調(diào)來讀取新的更新值,然后手動調(diào)用 setters 。 所有的回調(diào)函數(shù)都將 補間對象 作為唯一的參數(shù)。

const trickyObjTween = new TWEEN.Tween({
	propertyA: trickyObj.getPropertyA(),
	propertyB: trickyObj.getPropertyB(),
})
	.to({propertyA: 100, propertyB: 200})
	.onUpdate(function (object) {
		object.setA(object.propertyA)
		object.setB(object.propertyB)
	})

或者想在開始補間時播放聲音。 可以使用 start 回調(diào):

const tween = new TWEEN.Tween(obj).to({x: 100}).onStart(function () {
	sound.play()
})

每個回調(diào)的范圍是補間對象——在本例中為 obj。

onStart

在補間開始動畫之前執(zhí)行,在 delay 方法指定的任何延遲時間之后。 每個補間只會執(zhí)行一次,即當補間通過 repeat() 重復時不會運行。

onStart 非常適合與其他事件同步,或觸發(fā)需要在補間開始時執(zhí)行的操作。

onStop

當補間通過 stop() 顯式停止執(zhí)行時,該補間的 onComplete 將不會執(zhí)行,并且在所有后續(xù)鏈接補間的 onStart 也不會執(zhí)行。

  	// 創(chuàng)建一個對象,用于存儲需要補間的屬性
    const object = { x: 0 };
    // 創(chuàng)建第一個補間,將 object.x 從 0 過渡到 100,持續(xù)時間為 5000 毫秒
    const tween1 = new TWEEN.Tween(object)
        .to({ x: 100 }, 5000)
        .onUpdate((obj) => {
       	  // 輸出的是本次更新之后的值
          console.log("Tween 1 update", obj.x);
        })
        .onStop(() => {
          console.log("Tween 1 被手動停止");
        })
        .onComplete(() => {
          console.log("Tween 1 完成");
        });
    // 創(chuàng)建第二個補間,將 object.x 從 100 過渡到 200,持續(xù)時間為 3000 毫秒
    const tween2 = new TWEEN.Tween(object)
        .to({ x: 200 }, 3000)
        .onStart(() => {
          // 因為第一次補間顯式的停止,所以不會觸發(fā)后續(xù)鏈接補間的 onStart 事件
          console.log("Tween 2 開始");
        })
        .onUpdate((obj) => {
          console.log("t2 update", obj.x);
        })
        .onStop(() => {
          console.log("Tween 2 被手動停止");
        })
        .onComplete(() => {
          console.log("Tween 1 完成");
        });
    // 鏈接兩個補間
    tween1.chain(tween2);
    // 啟動第一個補間
    tween1.start();
    // 在 2000 毫秒后停止第一個補間
    setTimeout(() => {
      tween1.stop();
    }, 2000);
    function animate() {
      // 更新補間動畫的狀態(tài)
      TWEEN.update();
      // 如果補間動畫還在進行中,繼續(xù)調(diào)用 animate 函數(shù)
      if (TWEEN.getAll().length > 0) {
        requestAnimationFrame(animate);
      }
    }
    // 開始動畫循環(huán)
    animate();

onUpdate

每次更新補間時執(zhí)行,在實際更新值之后執(zhí)行。

onComplete

當補間正常完成(即未停止)時執(zhí)行。

onRepeat

每當補間剛剛完成一個重復并將開始另一個重復時執(zhí)行。

補間狀態(tài)

isPlaying

開始時為 true(即使是暫停)。

當補間 停止 時,isPlayingisPaused 都將為 false。

isPaused

暫停時為 true。 isPlaying 也將為 true。 如果補間已啟動但未暫停,則 isPlaying 將為 trueisPaused 將為 false。

高級補間

相對值

使用 to 方法時,也可以使用 相對值 。 當 tween 啟動時,Tween.js 將讀取當前屬性值并應用相對值來找出新的最終值。 但是需要使用 引號 ,否則這些值將被視為絕對的。查看示例。

// 這將使 `x` 屬性始終為 100
const absoluteTween = new TWEEN.Tween(absoluteObj).to({x: 100})
// 假設 absoluteObj.x 現(xiàn)在為 0
absoluteTween.start() // 使 x 變?yōu)?100
// 假設 absoluteObj.x 現(xiàn)在是 -100
absoluteTween.start() // 使 x 變?yōu)?100
// 相比之下...
// 這將使 `x` 屬性相對于開始時的實際值多 100 個單位
const relativeTween = new TWEEN.Tween(relativeObj).to({x: '+100'})
// 假設 relativeObj.x 現(xiàn)在是 0
relativeTween.start() // 使 x 變?yōu)?0 +100 = 100
// 假設 relativeObj.x 現(xiàn)在是 -100
relativeTween.start() // 使 x 變?yōu)?-100 +100 = 0

補間嵌套對象

Tween.js 還可以跨嵌套對象更改屬性。 例如:

const nestedObject = {scale: {x: 0, y: 0}, alpha: 0}
const tween = new TWEEN.Tween(nestedObject).to({scale: {x: 100, y: 100}, alpha: 1})

補間值的數(shù)組

除了補間到絕對值或相對值之外,還可以讓 Tween.js 更改一系列值的屬性。 為此,只需為屬性指定一個值 數(shù)組 而不是單個值。 例如:

const tween = new TWEEN.Tween(relativeObj).to({x: [0, -100, 100]})

將使 x 從初始值變?yōu)?0,-100 和 100。

這些值的計算方法如下:

  1. 首先,補間進度如常計算
  2. 進度(從 0 到 1)用作插值函數(shù)的輸入
  3. 基于進度和值的數(shù)組,生成內(nèi)插值

例如,當補間剛剛 啟動(進度為 0)時,插值函數(shù)將返回數(shù)組中的 第一 個值。 當補間到 一半 時,插值函數(shù)將返回一個大約在數(shù)組 中間 的值,當補間結(jié)束時,插值函數(shù)將返回最后一個值。

你可以使用插值方法更改插值函數(shù)。 例如:

tween.interpolation(TWEEN.Interpolation.Bezier)

以下值可用:

  • TWEEN.Interpolation.Linear
  • TWEEN.Interpolation.Bezier
  • TWEEN.Interpolation.CatmullRom
    默認是 Linear 。

注:插值函數(shù)對于在同一補間中與數(shù)組補間的所有屬性都是全局的。 不能使用數(shù)組和線性函數(shù)更改屬性 A,也不能使用數(shù)組和使用相同補間的貝塞爾函數(shù)更改屬性 B; 應該使用兩個運行在同一對象上但修改不同屬性并使用不同插值函數(shù)的補間對象。

查看示例。

獲得最佳性能

雖然 Tween.js 試圖靠自己發(fā)揮性能,但沒有什么能阻止以反性能的方式使用它。 以下是一些在使用 Tween.js 時(或通常在 Web 中制作動畫時)可以避免拖慢項目速度的方法。

使用高性能的 CSS

當你嘗試為頁面中元素的位置設置動畫時,最簡單的解決方案是為 top 和 left 樣式屬性設置動畫,如下所示:

const element = document.getElementById('myElement')
const tween = new TWEEN.Tween({top: 0, left: 0}).to({top: 100, left: 100}, 1000).onUpdate(function (object) {
	element.style.top = object.top + 'px'
	element.style.left = object.left + 'px'
})

但這確實效率低下,因為更改這些屬性會強制瀏覽器在每次更新時重新計算布局,這是一項非常消耗性能的操作。應該使用 transform,它不會使布局無效,并且在可能的情況下也會進行硬件加速,如下所示:

const element = document.getElementById('myElement')
const tween = new TWEEN.Tween({top: 0, left: 0}).to({top: 100, left: 100}, 1000).onUpdate(function (object) {
	element.style.transform = 'translate(' + object.left + 'px, ' + object.top + 'px);'
})

如果動畫需求就這么簡單,最好只使用 CSS 動畫或過渡(在適用的情況下),這樣瀏覽器就可以盡可能地進行優(yōu)化。 當動畫需要涉及復雜的操作時,Tween.js 是非常有用,也就是說,需要將多個補間同步在一起,在一個完成后開始,循環(huán)多次,具有不是使用 CSS 而是使用 Canvas 渲染的圖形或 WebGL 等等。

對垃圾收集器(別名 GC)

如果使用 onUpdate 回調(diào),需要非常小心放在它上面的東西。 這個函數(shù)每秒會被調(diào)用很多次,如果每次更新時都做代價高昂的操作,可能會阻塞主線程并導致可怕的卡頓,或者——如果操作涉及內(nèi)存分配,會使垃圾收集器運行過于頻繁,也會導致卡頓。 所以不要做這兩件事。 保持 onUpdate 回調(diào)非常輕量級,并確保在開發(fā)時也使用內(nèi)存分析器。

總結(jié)

到此這篇關于Tween.js使用指南與詳解的文章就介紹到這了,更多相關tween.js使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

三亚市| 大埔县| 临猗县| 镇赉县| 大庆市| 广安市| 泾阳县| 利辛县| 吉林省| 吴旗县| 土默特左旗| 宕昌县| 洛阳市| 南康市| 横峰县| 永福县| 涿州市| 三亚市| 洛南县| 中牟县| 九江市| 三江| 山丹县| 巴东县| 固安县| 太保市| 达州市| 延安市| 吴忠市| 怀仁县| 奉化市| 苍南县| 穆棱市| 吉林市| 浙江省| 元谋县| 哈巴河县| 龙泉市| 涪陵区| 安徽省| 库车县|