摘要:注意如果想得到連貫的逐幀動(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)):
兼容寫(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
摘要:注意如果想得到連貫的逐幀動(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à)的需求。...
摘要:注意如果想得到連貫的逐幀動(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à)的需求。...
摘要:注意如果想得到連貫的逐幀動(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à)的需求。...
摘要:動(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...
閱讀 2500·2021-11-17 09:33
閱讀 796·2021-11-04 16:13
閱讀 1358·2021-10-14 09:50
閱讀 718·2019-08-30 15:53
閱讀 3693·2019-08-30 14:18
閱讀 3287·2019-08-30 14:14
閱讀 2127·2019-08-30 12:46
閱讀 3208·2019-08-26 14:05