KonvaJS 快速入門
Konva 是一個 基於 Canvas 開發的 2d js 框架庫, 它可以輕松的實現桌面應用和移動應用中的圖形交互交互效果.
Konva 可以高效的實現動畫, 變換, 節點嵌套, 局部操作, 濾鏡, 緩存, 事件等功能, 不僅僅適用於桌面與移動開發, 還有更為廣泛的應用.
Konva 允許在舞台上繪圖, 添加事件監聽, 移動或縮放某個圖形, 獨立旋轉, 以及高效的動畫. 即使應用中含有數千個圖形也是可以輕松實現的.
使用 Konva
- 打開鏈接 http://konvajs.github.io/, 下載 KonvaJS 代碼.
- 開發中為了方便調試, 使用完全版. 實際使用使用壓縮版.
- 使用 script 標簽導入需要使用的 Konva 庫. <script src="konva.js"></script>
KonvaJS 的理念
任何圖形都存在於舞台中( Konva.Stage ). 這個舞台中又可以包多個用戶層( Konva.Layer ).
每一個層中都含有兩個 <canvas> 着色器: 一個前台渲染器, 一個后台渲染器. 前台渲染器是可以看見的部分, 而后台渲染器是一個隱藏的 canvas. 后台渲染器為了提高效率實現事件監聽的工作.
每一個層可以包含形狀( Shape ), 形狀的組( Group ), 甚至是由組組成的組. 舞台, 層, 組, 以及形狀都是虛擬的節點( node ). 類似於 HTML 頁面中的 DOM 節點.
例如:
在這個圖形中, 首先有一個舞台( Stage ). 該舞台在頁面中與整個頁面的大小一樣. 然后舞台中有一個層( Layer ). 層中有一個矩形( Rect )和一個圓形( Circle ). 因此就有一個樹結構:
所有的節點都可以設置樣式與變化. 即使 Konva 可以重新渲染形狀, 例如: 矩形, 圓形, 圖片, 精靈, 文本, 線段, 多邊形, 正多邊形, 路徑, 和星星等. 但是開發者依舊可以根據 Shape 類的模板自定義自己的圖形, 然后重寫 draw
方法.
只要擁有了 舞台( Stage ), 並且上面放置了層( Layer )和圖形( Shape ), 那么就可以為他添加事件監聽, 變換節點, 運行動畫, 使用路徑, 甚至是更多的效果.
例如要實現上面的案例:
- 需要引入 Konva.js 文件
<script src="konva.js"></script>
- 然后頁面中放置一個容器作為 Konva 處理的對象. Konva 會在該容器中添加 canvas 標簽. 值得說明的是, 需要為這個標簽添加 id 屬性.
<div id="dv"></div>
- 然后編寫 js 代碼. Konva 是一個完全面向對象的庫.
- 創建舞台
var stage = new Konva.Stage({ container: 'dv', width: window.innerWidth, height: window.innerHeight });
- 首先, 在 Konva 中所有的圖形都是在 Konva 中的一個構造函數. Konva 是全局的命名空間.
- 創建舞台使用的是 Stage 構造函數. 該函數需要提供參數.
- Konva 中所有圖形的參數都是使用 json 對象的方式進行提供.
- 舞台需要設置容器的 id, 即 container 屬性. 以及寬( width ), 高( height ).
- 舞台中可以放置一個到多個層( Layer ), 所有的圖形應該放在在層中.
- 首先創建層對象. 層對象不需要傳遞參數.
var layer = new Konva.Layer();
- 將層添加到舞台中. Konva 中凡是添加, 都是使用 add 方法.
stage.add( layer );
- 首先創建層對象. 層對象不需要傳遞參數.
- 在層中放置一個矩形, 就創建一個 矩形對象.
- 矩形對象需要四個參數來確定, 分別是 左上角的兩個坐標, 和 寬與高.
var rect = new Konva.Rect({ x: 100, y: 50, width: 200, height: 100, fill: 'red' });
- Konva 中添加顏色使用 fill 屬性和 stroke 屬性, 分別表示填充顏色與描邊顏色.
- 將矩形添加到 層中
layer.add( rect );
- 矩形對象需要四個參數來確定, 分別是 左上角的兩個坐標, 和 寬與高.
- 在層中添加一個圓形, 使用構造函數 Circle
var circle = new Konva.Circle({ x: stage.getWidth() / 2, y: stage.getHeight() / 2, radius: 100, fill: 'pink', stroke: 'blue' }); layer.add( circle );
- Konva 中使用 radius 設置圓形的半徑.
- Konva 中如果需要獲取對象的數據, 使用 getXXX 方法. 傳入參數即設置, 不傳參數就是獲取數據.
-
layer.draw();
基本形狀
Konva.js 支持的形狀有: 矩形( Rect ), 圓形( Circle ), 橢圓( Rllipse ), 線段( Line ), 圖像( Image ), 文本( Text ), 文本路徑( TextPath ), 星星( Start ), 標簽( Label ), SVG 路徑( SVG Path ), 正多邊形( RegularPolygon ). 同時也可以自定義形狀.
- 自定義形狀使用 Shape 構造函數創建
- 需要提供自定義的繪圖方法 sceneFunc
var triangle = new Konva.Shape({ sceneFunc: function ( ctx ) { // 自定義繪圖路徑 ctx.moveTo( window.innerWidth / 2, window.innerHeight / 4 ); ctx.lineTo( window.innerWidth / 2 - window.innerHeight / ( 2 * 1.732 ), window.innerHeight * 3 / 4 ); ctx.lineTo( window.innerWidth / 2 + window.innerHeight / ( 2 * 1.732 ), window.innerHeight * 3 / 4 ); ctx.closePath(); // Konva.js 的獨有方法 ctx.fillStrokeShape( this ); }, fill: 'pink', stroke: 'red' });
- 將圖形添加后繪圖
layer.add( triangle ); layer.draw();
效果:
樣式
所有的形狀都支持下列樣式屬性:
- 填充. 顏色, 漸變或圖片.
- 描邊. 顏色與寬度.
- 陰影. 顏色, 偏移量, 透明度與模糊
- 透明度
繪制正五邊形
構造函數: Konva.RegularPolygon( options )
常用屬性:
- x, y. 表示正多邊形的中心坐標.
- sides. 表示正多邊形的邊數.
- radius. 表示半徑.
- fill. 填充顏色.
- stroke. 描邊的顏色.
- strokeWidth. 描邊的寬度.
- shadowOffsetX 和 shadowOffsety. 描述背景的偏移量.
- shadowBlur. 表示模糊程度.
- opacity. 表示透明度( 取值在 0, 1 之間 ).
案例
var shape = new Konva.RegularPolygon({ x: stage.getWidth() / 2, y: stage.getHeight() / 2, sides: 5, radius: 70, fill: 'red', stroke: 'black', strokeWidth: 4, shadowOffsetX: 20, shadowOffsetY: 25, shadowBlurBlur: 40, opacity: 0.5 }); layer.add( shape );
效果
事件
使用 Konva 可以輕松的實現監聽用戶添加的事件. 例如 click, dblclick, mouseover, tap, dbltap, touchstart 等. 屬性值變化事件. 例如 scaleXChange, fillChange 等. 以及拖拽事件. 例如 dragstart, dragmove, dragend.
circle.on( 'mouseout touchend', function () { console.log( '用戶輸入' ); }); circle.on( 'xChange', function () { console.log( '位置發生改變' ); }); circle.on( 'dragend', function () { console.log( '拖動停止' ); });
拖拽與降低
Konva 支持拖拽的功能. 也支持下降事件( drop, dropenter, dropleave, dropover ).
如果需要實現拖拽的功能. 可以設置 draggable 屬性為 true.
- 創建的時候設置屬性
- 創建后使用方法設置屬性 shape.draggable( true );
Konva 還支持給拖拽事件添加移動范圍.
動畫
Konva 中可以使用兩種方式創建動畫
- 使用 Konva.Animation
var anim = new Konva.Animation(function ( frame ) { var time = frame.time, timeDiff = frame.timeDiff, frameRate = frame.frameRate; // 更新代碼 }, layer );
2.使用 Konva.Tween
var tween = new Konva.Tween({ node: rect, duration: 1, x: 140, rotation: Math.PI * 2, opacity: 1, strokeWidth: 6 }); // 或者使用新的短方法
circle.to({ duration: 1, fill: 'green' });
選擇器
當構建規模較大的應用時, 如果可以對元素進行搜索是非常方便的. Konva 使用選擇器來實現元素的查找. 使用 find() 方法返回一個集合. 使用 findOne() 方法返回集合中的第 0 個元素.
-
- 給元素提供 name 屬性, 可以使用 '.name' 來進行獲取. 類似於類選擇器.
- 使用構造函數的名字也可以作為名字選擇器. 類似於標簽選擇器.
- 使用 id 屬性, 則使用 '#id' 來獲取.
- 查找方法使用層對象來調用.
序列號與反序列化
所有被創建的對象都可以保存為 JSON 對象. 可以在服務器或本地存儲中使用它.
var json = stage.toJSON();
同時, 也可以從 JSON 中恢復 Konva 對象.
var json = '{"attrs":{"width":578,"height":200},' +
'"className":"Stage", ' +
'"children":[{ ' +
'"attrs":{},' +
'"className":"Layer",' +
'"children":[ ' +
'{"attrs":{ ' +
'"x":100,"y":100,' +
'"sides":6,"radius":70,' +
'"fill":"red","stroke":"black",' +
'"strokeWidth":4},' +
'"className":"RegularPolygon"}' +
']' +
'}]}'; var stage = Konva.Node.create(json, 'container');