成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PocketLibs(1)—— 動(dòng)畫 tween.js

ShowerSun / 1484人閱讀

摘要:繪制變換曲線起飛以上函數(shù)就是我們基于內(nèi)置的實(shí)現(xiàn)的自定義變換。例如飛行動(dòng)畫結(jié)束后,將飛機(jī)復(fù)位。

如何運(yùn)行的?
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()
            //內(nèi)部有個(gè)this._startTime,如果傳的time-this._startTime大于2000
            //那么這個(gè)update只會(huì)執(zhí)行一次
            // animate(3000)
            animate()
        },
    }
})
#app-1 p{
    font-size: 2em;
    position: absolute;
    color:#fff;
}

?

TWEEN作用就是對(duì)一個(gè)對(duì)象持續(xù)的進(jìn)行線性式的改動(dòng),比如對(duì)象原始狀態(tài)為{distance:10,height:30},最終狀態(tài)為{distance:300,height:120},我們?cè)O(shè)置個(gè)時(shí)間,TWEEN就在該時(shí)間內(nèi)把對(duì)象原始的狀態(tài)漸進(jìn)的變換成最終狀態(tài)。
在初始化實(shí)例new TWEEN.Tween(original-obj)時(shí)設(shè)置原始數(shù)據(jù)對(duì)象,在實(shí)例方法to(final-obj,time)中設(shè)置最終數(shù)據(jù)對(duì)象及時(shí)間。通過實(shí)例方法start()啟動(dòng)一個(gè)TWEEN。然后通過全局方法TWEEN.update(time)去改動(dòng)對(duì)應(yīng)時(shí)間的原始數(shù)據(jù)對(duì)象,每一刻的時(shí)間對(duì)應(yīng)著一份修改的數(shù)據(jù),大概像下面這樣:

調(diào)用update() 調(diào)用后數(shù)據(jù)的改變
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);
    //內(nèi)部有個(gè)this._startTime,如果傳的time-this._startTime大于2000
    //那么這個(gè)update只會(huì)執(zhí)行一次
    // animate(3000)
    // animate()
},

點(diǎn)起飛,只會(huì)轉(zhuǎn)換到1500毫秒時(shí)的狀態(tài)。

結(jié)合requestAnimationFrame(fn)

如果我們不傳參數(shù),那么它會(huì)根據(jù)start()的時(shí)間自動(dòng)計(jì)算好當(dāng)前的時(shí)間再修改該時(shí)間數(shù)據(jù)。因?yàn)樽詈髷?shù)據(jù)是要渲染成動(dòng)畫形式,我們不可能一行行去調(diào)用update()。

因此要結(jié)合一個(gè)神器requestAnimationFrame(fn),這個(gè)函數(shù)就是在瀏覽器每一幀重繪一次屏幕,非常的穩(wěn)定。在這里如果是60fps的情況下就是16ms(1000ms/60)調(diào)用一次animate(),然后我們?cè)谶@個(gè)animate()重繪循環(huán)中不停的調(diào)用update(),它就可以線性的修改數(shù)據(jù),渲染之后就形成動(dòng)畫。

TWEEN也可以鏈?zhǔn)秸{(diào)用函數(shù)。開始的代碼可以修改成:

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函數(shù)

前面默認(rèn)情況下,數(shù)據(jù)變換和時(shí)間成正比的(Linear.None),我們可以通過傳遞參數(shù)easing()改變這種默認(rèn)效果,內(nèi)置了許多變換效果。

給TWEEN加上Bounce.Out效果

var tween = new TWEEN.Tween(this.position)
            .to(targetPos, 2000)
            .easing(TWEEN.Easing.Bounce.Out)
            .start();

自定義easing變換函數(shù)

TWEEN里最有特色的功能就是easing()參數(shù)可以是一個(gè)自定義的函數(shù),這樣可以實(shí)現(xiàn)變換的定制。

function customerFn(k){
    return fn(k) //用k作基礎(chǔ)的自定義運(yùn)算
}
tween.easing(customerFn);//寫好后傳給easing()函數(shù)就行

這個(gè)k是系統(tǒng)調(diào)用的,跟你無關(guān),它是一個(gè)在[0,1]范圍內(nèi)不停增長的值,速度與時(shí)間成正比,函數(shù)返回一個(gè)基于k進(jìn)行運(yùn)算后的值。比如簡單的像Linear.None那樣的默認(rèn)變換,就是不運(yùn)算直接返回k

我們也可使用以有的變換做運(yùn)算,正如下面這樣做。

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)函數(shù)就是我們基于內(nèi)置的Bounce.Out實(shí)現(xiàn)的自定義變換。createGraph()函數(shù)是官方例子扣下來的,就是在頁面繪制下自定義變換的曲線。

這是內(nèi)置的Bounce.Out變換,其實(shí)就是做了一絲絲抖動(dòng)效果。

回調(diào)方法

