iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
Modern Web

拾起 Canvas,人人都是大藝術家!系列 第 19

第 19 幅 - 用 Fabric.js 做一個獨一無二的圖表工具

  • 分享至 

  • xImage
  •  

昨天實作了 Particles.js ,今天就來玩玩 Fabric.js !大家還記得前天對於 Fabric.js 的介紹嗎?不記得也沒關係只要掌握兩件事,一是 Fabric.js 提供了許多 API 讓使用者可以直接在畫布上進行操作,例如選取、縮放、旋轉、變色等,此外 Fabric.js 也可以把 Canvas 轉成序列化的格式,包含 Json 和 svg,這兩個特點今天都會示範唷!

https://ithelp.ithome.com.tw/upload/images/20221004/201306304ZEQG64Cwp.png

起手式

一樣的我們可以直接安裝 fabricjs-react 的套件,因為我的專案內有用到 fabric,所以我也一併安裝了 fabric.js 和他的 type 型別。

npm install --save fabricjs-react fabric react react-dom
npm install fabric --save
npm install --save @types/fabric

強大的 FabricJSEditor ,透過 editor 呼叫 API

FabricJSEditor 提供了許多強大的 API,讓我們不用再去針對 canvas 寫程式繪圖,可以直接調用以下的 API 完成許多繪圖功能,如下圖是 FabricJSEditor 包含的功能,有新增圓形、矩形、線條、文字、填色、邊線顏色等等。

export interface FabricJSEditor {
    canvas: fabric.Canvas;
    addCircle: () => void;
    addRectangle: () => void;
    addLine: () => void;
    addText: (text: string) => void;
    updateText: (text: string) => void;
    deleteAll: () => void;
    deleteSelected: () => void;
    fillColor: string;
    strokeColor: string;
    setFillColor: (color: string) => void;
    setStrokeColor: (color: string) => void;
    zoomIn: () => void;
    zoomOut: () => void;
}

以下程式碼當中可以看到主要的幾個 API 調用方式都非常簡單,直接以 onClick 監聽後呼叫對應的 API,就可以完成我們想要的對應的功能,這邊特別分享幾個比較需要注意的設計:

1. 文字輸入新增與變更:

當選擇的是已經寫好的文字,那就會更新新的 Input value,若不是則會直接新增一個新的文字

    const handleAddText = () => {
        if (selectedObjects?.length) {
            return editor?.updateText(text);
        }
        editor?.addText(text);
    };

2. 選擇顏色與變更所選物件顏色:

我們可以透過 input type=color 的方式讓使用者選取顏色,並以 onChange 作為選擇的監聽,選好顏色後再呼叫 setFillColor(),記得這裡只有被選擇的或是直接新增的會變更顏色

    
	  const handleFillColor = () => {
        editor?.setFillColor(fillColor);
    };

		<input
             style={{ width: '40px', height: '40px' }}
             type="color"
             value={strokeColor || editor?.strokeColor}
             onChange={(e) => setStrokeColor(e.target.value)}
             />
                <button className="button-16" onClick={handleAddStrokeColor}>
                    Set Stroke Color
                </button>

3. 上傳圖片檔案:

a. 此處為了要讓樣式好看,所以我以 <label> 包裝,並讓原生的 type="file" 的樣式直接消失,當然如果想直接使用原生樣式,這裡就不需要 display: none 與包一個 <label>
b. 因為可以上傳多個檔案,因此 handleUploadImage() 當中有以 map 的概念去新增每一個檔案,並且全部渲染

    const handleUploadImage = (e: any) => {
        const image = e.target.files[0];
        fabric.Image.fromURL(URL.createObjectURL(image), (img) => {
            editor?.canvas.add(img);
            editor?.canvas.renderAll();
        });
    };

   <label className="button-16">
          <input type="file" style={{ display: 'none' }} onChange={handleUploadImage} />
          <div style={{ paddingTop: '5px' }}>Upload Image</div>
   </label>

4. Canvas to json 格式:

前面有提到 Fabric.js 可以很輕鬆的把 Canvas 轉成序列化的格式,在這個範例的最後我也有加上這個功能,當有物件被選取到時就顯示出該物件的 json 格式資料。

 <pre>{selectedObjects?.length !== 0 && JSON.stringify(selectedObjects)}</pre>

https://ithelp.ithome.com.tw/upload/images/20221004/20130630bRVgu64XdO.jpg

完整專案程式碼之後會一起釋出 github 唷~~


上一篇
第 18 幅 - 實作 Particle.js 動畫,讓你的網頁「哇~好像很厲害」
下一篇
第 20 幅 - 時代在走,基本圖表要會!來個 Chart.js
系列文
拾起 Canvas,人人都是大藝術家!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Rson Wilson
iT邦新手 4 級 ‧ 2022-10-04 23:55:09

可以用 fabric.js 來做個獨一無二的交屋工具咪~

我要留言

立即登入留言