文章目錄
- 前言
- 簡介
- 什么是 Konva?
- 安裝 Konva
- 概述
- 它是如何工作的?
- 基本形狀
- 樣式
- 事件
- 拖放
- 濾鏡
- 動畫
- 選擇器
- 序列化與反序列化
- 性能
前言
結合項目實際業務需求,在 Fabric、Konva 等圖形化框架中,我選擇了性能表現好的 Konva。首先去學習官方文檔和示例,以下是 Konva 的相關文檔地址:
- Konva 官網
- Github
- Konva 中文文檔
我是在豆包的瀏覽器中打開 Konva 官網,其自帶全文翻譯功能,可以快速查看中文內容。
簡介
什么是 Konva?
Konva 是一個 HTML5 畫布 JavaScript 框架,它通過為桌面和移動應用程序實現畫布交互性來擴展 2D 上下文。
Konva 可為桌面和移動應用程序實現高性能動畫、過渡效果、節點嵌套、分層、過濾、緩存、事件處理等諸多功能。
你可以在舞臺上繪制圖形,為它們添加事件監聽器,對它們進行移動、縮放和旋轉操作,這些操作與其他形狀相互獨立,以支持高性能動畫,即使你的應用程序使用了數千個圖形。
安裝 Konva
下面列出了三種安裝命令,任選一種:
npm install konva --saveyarn add konvapnpm add konva
概述
它是如何工作的?
所有內容都從 Konva.Stage 開始,它包含若干用戶圖層(Konva.Layer)。
每一層都有兩個 <canvas>
渲染器:一個場景渲染器(Scene Canvas)和一個圖像命中渲染器(Hit Canvas)。場景渲染器是你能看到的內容,而圖像命中渲染器是一個特殊的隱藏畫布,用于高性能的事件檢測。
在 Hit Canvas 中,所有元素會被繪制為唯一顏色標識(如 rgb(1, 0, 0)對應 ID 為 1 的元素)。這種顏色與可視元素的樣式無關,僅用于身份識別。當觸發鼠標/觸摸事件時,Konva 通過 context.getImageData()讀取 Hit Canvas 對應坐標的像素值,將像素值轉換為元素 ID,實現毫秒級事件目標識別。
每一層都可以包含形狀、形狀組或其他組的組。Stage(舞臺)、layers(圖層)、groups(組)和 shapes(圖形)都是虛擬節點,類似于 HTML 頁面中的 DOM 節點。
注意:創建一個 Layer(圖層)時,會自動創建 2 個 Canvas 元素,從性能方面考慮,最多創建 3 個 Layer(圖層)。
以下是一個節點結構示例層級:
Stage|+------+------+| |Layer Layer| |+-----+-----+ Shape| |Group Group| |+ +---+---+| | |Shape Group Shape|+|Shape
所有節點都可以設置樣式和進行變換。雖然 Konva 有預構建的形狀,如矩形、圓形、圖像、精靈圖、文本、線條、多邊形、正多邊形、路徑、星形等,但你也可以通過實例化 Shape 類并創建一個繪制函數來創建自定義形狀。
一旦你使用圖層和形狀搭建好了一個場景,就可以綁定事件監聽器、變換節點、運行動畫、應用濾鏡等等。
最小代碼示例:
// first we need to create a stage
var stage = new Konva.Stage({container: 'container', // id of container <div>width: 500,height: 500,
})// then create layer
var layer = new Konva.Layer()// create our shape
var circle = new Konva.Circle({x: stage.width() / 2,y: stage.height() / 2,radius: 70,fill: 'red',stroke: 'black',strokeWidth: 4,
})// add the shape to the layer
layer.add(circle)// add the layer to the stage
stage.add(layer)
基本形狀
Konva.js 支持以下形狀:矩形、圓形、橢圓、直線、多邊形、樣條曲線、不規則圖形、圖像、文本、文本路徑、星形、標簽、SVG 路徑、正多邊形。你還可以創建自定義形狀:
var triangle = new Konva.Shape({sceneFunc: function (context) {context.beginPath()context.moveTo(20, 50)context.lineTo(220, 80)context.quadraticCurveTo(150, 100, 260, 170)context.closePath()// special Konva.js methodcontext.fillStrokeShape(this)},fill: '#00D2FF',stroke: 'black',strokeWidth: 4,
})
樣式
每個形狀都支持以下樣式屬性:
- 填充。純色、漸變或圖像
- 描邊(顏色,寬度)
- 陰影(顏色、偏移量、不透明度、模糊度)
- 不透明度
var pentagon = new Konva.RegularPolygon({x: stage.width() / 2,y: stage.height() / 2,sides: 5,radius: 70,fill: 'red',stroke: 'black',strokeWidth: 4,shadowOffsetX: 20,shadowOffsetY: 25,shadowBlur: 40,opacity: 0.5,
})
事件
使用 Konva,你可以輕松監聽用戶輸入事件(click、dblclick、mouseover、tap、dbltap、touchstart 等)、屬性更改事件(scaleXChange、fillChange)以及拖放事件(dragstart、dragmove、dragend)。
circle.on('mouseout touchend', function () {console.log('user input')
})circle.on('xChange', function () {console.log('position change')
})circle.on('dragend', function () {console.log('drag stopped')
})
參閱綁定事件示例
拖放
注意:拖拽 drag 和 拖放 drop 是不一樣的。拖拽 drag 是指在畫布上移動元素,而拖放 drop 是指在畫布上將元素放置在某個位置。
Konva 有內置的拖拽支持。目前沒有 drop 事件(drop、dragenter、dragleave、dragover),但通過框架實現它們非常容易,參閱拖放事件示例。
要啟用拖放功能,只需將屬性 draggable 設置為 true。
接下來你就可以參閱 drag&drop 事件和設置移動限制
濾鏡
Konva 提供了多種濾鏡:blur, invert, noise 等等。 參閱濾鏡 API
動畫
你可以通過兩種方式創建動畫:
- 通過 Konva.Animation Demo
- 通過 Konva.Tween Demo
選擇器
在構建大型應用程序時,在元素中使用搜索功能非常有用。Konva 可幫助您通過選擇器查找元素。您可以使用 find() 方法(返回集合)或 findOne() 方法(返回集合的第一個元素)。
var circle = new Konva.Circle({radius: 10,fill: 'red',id: 'face',name: 'red circle',
})
layer.add(circle)// then try to search// find by type
layer.find('Circle') // returns array of all circles// find by id
layer.findOne('#face')// find by name (like css class)
layer.find('.red')
序列化與反序列化
所有創建的對象都可以保存為 JSON 格式。你可以將其保存到服務器或本地存儲中。
var json = stage.toJSON()
此外,你可以從 JSON 中恢復對象:
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')
性能
Konva 提供了一些提升性能的工具。
主要的方法有:
1.緩存
Caching 允許你在 buffer canvas 里繪制元素,然后再通過 buffer canvas 繪制到場景,它能提升繪制復雜節點例如:文本、包含陰影或者描邊的圖形。 Demo
shape.cache()
2.圖層
框架支持創建任意數量的 <canvas>
。如果你的應用包含復雜的背景和許多可以移動的圖形,你可以使用一個圖層顯示背景,另一個圖層顯示圖形,從而只更新圖形而不更新背景。 Demo
你可以在此處找到所有可用的性能提示:https://konvajs.org/docs/performance/All_Performance_Tips.html