為什麼選擇GraphicsJS
前端可以選擇的svg庫,有很多,比如snap.svg或者BonsaiJS當然這些庫也是各有優勢。而這篇文章主要就是說GraphicsJS,讓大家知道他的優勢和特點。
- 輕量級,具備靈活的 Javascript API
- 來自AnyChart團隊,全球非常出名的視覺化團隊。
- GraphicsJS 是一個開源專案,無需商業授權
- 對於低版本的瀏覽器的支援,支援IE6
- 對於影像和動畫支援比較好,幫助開發者建立複雜的互動效果
GraphicsJS 基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<style> .stage{ width: 280px; height: 280px; } </style> <div class="stage" id="rect1"></div> <script src="https://cdn.anychart.com/js/latest/graphics.min.js"></script> <script> // create a stage var stage = acgraph.create('rect1'); // draw a rectangle stage.rect(25, 50, 200, 200); </script> ... |
進一步深入
填充,描邊和圖案填充
任何的形狀和路徑都可以使用fill 和 stroke屬性來修改起顏色屬性,但是隻有閉合和路徑或者形狀,才能夠使用fill屬性,而且你還可以使用漸變和圖片來進行填充。而且GraphicsJS還允許你自己定義填充的圖案。 下面我們來實現一個比較複雜的效果,實現一個人挨著一個房子(參考 sitepoints):
1 2 3 4 5 |
// create a label to count leaves var counterLabel = stage.text(10,10, "Swiped: 0", {fontSize: 20}); // a layer for the leaves var gameLayer = stage.layer().zIndex(counterLabel.zIndex()-1); |
如同程式碼裡的實現,所有的繪製都是通過stage裡面的方法,而且這條原型鏈上可以對該物件進行移除和修改。
接下來我們給圖形上點色彩。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function drawLeaf(x, y) { // choose a random color from a palette var index = Math.floor(Math.random() * 5); var fill = palette_fill[index]; var stroke = palette_stroke[index]; // generate random scaling factor and rotation angle var scale = Math.round(Math.random() * 30) / 10 + 1; var angle = Math.round(Math.random() * 360 * 100) / 100; // create a new path (leaf) var path = acgraph.path(); // color and draw a leaf path.fill(fill).stroke(stroke, 1, 'none', 'round', 'round'); var size = 18; path.moveTo(x, y) .curveTo(x + size / 2, y - size / 2, x + 3 * size / 4, y + size / 4, x + size, y) .curveTo(x + 3 * size / 4, y + size / 3, x + size / 3, y + size / 3, x, y); // apply random transformations path.scale(scale, scale, x, y).rotate(angle, x, y); return path; }; |
現在的效果類似我們又了一個穿裙子的人,站在城堡的旁邊,我們還可以方框的背景填充版權符號,我們可使用自定義填充模版。
1 2 3 4 5 |
path.listen("mouseover", function(){ path.remove(); counterLabel.text("Swiped: " + leavesCounter++); if (gameLayer.numChildren() < 200) shakeTree(300); }); |
我們非常輕鬆的建立一個文字,並且去生成一個填充圖案。
接下來我們建立一個簡單的互動遊戲
遊戲非常簡單就是使用者通過滑鼠掃除落葉。滑鼠滑過樹葉時候,樹葉會自動消失。
Layers, zIndex and the Virtual DOM
首先我們建立一些初始化變數
1 2 3 4 5 6 7 8 9 10 |
function shakeTree(n){ stage.suspend(); // suspend rendering for (var i = 0; i < n; i++) { var x = Math.random() * stage.width()/2 + 50; var y = Math.random() * stage.height()/2 + 50; gameLayer.addChild(drawLeaf(x, y)); // add a leaf } stage.resume(); // resume rendering } |
遊戲中我們需要使用layer,這是一個包含多個原色的物件,這些元素最好分成小組,以方便我們進行批量操作。在Demo中我們需要將樹葉放在一個組中,避免遮蓋了存放奇數的文字,因此我們還需要建立一個label然後使用stage.layer
,這樣我們通過設定zIndex讓樹葉的圖層在其下面。
1 2 3 4 5 |
// create a label to count leaves var counterLabel = stage.text(10,10, "Swiped: 0", {fontSize: 20}); // a layer for the leaves var gameLayer = stage.layer().zIndex(counterLabel.zIndex()-1); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function drawLeaf(x, y) { // choose a random color from a palette var index = Math.floor(Math.random() * 5); var fill = palette_fill[index]; var stroke = palette_stroke[index]; // generate random scaling factor and rotation angle var scale = Math.round(Math.random() * 30) / 10 + 1; var angle = Math.round(Math.random() * 360 * 100) / 100; // create a new path (leaf) var path = acgraph.path(); // color and draw a leaf path.fill(fill).stroke(stroke, 1, 'none', 'round', 'round'); var size = 18; path.moveTo(x, y) .curveTo(x + size / 2, y - size / 2, x + 3 * size / 4, y + size / 4, x + size, y) .curveTo(x + 3 * size / 4, y + size / 3, x + size / 3, y + size / 3, x, y); // apply random transformations path.scale(scale, scale, x, y).rotate(angle, x, y); return path; }; |
新增事件處理
在GraphicsJS 任何的物件 圖層,都可以處理事件,在這裡,你可以檢視到支援的事件型別.在這裡我們也需要給樹葉繫結mouse over的事件,當滑鼠滑過的時候,樹葉執行函式。
1 2 3 4 5 |
path.listen("mouseover", function(){ path.remove(); counterLabel.text("Swiped: " + leavesCounter++); if (gameLayer.numChildren() < 200) shakeTree(300); }); |
優化
繫結事件的virtual dom可以讓開發者自己去控制渲染,關於效能優化的建議可以看這裡。
為了讓我們能過持續看到效果,當樹葉數量減少的時候我們需要新增一些上去。
1 2 3 4 5 6 7 8 9 10 |
function shakeTree(n){ stage.suspend(); // suspend rendering for (var i = 0; i < n; i++) { var x = Math.random() * stage.width()/2 + 50; var y = Math.random() * stage.height()/2 + 50; gameLayer.addChild(drawLeaf(x, y)); // add a leaf } stage.resume(); // resume rendering } |
而該函的用途就是為了讓我們可以持續的新增新葉子。
效果如圖:
小結
H5徹底顛覆了web,而我們也開始接觸到大量對圖形的操作需求,這個時候不妨試一試graph.js 作為一個開源專案,它小巧而又強大,擁有足夠多的API去支援i 你的工作,並且你無需擔心瀏覽器相容性。官方還提供了足夠多的demo,大家可以去自己研究和學習。