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

資訊專(zhuān)欄INFORMATION COLUMN

JS進(jìn)階篇--window.requestAnimationFrame與Tween.js配合使用實(shí)現(xiàn)

Riddler / 3390人閱讀

摘要:注意如果想得到連貫的逐幀動(dòng)畫(huà),函數(shù)中必須重新調(diào)用。如果你想做逐幀動(dòng)畫(huà)的時(shí)候,你應(yīng)該用這個(gè)方法。這個(gè)回調(diào)函數(shù)會(huì)收到一個(gè)參數(shù),這個(gè)類(lèi)型的參數(shù)指示當(dāng)前時(shí)間距離開(kāi)始觸發(fā)的回調(diào)的時(shí)間。

window.requestAnimationFrame 概述

window.requestAnimationFrame()這個(gè)方法是用來(lái)在頁(yè)面重繪之前,通知瀏覽器調(diào)用一個(gè)指定的函數(shù),以滿足開(kāi)發(fā)者操作動(dòng)畫(huà)的需求。這個(gè)方法接受一個(gè)函數(shù)為參,該函數(shù)會(huì)在重繪前調(diào)用。

注意: 如果想得到連貫的逐幀動(dòng)畫(huà),函數(shù)中必須重新調(diào)用 requestAnimationFrame()。

如果你想做逐幀動(dòng)畫(huà)的時(shí)候,你應(yīng)該用這個(gè)方法。這就要求你的動(dòng)畫(huà)函數(shù)執(zhí)行會(huì)先于瀏覽器重繪動(dòng)作。通常來(lái)說(shuō),被調(diào)用的頻率是每秒60次,但是一般會(huì)遵循W3C標(biāo)準(zhǔn)規(guī)定的頻率。如果是后臺(tái)標(biāo)簽頁(yè)面,重繪頻率則會(huì)大大降低。

回調(diào)函數(shù)只會(huì)被傳入一個(gè)DOMHighResTimeStamp參數(shù),這個(gè)參數(shù)指示當(dāng)前被 requestAnimationFrame 序列化的函數(shù)隊(duì)列被觸發(fā)的時(shí)間。因?yàn)楹芏鄠€(gè)函數(shù)在這一幀被執(zhí)行,所以每個(gè)函數(shù)都將被傳入一個(gè)相同的時(shí)間戳,盡管經(jīng)過(guò)了之前很多的計(jì)算工作。這個(gè)數(shù)值是一個(gè)小數(shù),單位毫秒,精確度在 10 μs。

語(yǔ)法
requestID = window.requestAnimationFrame(callback);// Firefox 23 / IE10 / Chrome / Safari 7 (incl. iOS)
requestID = window.mozRequestAnimationFrame(callback);// Firefox < 23
requestID = window.webkitRequestAnimationFrame(callback);// Older versions Chrome/Webkit
參數(shù)

callback在每次需要重新繪制動(dòng)畫(huà)時(shí),會(huì)調(diào)用這個(gè)參數(shù)所指定的函數(shù)。這個(gè)回調(diào)函數(shù)會(huì)收到一個(gè)參數(shù),這個(gè) DOMHighResTimeStamp 類(lèi)型的參數(shù)指示當(dāng)前時(shí)間距離開(kāi)始觸發(fā) requestAnimationFrame 的回調(diào)的時(shí)間。

返回值

requestID 是一個(gè)長(zhǎng)整型非零值,作為一個(gè)唯一的標(biāo)識(shí)符.你可以將該值作為參數(shù)傳給 window.cancelAnimationFrame() 來(lái)取消這個(gè)回調(diào)函數(shù)。

例子
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

var start = null;
var d = document.getElementById("SomeElementYouWantToAnimate");
function step(timestamp) { 
  if (start === null) start = timestamp;
  var progress = timestamp - start;
  d.style.left = Math.min(progress/10, 200) + "px";
  if (progress < 2000) {
    requestAnimationFrame(step);
  }
}
requestAnimationFrame(step);
Tween.js

tween.js源碼如下:

