前端動畫
在前端領域裡,一共有幾種方式可以處理動畫
- CSS
animation
參考舊文 - CSS
transition
- SVG SMIL
<animate>
參考舊文 - JavaScript
setInterval
- JavaScript
setTimeout
- JavaScript
requestAnimationFrame
requestAnimationFrame
是一個專門用來處理動態的方法,相對於前5項作法,其用法也相當複雜(但同時也很精細)
注意他不支援IE9(含)以下
RAF(略)用法初探
requestAnimationFrame
的用法跟setInterval / setTimeout
有一點點很像
這3種動畫函數都是window呼叫(並且都能省略window)
塞的第一個值都必須是動作的function
不過,setInterval / setTimeout都要指定第二個值:「秒數」
然後RAF不用塞秒數,所以我們只要寫成這樣就好▼
window.requestAnimationFrame(function(timestamp){
console.log(timestamp)
})
注意RAF塞進去的第一個值:函數的裡面
我又在塞了一個callback name:timestamp
這個callback name名字隨意取就行,不叫timestamp
也可以
這個timestamp
代表什麼。我們開啟開發者工具看看console.log(timestamp)
的回傳結果
timestamp
回傳的結果是「毫秒」
第一個值15147.488
毫秒,換算成正常秒數約等於15
秒。代表我打開這個網頁後,等了大約15
秒後,我才打開了開發面板,鍵入了window.requestAnimationFrame(...)
這坨函數
第二個值16281.32
毫秒,約等於16
秒。等於網頁準備好後過了16
秒,window.request...(...)
才被執行(所以他跟第一個console相距1
秒)
但是,實務上執行動畫時不能夠像這樣一直key函數上去,所以需要改寫成循環函數,讓RAF可以不斷地被重複執行
function call(timestamp){
console.log(timestamp);
window.requestAnimationFrame(call);
}
window.requestAnimationFrame(call);
【補充說明】
想要抓到RAF的index時,可以這樣做
function call(timestamp){
var idx=window.requestAnimationFrame(call);
console.log(idx);
}
window.requestAnimationFrame(call);
實作動態
本次實作利用rgb
參數調整的方式
做出動態的變色效果
b
值最小為0
b
值最大為255
⑴ 用canvas
畫一個圓
canvas#canvas(width=500 height=500)
canvas
border: 1px solid #000
width: 250px
height: 250px
var ctx=canvas.getContext('2d');
ctx.beginPath();
ctx.arc(250, 250, 100, 0, 2*Math.PI, false);
ctx.fill();
⑵ 加入RAF函數
定義每毫秒colorIndex
就會跑一次
- 當
colorIndex
加到255
時,反向遞減 - 當
colorIndex
減到0
時,又變成遞增
var colorIndex=0;
var isPlus=true;
function call(timestamp){
if(colorIndex==255){
isPlus=false;
}
if(colorIndex==0){
isPlus=true;
}
if(isPlus==true){
colorIndex++;
}else{
colorIndex--;
}
ctx.fillStyle=`rgb(0, 150, ${colorIndex})`;
ctx.fill();
window.requestAnimationFrame(call);
}
window.requestAnimationFrame(call);
⑶ RAF的停止
停止運作要用到cancelAnimationFrame
這個方法
用法如下
cancelAnimationFrame(★這裏填入要停下的RAF★)
★要停下的RAF★
可以用變數的方式預先儲存好
完整範例如下
canvas#canvas(width=500 height=500)
button(onclick="stopAnimation()") STOP IT
canvas
border: 1px solid #000
width: 250px
height: 250px
var ctx=canvas.getContext('2d');
ctx.beginPath();
ctx.arc(250, 250, 100, 0, 2*Math.PI, false);
ctx.fill();
var colorIndex=0;
var isPlus=true;
var myAnimation;
function call(timestamp){
if(colorIndex==250){
isPlus=false;
}
if(colorIndex==0){
isPlus=true;
}
if(isPlus==true){
colorIndex++;
}else{
colorIndex--;
}
ctx.fillStyle=`rgb(0, 150, ${colorIndex})`;
ctx.fill();
myAnimation=window.requestAnimationFrame(call);
}
window.requestAnimationFrame(call);
function stopAnimation(){
window.cancelAnimationFrame(myAnimation);
}