休息 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