還記得之前的活動「The F2E - 前端修練精神時光屋」嗎?我們在活動中期製作了一個匯集每位 UI 設計師投稿的作品牆,而這些東西是怎麼做出來的呢?

pixi

要是你還沒看過動畫,可以看看 精神時光屋

這邊的動畫,是使用 Pixi.js 撰寫的──Pixi.js 是個輕量、快速的 2D 渲染框架,預設會使用 WebGL 來加速渲染,在不支援的裝置則會用 canvas 和 SVG 來支援(所以在手機也能用)。除了可以用來渲染素材、做簡單而大量的視覺化以外,也可以用來當作遊戲引擎,例如 Phaser.js 就是以 Pixi.js 為底而製作的(雖然新版的 Phaser 並沒有在用 Pixi 了)。

在 Pixi.js 提供的 API 中,我們可以輕易地建立一個舞臺、載入並快取一些資源、再修改每個物件的時間、計時器等等。不過也有一些缺點,例如不支援 3D(所以我們看起來像 3D 的東西是怎麼做的呢,顆顆),不過這些缺點已經在下一個版本(v5)的草案出現了,所以可以預期下一個版本會補完這些功能。

初始化 Pixi.js

首先我們需要建立一個 PIXI.Container,之後的元素都會放在這個 Container 上。接著一開始先載入底圖並放到舞臺上,同時加入 Loading... 、百分比字眼,以及從 API 拿的報名人數。

載入各個投稿圖片

載入的這個細節就很複雜了。首先要先麻煩這個網站的後端工程師提供各個投稿圖片的 API,而且為了載入快速(你總不希望每個使用者拿手機進來都要先載入 2GB 的流量吧 XD)還必須先把這些圖片縮小、壓縮過。另外,由於這些圖片的節點並不在臺灣,載入速度不太快,我們也用了 CloudFlare 的 CDN 服務來協助快取、快速載入它。

偏後端的地方都整理完以後,在前端使用這個 API 讀出圖片列表,並隨機選出 500 張圖片讀進 Pixi 的載入器中,讓他載入,載入的同時我們要跑 Loading 的百分比。

正片開始

相關圖片都載入完後,我們先取前 480 張隨機擺放在 Container 上。這邊指的不是隨機 x, y 位置,而是都使用固定比例,例如 $(0, 0)、(40, 0)、(80, 0)、...、(0, 20)...$ 等座標。

接著剩下的 20 張一開始隨機放在舞臺外面,再飛進來替換掉原本已經在舞台上的圖。為了讓畫面看起來沒那麼亂,我們要去判斷圖片在第幾象限,例如圖片如果舞台的右上角外面的話,就只能飛到第一象限的區域,這樣才不會有太多圖片路線交錯的情形。同時,為了達到「假 3D」的效果,我們還得去計算它的質心距離目標位置還有多遠,以此為依據更改每張圖片的縮放比例及透明度。

最後則是用一個計時器去連續、隨機跑 20 張圖片來交替,讓動畫無限延續。