摘要:繪制變換曲線起飛以上函數就是我們基于內置的實現的自定義變換。例如飛行動畫結束后,將飛機復位。
如何運行的?
new Vue({ el:"#app-1", data:{ position:{ distance:10, height:30, } }, methods:{ flying:function(){ var targetPos = {distance:300,height:120} var tween = new TWEEN.Tween(this.position) function animate(time){ var id = requestAnimationFrame(animate); var isFlying = TWEEN.update(time); if(!isFlying) cancelAnimationFrame(id); } tween.to(targetPos, 2000) tween.start() //內部有個this._startTime,如果傳的time-this._startTime大于2000 //那么這個update只會執行一次 // animate(3000) animate() }, } })
#app-1 p{ font-size: 2em; position: absolute; color:#fff; }
?
TWEEN作用就是對一個對象持續的進行線性式的改動,比如對象原始狀態為{distance:10,height:30},最終狀態為{distance:300,height:120},我們設置個時間,TWEEN就在該時間內把對象原始的狀態漸進的變換成最終狀態。
在初始化實例new TWEEN.Tween(original-obj)時設置原始數據對象,在實例方法to(final-obj,time)中設置最終數據對象及時間。通過實例方法start()啟動一個TWEEN。然后通過全局方法TWEEN.update(time)去改動對應時間的原始數據對象,每一刻的時間對應著一份修改的數據,大概像下面這樣:
調用update() | 調用后數據的改變 |
---|---|
TWEEN.update(20) | {distance:15,height:31} |
TWEEN.update(40) | {distance:25,height:33} |
TWEEN.update(70) | {distance:45,height:37} |
如修改下代碼:
flying:function(){ var targetPos = {distance:300,height:120} var tween = new TWEEN.Tween(this.position) // function animate(time){ // var id = requestAnimationFrame(animate); // var isFlying = TWEEN.update(time); // if(!isFlying) cancelAnimationFrame(id); // } tween.to(targetPos, 2000) tween.start() TWEEN.update(1500); //內部有個this._startTime,如果傳的time-this._startTime大于2000 //那么這個update只會執行一次 // animate(3000) // animate() },
點起飛,只會轉換到1500毫秒時的狀態。
結合requestAnimationFrame(fn)如果我們不傳參數,那么它會根據start()的時間自動計算好當前的時間再修改該時間數據。因為最后數據是要渲染成動畫形式,我們不可能一行行去調用update()。
因此要結合一個神器requestAnimationFrame(fn),這個函數就是在瀏覽器每一幀重繪一次屏幕,非常的穩定。在這里如果是60fps的情況下就是16ms(1000ms/60)調用一次animate(),然后我們在這個animate()重繪循環中不停的調用update(),它就可以線性的修改數據,渲染之后就形成動畫。
TWEEN也可以鏈式調用函數。開始的代碼可以修改成:
flying:function(){ var targetPos = {distance:300,height:120} var tween = new TWEEN.Tween(this.position) .to(targetPos, 2000) .start(); function animate(time){ var id = requestAnimationFrame(animate); var isFlying = TWEEN.update(time); if(!isFlying) cancelAnimationFrame(id); } animate() },easing函數
前面默認情況下,數據變換和時間成正比的(Linear.None),我們可以通過傳遞參數easing()改變這種默認效果,內置了許多變換效果。
給TWEEN加上Bounce.Out效果
var tween = new TWEEN.Tween(this.position) .to(targetPos, 2000) .easing(TWEEN.Easing.Bounce.Out) .start();自定義easing變換函數
TWEEN里最有特色的功能就是easing()參數可以是一個自定義的函數,這樣可以實現變換的定制。
function customerFn(k){ return fn(k) //用k作基礎的自定義運算 } tween.easing(customerFn);//寫好后傳給easing()函數就行
這個k是系統調用的,跟你無關,它是一個在[0,1]范圍內不停增長的值,速度與時間成正比,函數返回一個基于k進行運算后的值。比如簡單的像Linear.None那樣的默認變換,就是不運算直接返回k。
我們也可使用以有的變換做運算,正如下面這樣做。
methods: { flying: function () { var targetPos = { distance: 300, height: 120 } /** 繪制變換曲線 */ var target = document.getElementById("target"); target.appendChild(this.createGraph("Noisy Exponential.InOut", noisyEasing) ); function noisyEasing(k) { return 0.3 * Math.random() + 0.7 * TWEEN.Easing.Bounce.Out(k); } var tween = new TWEEN.Tween(this.position) .to(targetPos, 2000) .easing(noisyEasing) .start(); function animate(time) { var id = requestAnimationFrame(animate); var isFlying = TWEEN.update(time); if (!isFlying) cancelAnimationFrame(id); } animate() }, createGraph:function( t, f, c ) { var div = document.createElement( "div" ); div.style.display = "inline-block"; div.style.width = "200px"; div.style.height = "120px"; var canvas = document.createElement( "canvas" ); canvas.width = 180; canvas.height = 100; var context = canvas.getContext( "2d" ); context.fillStyle = "rgb(250,250,250)"; context.fillRect( 0, 0, 180, 100 ); context.lineWidth = 0.5; context.strokeStyle = "rgb(230,230,230)"; context.beginPath(); context.moveTo( 0, 20 ); context.lineTo( 180, 20 ); context.moveTo( 0, 80 ); context.lineTo( 180, 80 ); context.closePath(); context.stroke(); context.lineWidth = 2; context.strokeStyle = "rgb(255,127,127)"; var position = { x: 5, y: 80 }; var position_old = { x: 5, y: 80 }; new TWEEN.Tween( position ).to( { x: 175 }, 2000 ).easing( TWEEN.Easing.Linear.None ).start(); new TWEEN.Tween( position ).to( { y: 20 }, 2000 ).easing( f ).onUpdate( function () { context.beginPath(); context.moveTo( position_old.x, position_old.y ); context.lineTo( position.x, position.y ); context.closePath(); context.stroke(); position_old.x = position.x; position_old.y = position.y; }).start(); div.appendChild( document.createTextNode( t ) ); div.appendChild( document.createElement( "br" ) ); div.appendChild( canvas ); return div; } }
?
以上noisyEasing(k)函數就是我們基于內置的Bounce.Out實現的自定義變換。createGraph()函數是官方例子扣下來的,就是在頁面繪制下自定義變換的曲線。
這是內置的Bounce.Out變換,其實就是做了一絲絲抖動效果。
回調方法TWEEN的四種狀態啟動、停止、更新和完成,每種下面都可以綁定一個回調函數,onStart(fn)、onStop(fn)、onUpdate(fn)和onComplete(fn)。例如飛行動畫結束后,將飛機復位。
new Vue({ el: "#app-2", data: { position: { distance: 10, height: 30, } }, methods: { flying: function () { var _this = this var targetPos = { distance: 300, height: 120 } var tween = new TWEEN.Tween(this.position) tween.to(targetPos, 5000) .easing(TWEEN.Easing.Circular.InOut) .onComplete(function () { _this.position.distance = 10 _this.position.height = 30 }) function animate(time) { var id = requestAnimationFrame(animate); var isFlying = TWEEN.update(time); if (!isFlying) cancelAnimationFrame(id); } tween.start() animate() } } })
由于閉包的關系,Vue里的this不能用鉤子函數里,因此定義了一個中間變量_this。
其實update()是最常用的鉤子,一般用來在每次修改后對頁面元素做數據綁定,但這里有Vue就不需要它了。
調用實例方法repeat(frequency)設置動畫循環次數,若參數為Infinity,則循環無限次。
new Vue({ el: "#app-3", data: { rotation: { x: 0, y: 0, z: 0 } }, methods: { rotate: function () { var tween_x= new TWEEN.Tween(this.rotation) .to({ x: 360 }) var tween_y = new TWEEN.Tween(this.rotation) .to({ y: 360 }).repeat(3) var tween_z = new TWEEN.Tween(this.rotation) .to({ z: 360 }).repeat(Infinity) function animate(time) { var id = requestAnimationFrame(animate); var isFlying = TWEEN.update(time); if (!isFlying) cancelAnimationFrame(id); } tween_x.start() tween_y.start() tween_z.start() animate() } } })
轉一圈 轉三圈 無限轉
可以使用tween.stop()停止動畫,修改上段JS代碼:
methods: { rotate: function () { var tween_x= new TWEEN.Tween(this.rotation) .to({ x: 360 }) var tween_y = new TWEEN.Tween(this.rotation) .to({ y: 360 }).repeat(3).onComplete(function(){ //當第二個tween動畫完成時,停止第三個tween運行 tween_z.stop() }) var tween_z = new TWEEN.Tween(this.rotation) .to({ z: 360 }).repeat(Infinity) function animate(time) { var id = requestAnimationFrame(animate); var isFlying = TWEEN.update(time); if (!isFlying) cancelAnimationFrame(id); } tween_x.start() tween_y.start() tween_z.start() animate() } }
當第二動畫的三圈轉完時,停止第三個動畫效果。
調用鏈條與鏈條循環使用tween_a.chain(tween_b)可以按順序的(先a后b)鏈式調用多個tween實例,如果接著調用tween_b.chain(tween_a)調用將進入無限循環中(執行a->b->a->b),如下:
new Vue({ el: "#app-4", data: { position: { x: 20, y: 0 } }, methods: { move: function () { console.log("aaa"); var tween_a = new TWEEN.Tween(this.position) .to({ x: 280, y: 0 }, 3000) var tween_b = new TWEEN.Tween(this.position) .to({ x: 280, y: 120 }, 3000) var tween_c = new TWEEN.Tween(this.position) .to({ x: 20, y: 120 }, 3000) var tween_d = new TWEEN.Tween(this.position) .to({ x: 20, y: 0 }, 3000) function animate(time) { var id = requestAnimationFrame(animate); var isFlying = TWEEN.update(time); if (!isFlying) cancelAnimationFrame(id); } tween_a.chain(tween_b) tween_b.chain(tween_c) tween_c.chain(tween_d) tween_d.chain(tween_a) tween_a.start() animate() } } })
YOYO
如果TWEEN有循環(調用repeat()),并調用tween.yoyou(true),那么在執行下一次動畫之前,動畫會彈到起始位置。
el: "#app-5", data: { position: { x: 20 } }, methods: { move: function () { var tween = new TWEEN.Tween(this.position) .to({ x: 280 }, 1000).repeat(1).yoyo(true) function animate(time) { var id = requestAnimationFrame(animate); var isFlying = TWEEN.update(time); if (!isFlying) cancelAnimationFrame(id); } tween.start() animate() } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93579.html
摘要:可以指定一個具體值,而非增量,在之間。這是因為,使進度增加超過時,會變成,之后又從重新開始。所以,當為時,我們停止調用。 依賴jQuery。 import nprogress from nprogress import nprogress/nprogress.css $(#btn-loading).on(click, function () { nprogress.start...
摘要:動畫運動算法線性勻速運動效果二次方的緩動三次方的緩動四次方的緩動五次方的緩動正弦曲線的緩動指數曲線的緩動圓形曲線的緩動指數衰減的正弦曲線緩動超過范圍的三次方緩動指數衰減的反彈緩動。 requestAnimFrame兼容 window.requestAnimFrame = (function (callback,time) { return window.requestAnima...
摘要:首先引入一個概念就補間動畫做動畫時會用到類,利用它可以做很多動畫效果,例如緩動彈簧等等。代表的就是最后一幀減去初始值就是變化量,代表最后一幀的結束也是動畫的結束。 一、理解tween.js 如果看到上面的已經理解了,可以跳過下面的部分.下面為對Tween.js的解釋 下面就介紹如何使用這個Tween了,首先b、c、d三個參數(即初始值,變化量,持續時間)在緩動開始前,是需要先確定好的。...
摘要:個人筆記在給在線簡歷添加特效過程中遇到的問題及解決方法二預覽點擊菜單滾動動畫首頁目標位置當作終點坐標當前滾動到的距離當做起點是步數分步是每次重復都加的變量既要清除又要毫秒除以幀就是每走一步的時間庫緩動動畫緩動函數速查表庫搜索引入一個網站 (個人筆記)在給在線簡歷添加js特效過程中遇到的問題及解決方法 二 github預覽 點擊菜單滾動動畫首頁 let top = element.of...
閱讀 4221·2021-09-26 10:17
閱讀 871·2021-09-22 15:02
閱讀 3446·2021-09-06 15:00
閱讀 1055·2021-07-25 16:52
閱讀 2734·2019-08-29 16:16
閱讀 2515·2019-08-29 13:25
閱讀 1588·2019-08-26 13:51
閱讀 2182·2019-08-26 10:58