TWEEN的四種狀態(tài)啟動(dòng)、停止、更新和完成,每種下面都可以綁定一個(gè)回調(diào)函數(shù),onStart(fn)、onStop(fn)onUpdate(fn)onComplete(fn)。例如飛行動(dòng)畫結(jié)束后,將飛機(jī)復(fù)位。

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()
        }
    }
})

由于閉包的關(guān)系,Vue里的this不能用鉤子函數(shù)里,因此定義了一個(gè)中間變量_this。
其實(shí)update()是最常用的鉤子,一般用來在每次修改后對(duì)頁面元素做數(shù)據(jù)綁定,但這里有Vue就不需要它了。

循環(huán)執(zhí)行(repeat)與停止動(dòng)畫(stop)

調(diào)用實(shí)例方法repeat(frequency)設(shè)置動(dòng)畫循環(huán)次數(shù),若參數(shù)為Infinity,則循環(huán)無限次。

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()
        }
    }
})

轉(zhuǎn)一圈 轉(zhuǎn)三圈 無限轉(zhuǎn)

可以使用tween.stop()停止動(dòng)畫,修改上段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(){
                //當(dāng)?shù)诙€(gè)tween動(dòng)畫完成時(shí),停止第三個(gè)tween運(yùn)行
                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()
    }
}

當(dāng)?shù)诙?dòng)畫的三圈轉(zhuǎn)完時(shí),停止第三個(gè)動(dòng)畫效果。

調(diào)用鏈條與鏈條循環(huán)

使用tween_a.chain(tween_b)可以按順序的(先a后b)鏈?zhǔn)秸{(diào)用多個(gè)tween實(shí)例,如果接著調(diào)用tween_b.chain(tween_a)調(diào)用將進(jìn)入無限循環(huán)中(執(zhí)行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有循環(huán)(調(diào)用repeat()),并調(diào)用tween.yoyou(true),那么在執(zhí)行下一次動(dòng)畫之前,動(dòng)畫會(huì)彈到起始位置。

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()
    }
}


文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93579.html

相關(guān)文章

  • PocketLibs(3)—— 進(jìn)度條 NProgress

    摘要:可以指定一個(gè)具體值,而非增量,在之間。這是因?yàn)?,使進(jìn)度增加超過時(shí),會(huì)變成,之后又從重新開始。所以,當(dāng)為時(shí),我們停止調(diào)用。 依賴jQuery。 import nprogress from nprogress import nprogress/nprogress.css $(#btn-loading).on(click, function () { nprogress.start...

    crossoverJie 評(píng)論0 收藏0
  • JS動(dòng)畫緩動(dòng)—tween.js

    摘要:動(dòng)畫運(yùn)動(dòng)算法線性勻速運(yùn)動(dòng)效果二次方的緩動(dòng)三次方的緩動(dòng)四次方的緩動(dòng)五次方的緩動(dòng)正弦曲線的緩動(dòng)指數(shù)曲線的緩動(dòng)圓形曲線的緩動(dòng)指數(shù)衰減的正弦曲線緩動(dòng)超過范圍的三次方緩動(dòng)指數(shù)衰減的反彈緩動(dòng)。 requestAnimFrame兼容 window.requestAnimFrame = (function (callback,time) { return window.requestAnima...

    wangxinarhat 評(píng)論0 收藏0
  • tween.js緩動(dòng)(補(bǔ)間動(dòng)畫

    摘要:首先引入一個(gè)概念就補(bǔ)間動(dòng)畫做動(dòng)畫時(shí)會(huì)用到類,利用它可以做很多動(dòng)畫效果,例如緩動(dòng)彈簧等等。代表的就是最后一幀減去初始值就是變化量,代表最后一幀的結(jié)束也是動(dòng)畫的結(jié)束。 一、理解tween.js 如果看到上面的已經(jīng)理解了,可以跳過下面的部分.下面為對(duì)Tween.js的解釋 下面就介紹如何使用這個(gè)Tween了,首先b、c、d三個(gè)參數(shù)(即初始值,變化量,持續(xù)時(shí)間)在緩動(dòng)開始前,是需要先確定好的。...

    chengjianhua 評(píng)論0 收藏0
  • (個(gè)人筆記)在給在線簡歷添加js特效過程中遇到的問題及解決方法 二

    摘要:個(gè)人筆記在給在線簡歷添加特效過程中遇到的問題及解決方法二預(yù)覽點(diǎn)擊菜單滾動(dòng)動(dòng)畫首頁目標(biāo)位置當(dāng)作終點(diǎn)坐標(biāo)當(dāng)前滾動(dòng)到的距離當(dāng)做起點(diǎn)是步數(shù)分步是每次重復(fù)都加的變量既要清除又要毫秒除以幀就是每走一步的時(shí)間庫緩動(dòng)動(dòng)畫緩動(dòng)函數(shù)速查表庫搜索引入一個(gè)網(wǎng)站 (個(gè)人筆記)在給在線簡歷添加js特效過程中遇到的問題及解決方法 二 github預(yù)覽 點(diǎn)擊菜單滾動(dòng)動(dòng)畫首頁 let top = element.of...

    CarlBenjamin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<