打造高大上的Canvas粒子動畫
很酷炫!
那如何去實現類似上面的粒子動畫甚至根據自己的喜好去做更多其他軌跡的動畫呢~請看下面詳細的講解。
技術選擇
因為粒子數量很多,而且涉及到圖像像素處理,所以這裡使用Canvas是不二選擇。
注意,以下演示的代碼只是關鍵代碼,重點在於解決思路。
一、繪製粒子輪廓圖
首先要在canvas畫布上繪製一個由粒子組成的輪廓圖,記錄下每一個粒子的坐標,這樣才能有後續的動畫。
1. 創建一個元素,並獲取Canvas畫布渲染上下文
是一個雙標籤元素,通過width和height的值來設置畫布的大小。至於ctx(畫布渲染上下文),可以理解為畫布上的畫筆,我們可以通過畫筆在畫布上隨心所欲的繪製圖案。如果瀏覽器不支持canvas會直接顯示標籤中間自己設定的文字。當然標籤中間也可以是一張當不支持canvas時需要替換顯示的圖片。
2. 使用canvas的圖像操作API繪製圖像
繪製圖像的關鍵API及參數說明:
引用MDN上的一張圖會比較清晰的看出每個參數的作用:
drawImage就是把一個image對象或者canvas上(甚至是video對象上的的每一幀)指定位置和尺寸的圖像繪製到當前的畫布上。而在我們的需求中,是要把整個圖像繪製到畫布中。
對應瀏覽器看到的效果:
3. 獲取圖像的像素信息,並根據像素信息重新繪製出粒子效果輪廓圖
canvas有一個叫getImageData的介面,通過該介面可以獲取到畫布上指定位置的全部像素的數據:
把獲取的imageData輸出到控制台可以看到,imageData包含三個屬性:
其中,width、height是讀取圖像像素信息完整區域的寬度和高度,data是一個Uint8ClampedArray類型的一維數組,包含了整個圖片區域里每個像素點的RGBA的整型數據。這裡必須要理解這個數組所保存像素信息的排序規則,請看下圖描述的data數組:
每一個色值佔據data數組索引的一個位置,一個像素有個4個值(R、G、B、A)佔據數組的4個索引位置。根據數列規則可以知道,要獲取第n個位置(n從1開始)的R、G、B像素信息就是:Rn = (n-1)*4 ,Gn = (n-1)*4+1 ,Bn = (n-1)*4+2,so easy~ 當然,實際上圖像是一個包括image.height行,image.width列像素的矩形而不是單純的一行到結束的,這個n值在矩形中要計算下:
由於一個像素是帶有4個索引值(rgba)的,所以拿到圖像中第i行第j列的R、G、B、A像素信息就是 Rij = [(j-1)*imageData.width + (i-1)]*4 ,Gij = [(j-1)*imageData.width + (i-1)]*4 + 1,Bij = [(j-1)*imageData.width + (i-1)]*4 + 2,Aij = [(j-1)*imageData.width + (i-1)]*4 + 3。每個像素值都可以拿到了!
接下來就要把圖像的粒子化輪廓圖畫出來了。那麼,怎麼做這個輪廓圖呢,我們先讀取每個像素的信息(用到上面的計算公式),如果這個像素的色值符合要求,就保存起來,用於繪製在畫布上。另外,既然是做成粒子的效果,我們只需要把像素粒子保存一部分,展示在畫布上。
具體做法是,設定每一行和每一列要顯示的粒子數,分別是cols和rows,一個粒子代表一個單元格,那麼每個單元格的的寬高就是imageWidth/cols和imageHeight/rows,然後循環的判斷每個單元格的第一個像素是否滿足像素值的條件,如果滿足了,就把這個單元格的坐標保存到數組裡,用作後續繪製圖案用。
關鍵參考代碼:
用完整代碼做出的demo及效果:
至此,粒子輪廓圖已經製作完成。
二、製作粒子動畫
製作粒子動畫分兩種:
一種是粒子漂浮類,這種比較簡單,只需要隨機的改變每個粒子的位置值,然後一直執行setInterval或者requestAnimationFrame重繪畫布即可,具體的效果因人喜好而去設定,就不具體講解了,做了個簡單的粒子漂浮的例子。
另一種是粒子的軌跡動畫,這個相對複雜一些。這裡要介紹的是每個粒子按照指定的軌跡在指定的時間內做位移,最終匯聚成指定圖案的動畫效果(也就是文章一開始的動效),要做成這類動畫效果需要解決兩個問題:一個是動畫軌跡,另外一個是每個粒子執行動畫的時機。
粒子動畫軌跡
動畫位移的軌跡,最常見的就是單位時間內改變固定的位移值,從而達到動畫效果。但要做到炫酷的效果依賴這種單調固定的位移肯定是不行的。所以位移可以依賴緩動函數去做到單位時間內改變不一樣的位移值,從而達到特別的效果。
製作緩動效果有兩種方法:
一種是自己設定好控制點,然後通過貝塞爾曲線公式來計算每個單位時間的坐標值。
引用了wikipedia裡面的圖:
上面兩個圖都是在繪製一條特定曲線,可以看出二次曲線需要一個特定控制點P1,三次曲線需要兩個特定控制點P1和P2來確定一條曲線,高階曲線甚至需要更多的控制點來確定曲線軌跡。
求曲線的公式是根據德卡斯特里奧演算法計算得來的,直接上公式。
二次曲線對應的公式:
三次曲線對應的公式:
從公式可以看出,只要確定控制點坐標、起始坐標和終點坐標後,就可以確定了一條曲線,然後就可以根據曲線公式求出每個時刻t對應的位置值B(t)。
當然使用這種方法需要自己去制定控制點坐標,計算也比較複雜,實現起來很繁瑣。沒事,我們還有別的辦法確定曲線。
是不是覺得很熟悉?對沒錯,jquery用的動畫擴展插件easing.js就是Tween演算法的緩動函數。有了這現成的緩動函數,就可以制定粒子的起始點、終點(終點就是圖案本身的坐標位置)以及動畫執行持續時間來做我們要的效果。
根據參考代碼做出一個效果:
嗯,動畫效果是有了,但總感覺不太對勁。。。唔,仔細觀察一下,是圖案動畫執行太過整體了,沒有明顯的顆粒動畫效果,這就引出粒子動畫的另一個關鍵點,粒子執行動畫的時機。
粒子執行動畫的時機
要讓粒子效果比較明顯,那就不能讓動畫效果執行太過整體了,需要讓圖案上每個粒子有不同的時間間隔啟動,根據一定的規律交錯的執行動畫。這裡的粒子啟動間隔有兩種,一種是每一行粒子執行時間間隔,要讓每一行的粒子啟動時間有規律錯開;另外一種是每一行粒子之間啟動時間隨機的錯開,這樣執行的粒子動畫才會有一種層次感和每個粒子有獨立動畫的顆粒感。看下加了粒子啟動時間間隔之後的效果對比:
比上面不加粒子啟動時間間隔的效果好多了。
Metropolis-Hastings 演算法和 Gibbs sampling 演算法
獨家解密:探月「網紅」兔背後的推手
海報設計靈感:簡約獨特的圖形圖案排版 by Quim Marin
量子通信衛星上天,VR遊戲時代的黎明也快到了?
廣告人挖腦溝想創意,有人成就經典,有人只是挖溝
TAG:推酷 |
※帶大家用JavaScript做一個2D粒子效果
※专访Gary Sanders:从粒子加速器、引力波到巨型望远镜
※節點式三維粒子插件Superluminal Stardust新版本即將發布
※C4D粒子插件X-Particles 4新功能搶先看
※AE教程:用Particular製作粒子光線效果
※專訪Gary Sanders:從粒子加速器、引力波到巨型望遠鏡
※CooYoo 粒子 Partice XX 9600流明小鋼炮搜索手電筒
※Photoshop設計人像被粒子打散特效效果
※理科系福利?《ParticleBoys~素粒子男子》擬人企劃
※Small Methods:多路復用的熒光團-納米粒子複合結構用於拓展pH檢測範圍
※Photoshop製作衝擊粒子主題的3D海報教程
※Unity粒子遇上著色器,引爆視覺特效
※AE插件:超強三維點線面粒子插件破解版Rowbyte Plexus v3.0.11
※張首晟團隊宣布發現天使粒子-神秘的Majorana費米子
※張首晟院士宣布天使粒子—Majorana費米子的發現,使構造穩固的拓撲量子計算機成為可能
※今日Nature:超順磁納米粒子大幅度提升熱電性能
※教程!PPT中炫酷的粒子效果是怎麼做的
※諾獎得主Wilczek:粒子物理學將去往何方?
※能閃瞎狗眼的不止是狗男女秀的恩愛還有CooYoo粒子X9