/*
 * Tween.js
 * t: current time(當(dāng)前時(shí)間);
 * b: beginning value(初始值);
 * c: change in value(變化量);
 * d: duration(持續(xù)時(shí)間)。
 * you can visit "http://easings.net/zh-cn" to get effect
*/
var Tween = {
    Linear: function(t, b, c, d) { return c*t/d + b; },
    Quad: {
        easeIn: function(t, b, c, d) {
            return c * (t /= d) * t + b;
        },
        easeOut: function(t, b, c, d) {
            return -c *(t /= d)*(t-2) + b;
        },
        easeInOut: function(t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t + b;
            return -c / 2 * ((--t) * (t-2) - 1) + b;
        }
    },
    Cubic: {
        easeIn: function(t, b, c, d) {
            return c * (t /= d) * t * t + b;
        },
        easeOut: function(t, b, c, d) {
            return c * ((t = t/d - 1) * t * t + 1) + b;
        },
        easeInOut: function(t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t*t + b;
            return c / 2*((t -= 2) * t * t + 2) + b;
        }
    },
    Quart: {
        easeIn: function(t, b, c, d) {
            return c * (t /= d) * t * t*t + b;
        },
        easeOut: function(t, b, c, d) {
            return -c * ((t = t/d - 1) * t * t*t - 1) + b;
        },
        easeInOut: function(t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
            return -c / 2 * ((t -= 2) * t * t*t - 2) + b;
        }
    },
    Quint: {
        easeIn: function(t, b, c, d) {
            return c * (t /= d) * t * t * t * t + b;
        },
        easeOut: function(t, b, c, d) {
            return c * ((t = t/d - 1) * t * t * t * t + 1) + b;
        },
        easeInOut: function(t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
            return c / 2*((t -= 2) * t * t * t * t + 2) + b;
        }
    },
    Sine: {
        easeIn: function(t, b, c, d) {
            return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
        },
        easeOut: function(t, b, c, d) {
            return c * Math.sin(t/d * (Math.PI/2)) + b;
        },
        easeInOut: function(t, b, c, d) {
            return -c / 2 * (Math.cos(Math.PI * t/d) - 1) + b;
        }
    },
    Expo: {
        easeIn: function(t, b, c, d) {
            return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
        },
        easeOut: function(t, b, c, d) {
            return (t==d) ? b + c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
        },
        easeInOut: function(t, b, c, d) {
            if (t==0) return b;
            if (t==d) return b+c;
            if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
            return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
        }
    },
    Circ: {
        easeIn: function(t, b, c, d) {
            return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
        },
        easeOut: function(t, b, c, d) {
            return c * Math.sqrt(1 - (t = t/d - 1) * t) + b;
        },
        easeInOut: function(t, b, c, d) {
            if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
            return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
        }
    },
    Elastic: {
        easeIn: function(t, b, c, d, a, p) {
            var s;
            if (t==0) return b;
            if ((t /= d) == 1) return b + c;
            if (typeof p == "undefined") p = d * .3;
            if (!a || a < Math.abs(c)) {
                s = p / 4;
                a = c;
            } else {
                s = p / (2 * Math.PI) * Math.asin(c / a);
            }
            return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
        },
        easeOut: function(t, b, c, d, a, p) {
            var s;
            if (t==0) return b;
            if ((t /= d) == 1) return b + c;
            if (typeof p == "undefined") p = d * .3;
            if (!a || a < Math.abs(c)) {
                a = c; 
                s = p / 4;
            } else {
                s = p/(2*Math.PI) * Math.asin(c/a);
            }
            return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
        },
        easeInOut: function(t, b, c, d, a, p) {
            var s;
            if (t==0) return b;
            if ((t /= d / 2) == 2) return b+c;
            if (typeof p == "undefined") p = d * (.3 * 1.5);
            if (!a || a < Math.abs(c)) {
                a = c; 
                s = p / 4;
            } else {
                s = p / (2  *Math.PI) * Math.asin(c / a);
            }
            if (t < 1) return -.5 * (a * Math.pow(2, 10* (t -=1 )) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
            return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p ) * .5 + c + b;
        }
    },
    Back: {
        easeIn: function(t, b, c, d, s) {
            if (typeof s == "undefined") s = 1.70158;
            return c * (t /= d) * t * ((s + 1) * t - s) + b;
        },
        easeOut: function(t, b, c, d, s) {
            if (typeof s == "undefined") s = 1.70158;
            return c * ((t = t/d - 1) * t * ((s + 1) * t + s) + 1) + b;
        },
        easeInOut: function(t, b, c, d, s) {
            if (typeof s == "undefined") s = 1.70158; 
            if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
            return c / 2*((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
        }
    },
    Bounce: {
        easeIn: function(t, b, c, d) {
            return c - Tween.Bounce.easeOut(d-t, 0, c, d) + b;
        },
        easeOut: function(t, b, c, d) {
            if ((t /= d) < (1 / 2.75)) {
                return c * (7.5625 * t * t) + b;
            } else if (t < (2 / 2.75)) {
                return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
            } else if (t < (2.5 / 2.75)) {
                return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
            } else {
                return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
            }
        },
        easeInOut: function(t, b, c, d) {
            if (t < d / 2) {
                return Tween.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
            } else {
                return Tween.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
            }
        }
    }
}
Math.tween = Tween;
簡(jiǎn)介

動(dòng)畫(huà)運(yùn)動(dòng)算法名稱如下:

Linear:線性勻速運(yùn)動(dòng)效果;

Quadratic:二次方的緩動(dòng)(t^2);

Cubic:三次方的緩動(dòng)(t^3);

Quartic:四次方的緩動(dòng)(t^4);

Quintic:五次方的緩動(dòng)(t^5);

Sinusoidal:正弦曲線的緩動(dòng)(sin(t));

Exponential:指數(shù)曲線的緩動(dòng)(2^t);

Circular:圓形曲線的緩動(dòng)(sqrt(1-t^2));

Elastic:指數(shù)衰減的正弦曲線緩動(dòng);

Back:超過(guò)范圍的三次方緩動(dòng)((s+1)t^3 – st^2);

Bounce:指數(shù)衰減的反彈緩動(dòng)。

每個(gè)效果都分三個(gè)緩動(dòng)方式,分別是:

easeIn:從0開(kāi)始加速的緩動(dòng),也就是先慢后快;

easeOut:減速到0的緩動(dòng),也就是先快后慢;

easeInOut:前半段從0開(kāi)始加速,后半段減速到0的緩動(dòng)。

所有的這些緩動(dòng)算法都離不開(kāi)下面4個(gè)參數(shù),t, b, c, d,含義如下:

/*
 * t: current time(當(dāng)前時(shí)間);
 * b: beginning value(初始值);
 * c: change in value(變化量);
 * d: duration(持續(xù)時(shí)間)。
*/

下面用最簡(jiǎn)單的線性勻速運(yùn)動(dòng)來(lái)解釋下:

Tween.Linear = function(t, b, c, d) { 
    return c*t/d + b; 
}

比方說(shuō)我們要從位置0的地方運(yùn)動(dòng)到100,時(shí)間是10秒鐘,此時(shí),b, c, d三個(gè)參數(shù)就已經(jīng)確認(rèn)了,b初始值就是0,變化值c就是100-0就是100,最終的時(shí)間就是10,此時(shí),只要給一個(gè)小于最終時(shí)間10的值,Tween.Linear就會(huì)返回當(dāng)前時(shí)間應(yīng)該的坐標(biāo),例如,假設(shè)此時(shí)動(dòng)畫(huà)進(jìn)行到第5秒,也就是t為5,則得到(截圖自Chrome控制臺(tái)):

如何實(shí)際使用Tween.js中的緩動(dòng)算法?

兼容寫(xiě)法:

window.requestAnimFrame = (function (callback,time) {
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimaitonFrame ||
        function (callback) {
            window.setTimeout(callback, time);
        };
})();

我們要顯示一個(gè)動(dòng)畫(huà)效果,例如,還是拿上面的線性效果舉例,則代碼可以變成:

var t = 0, b = 0, c = 100, d = 10;
var step = function () {
    // value就是當(dāng)前的位置值
    // 例如我們可以設(shè)置DOM.style.left = value + "px"實(shí)現(xiàn)定位
    var value = Tween.Linear(t, b, c, d);
    t++;
    if (t <= d) {
         // 繼續(xù)運(yùn)動(dòng)
         requestAnimationFrame(step);
    } else {
        // 動(dòng)畫(huà)結(jié)束
    }
};

基本上,所有的動(dòng)畫(huà)使用都是這個(gè)套路。

參考地址:
緩動(dòng)函數(shù)速查表:http://easings.net/zh-cn
http://www.zhangxinxu.com/wor...

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

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

相關(guān)文章

  • JS進(jìn)階--window.requestAnimationFrameTween.js配合使用實(shí)現(xiàn)

    摘要:注意如果想得到連貫的逐幀動(dòng)畫(huà),函數(shù)中必須重新調(diào)用。如果你想做逐幀動(dòng)畫(huà)的時(shí)候,你應(yīng)該用這個(gè)方法。這個(gè)回調(diào)函數(shù)會(huì)收到一個(gè)參數(shù),這個(gè)類(lèi)型的參數(shù)指示當(dāng)前時(shí)間距離開(kāi)始觸發(fā)的回調(diào)的時(shí)間。 window.requestAnimationFrame 概述 window.requestAnimationFrame()這個(gè)方法是用來(lái)在頁(yè)面重繪之前,通知瀏覽器調(diào)用一個(gè)指定的函數(shù),以滿足開(kāi)發(fā)者操作動(dòng)畫(huà)的需求。...

    Ilikewhite 評(píng)論0 收藏0
  • JS進(jìn)階--window.requestAnimationFrameTween.js配合使用實(shí)現(xiàn)

    摘要:注意如果想得到連貫的逐幀動(dòng)畫(huà),函數(shù)中必須重新調(diào)用。如果你想做逐幀動(dòng)畫(huà)的時(shí)候,你應(yīng)該用這個(gè)方法。這個(gè)回調(diào)函數(shù)會(huì)收到一個(gè)參數(shù),這個(gè)類(lèi)型的參數(shù)指示當(dāng)前時(shí)間距離開(kāi)始觸發(fā)的回調(diào)的時(shí)間。 window.requestAnimationFrame 概述 window.requestAnimationFrame()這個(gè)方法是用來(lái)在頁(yè)面重繪之前,通知瀏覽器調(diào)用一個(gè)指定的函數(shù),以滿足開(kāi)發(fā)者操作動(dòng)畫(huà)的需求。...

    codergarden 評(píng)論0 收藏0
  • JS進(jìn)階--window.requestAnimationFrameTween.js配合使用實(shí)現(xiàn)

    摘要:注意如果想得到連貫的逐幀動(dòng)畫(huà),函數(shù)中必須重新調(diào)用。如果你想做逐幀動(dòng)畫(huà)的時(shí)候,你應(yīng)該用這個(gè)方法。這個(gè)回調(diào)函數(shù)會(huì)收到一個(gè)參數(shù),這個(gè)類(lèi)型的參數(shù)指示當(dāng)前時(shí)間距離開(kāi)始觸發(fā)的回調(diào)的時(shí)間。 window.requestAnimationFrame 概述 window.requestAnimationFrame()這個(gè)方法是用來(lái)在頁(yè)面重繪之前,通知瀏覽器調(diào)用一個(gè)指定的函數(shù),以滿足開(kāi)發(fā)者操作動(dòng)畫(huà)的需求。...

    zorpan 評(píng)論0 收藏0
  • JS—?jiǎng)赢?huà)緩動(dòng)—tween.js

    摘要:動(dòng)畫(huà)運(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)超過(guò)范圍的三次方緩動(dòng)指數(shù)衰減的反彈緩動(dòng)。 requestAnimFrame兼容 window.requestAnimFrame = (function (callback,time) { return window.requestAnima...

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

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

0條評(píng)論

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