休息 3 個月,基於 Canvas 寫了個簡單的前端繪圖 JavaScript 框架
前言
不知不覺,有一年沒發佈公衆號文章了,這段時間剛好有空,就抽時間寫了這篇文章。本文主要講解我裸辭 3 個月以來,利用在家休息的空隙時間,開發了一個前端繪圖的 JavaScript 庫 iDraw.js。
爲啥要開發這個東西
爲了實現用純 Canvas 能力結合圖片、HTML 和 SVG 作爲素材 來做繪圖功能。
爲了試試看單獨用 Canvas 的 2D(二維)API 能作出怎樣的多種素材繪圖實現。
最後是爲了試試看盡量用 Canvas 能實現多複雜的繪圖素材操作。
目前我的認知中,還沒發現類似的可以操控素材繪圖的 Canvas 開源框架,所以就想自己開發一個。
iDraw.js 簡介
一個基於純 Canvas 的 2D API 來實現繪圖和操控素材能力的 JavaScript 庫。
可以基於 iDraw.js 進行擴展自定義開發各種可視化操控應用,這裏可以訪問 idraw.js.org/playground/ 的顯示例子,或者訪問 idraw.js.org/studio/ 查看基於 iDraw.js 實現的畫圖案例。
iDraw.js 有哪些功能
支持繪製文字、矩形、圓形、圖片、HTML 片段和 SVG 片段 繪圖元素
繪製文字
繪製矩形
繪製圓形
繪製圖片
繪製 HTML 片段
繪製 SVG 片段
以上這些功能都是基於 Canvas 的 2D API 實現的可視化操作。
iDraw.js 有哪些特點
可以繪製文字、矩形、圓形、圖片、HTML 片段和 SVG 文件,並且作爲繪圖元素。
可以直接在 Canvas 操控以上繪圖元素,不用擔心 CSS 和 DOM 變化的污染問題。
Canvas 操控繪製,並且是所見即所得可以直接導出繪製的圖片結果。由於可視化操控和圖片生成都是基於 Canvas,可以儘量減少繪圖的瀏覽器兼容問題。
可以通過快捷鍵來複制、剪切、粘貼各種元素。
原理介紹
基於數據驅動來繪製 Canvas 的圖畫,所有繪圖元素都用 JSON 的數據格式來描述的。
基於 requestAnimationFrame 來控制數據變化時候,控制 Canvas 的重繪處理,使得在操控繪圖元素的時候操作保持操作流暢減少卡頓。
內置一個前端併發隊列來處理 圖片、HTML 和 SVG 的圖片化轉換渲染。
如何使用
安裝 npm 模塊
npm install idraw
渲染繪畫
import iDraw from 'idraw';
const app = document.querySelector('#app');
const options = {
width: 600,
height: 400,
contextWidth: 600,
contextHeight: 400,
devicePixelRatio: 2,
};
const idraw = new iDraw(app, options);
idraw.addElement({
name: "rect-001",
x: 140,
y: 120,
w: 200,
h: 100,
type: "rect",
desc: {
bgColor: "#f7d3c1",
borderRadius: 20,
borderWidth: 4,
borderColor: "#ff6032",
},
});
更多使用方式可以查看文檔或者 Playground 演示
實際使用案例
一個基於 iDraw.js 實現的 UI 可視化繪圖,@idraw/studio 的實現。
總結心得
Canvas 的 2D Context API 實在比較好用,可以自由繪圖。同時可以通過 JS 將不同數據格式轉換成 DataURL,例如將 HTML 和 SVG 等代碼片段轉換後,在 Canvas 中直接渲染。
但是如果 HTML 渲染的 CSS 內容比較複雜的話,在操控元素移動變化時候會出現比較明顯的掉幀和卡頓,即使我使用了 requestAnimationFrame 來控制幀率的渲染也一樣。如果需要做複雜情況下的性能優化,需要在後續計劃中加入 WebGL 的渲染模式,利用 GPU 的能力來優化操控繪圖素材比變化的渲染結果。
後續計劃
發現在圖片尺寸比較大,而且涉及圖片、HTML 和 SVG 需要轉換資源格式的情況下,在操作元素的移動等行爲時候,會出現比較明顯的掉幀和卡頓,後續打算把底層的基於 Canvas 2D API 渲染畫圖,重寫一套基於 WebGL 的實現,讓使用者可以根據自己場景要求考慮是否選擇 WebGL 加速渲染。
其他
GitHub 地址: https://github.com/idrawjs/idraw
官方網站: https://idraw.js.org/
Playground API 示例: https://idraw.js.org/playground/
基於 iDraw.js 的 Studio 實際案例: https://idraw.js.org/studio/
或者直接在公衆號回覆 “idraw” 就可以獲取相關鏈接。如果其他疑問或者問題,歡迎提 issue 和 PR。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Ipbmv62pwqlOc5waPnC68A