
簡單的介紹
說到屏保,想必大家都很熟悉,它就是有動畫構成的,或簡單,或複雜。
但是,今天我們不僅要做出動畫,而且還要讓其有些“溫度”,能與我們進行互動。
好吧,讓我們先來看一些demo:(沒有移入滑鼠時)
加載的時,畫布上會出現一定數量的小圓圈,有大有小,不斷在畫布上移動。
當滑鼠移入時:
當使用者滑鼠移入畫布,在滑鼠範圍内的小圓形會逐漸被“放大”到一定值;當圓圈移出滑鼠位置時候,會恢複到原來的狀态。
那麼讓我們用Canvas來實作吧。
擷取畫布
首先我們先擷取html中的canvas元素,并對其設定:
document
了解arc
,也就是弧度繪制産生的圓心,也就是坐标
x值與
y值的相交點;
radius為弧度半徑;
startAngle起始的弧度;
endAngle結束的弧度;
anticlockwisefalse時為順時針繪制定義的弧度,true為逆時針繪制。
由此可以看出繪制一個圓形startAngle->endAngle 的參數應是0PI->2PI(π);
以上就是對arc(x, y, radius, startAngle, endAngle , anticlockwise),參數的了解。
從0-1
我們定義一個Circle構造函數,包括:
- draw函數依賴arc弧度畫圓。
- update函數對所畫圓形運動軌迹的限制。
我們在draw函數内使用arc繪制好了圓形,其所依賴的屬性都被指派到Circle私有屬性。通過update函數對draw函數進行了限制,使得draw函數按照我們的邏輯繪畫。
//聲明Circle函數依賴的全局變量
以上我們定義了圓形的最大半徑,最小半徑(沒有進行指派),存放5個顔色的數組支援Circle中的color屬性。
function
通過uptate我們對圓形的運動進行限制:
如圖所示,
- 一個圓運動,就是要控制center point的位置(x,y);
- 圓心cp在畫布x軸的移動極限為W-R,且圓自左向右運動x軸的數值會不斷增大;
- 圓心cp在畫布y軸的移動極限為H-R,且圓自上而下運動y軸的數值會不斷增大。
我們用偏移量dx,dy,控制W-R,H-R的數值大小變化,也就是構造函數Circle中x,y的極限距離。
繪制多個圓形執行個體
我們通過init函數中的循環來設定生成的Circle執行個體數量,然後追加到數組中。
var
function
requestAnimationFrame幀動畫接口:
現在我們需要依賴requestAnimationFrame使得我們的圓形動起來,
因為計時器setTimeout 以及 setInterval有些問題:
- 間隔時間不精确,可能被阻塞。計時器的間隔指的是将回調函數推入任務隊列的間隔時間,任務隊列中的任務隻有在主線程任務執行完畢後才會被執行。
- 計時器動畫的間隔時間如果設定過短就會出現過度渲染占用大量資源,如果設定過長就會影響動畫的流暢度。隻能夠估計合适的時間間隔。
- 多數浏覽器對于計時器動畫沒有優化。
是以我們使用requestAnimationFrame渲染動畫,需要處理浏覽器的相容性,我們先看一下各浏覽器相容情況:
處理requestAnimationFrame相容性:
//采用IIFE,處理requestAnimationFrame相容性
加入滑鼠互動
現在我們在update中加入滑鼠移入規則,為生成的圓形加入動畫互動,滑鼠移入圓形運動範圍内,使得圓不斷變大,當圓移動到滑鼠之外圓形變小。
//當滑鼠移入到x,y圓心的±40的時候
當然這時候我們需要注冊一個滑鼠移入的事件:
//添加mouse全局變量友善記錄mousemove事件中的x,y。
注冊全局mousemove事件來實時擷取浏覽器中滑鼠的位置x,y
window
我們列印下當滑鼠移入到浏覽器視窗時候,mouse.x與y實時記錄的滑鼠坐标,加深下印象:
完善動畫
注冊全局resize事件,當浏覽器視窗大小改變的時候,将浏覽器的可視範圍寬高指派給畫布的寬高。
window
思考總結
從0-1我們做了什麼:
- 首先我們了解arc方法支撐我們繪制圓形;
- 然後通過Circle函數中的draw方法調用畫布arc方法繪制了圓形;
- 通過animate方法中的requestAnimationFrame不停的調用自己完成了動畫;
- 通過update方法進行了動畫限制,包括圓運動範圍規則,滑鼠互動規則的定義;
- 當然我們也做了requestAnimationFrame的相容性,使我們的程式更加健壯。
但是細心的你會發現我們使用mousemove事件的時候,滑鼠在畫布上的值會被實時存放到mouse對象中,觸發事件的頻率很高,這樣也就影響到了我們動畫執行時候的性能,我們該如何解決呢?
下一個篇文章,我們将開始繪制wifi信号,請持續關注。