您好,登錄后才能下訂單哦!
這篇文章主要介紹“fabric.js圖層功能獨立顯隱、添加、刪除、預覽怎么實現”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“fabric.js圖層功能獨立顯隱、添加、刪除、預覽怎么實現”文章能幫助大家解決問題。
fabric本身有提供group功能,本意是讓你將畫布上的一些元素組合起來,這也將成為本次圖層功能的基礎 既以一個group代表一個圖層,畫布下第一層children只有圖層(group),而在group中,才是用戶實際繪制的內容
用戶可手動添加/刪除圖層
可對每個圖層進行獨立顯隱操作,并反饋到畫布中
可對每個圖層單獨預覽
首先fabric是需要到官方上下載的,在選擇你需要的模塊后再進行打包
雖然npm上也可以下載,但那不是官方的包,是有網友打包好以后上傳的,其中沒有包含橡皮擦模塊,很可能會不符合你的需求
所以我個人建議你可以自行去官網上打包,然后傳到你的私有npm庫里,然后就可以通過npm來管理了
fabric自定義打包下載地址:Custom Fabric build — Fabric.js Javascript Canvas Library (fabricjs.com)
fabric的事件文檔:Event inspector | Fabric.js Demos (fabricjs.com)
接下來的demo將會通過直接引入的方式來使用fabric,雖然我平時寫項目都是ts,但練手demo我個人建議還是js,問就是省事
fabric.js即為官網下載的插件包,這個文件就不放了,大家可以自行去官網打包下載
index.html即本次的頁面,主要負責dom的處理,直接扔瀏覽器運行就可以
sketchpad.js 是對fabric的二次封裝,同時也避免在html中寫太多fabric功能代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .content { display: flex; } .preview { margin-top: 40px; padding-top: 20px; width: 100%; display: flex; justify-content: center; border-top: 1px solid rgba(0,0,0,0.1); } .preview > img { width: 300px; height: 200px; } .layer-list { width: 300px; display: flex; flex-direction: column; padding-right: 10px; margin-right: 10px; box-sizing: content-box; border-right: 1px solid rgba(0,0,0, 0.2); } .layer { width: 300px; display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; border: 1px solid rgba(0,0,0, 0.2); } .layer > img { width: 30px; height: 30px; border: 1px solid rgba(0,0,0,0.1); } </style> </head> <body> <div id="app"> <div class="content"> <!-- 左側的圖層列表 --> <div class="layer-list"> <button @click="addLayer">增加圖層</button> <div @click="changeCurrentLayer(item.id)" class="layer" : v-for="item of layers" :key="item.id"> <button @click="changeVisible(item.id)">{{ item.show ? '已顯示' : '已隱藏'}}</button> <img :src="item.data"> <span>{{ item.name }}</span> <button @click="deleteLayer(item.id)">刪除</button> </div> </div> <!-- 右側的畫板 --> <div class="sketchpad-layout" > <canvas id="sketchpad" width="600" height="400" ></canvas> </div> </div> <!-- 對整張畫布進行圖片預覽 --> <div class="preview"> <button @click="updatePreview">整個畫布預覽:</button> <img :src="preview"> </div> </div> <!-- 使用vue3來進行ui的渲染,懶得操作dom了 --> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <!-- 打包好的fabric文件 --> <script src="./fabric.js"></script> <!-- sketchpad里面就是將fabric封裝了一層 --> <script src="./sketchpad.js"></script> <script> const { createApp } = Vue /** 單條的數據類型定義 */ const LayerData = { /** 用于顯示的名稱 */ name: '圖層名稱', /** 圖層的id,也用于管理圖層 */ id: '1111', /** 圖層的顯示狀態 */ show: true, /** 圖層的數據,用于顯示預覽圖 */ data: '', } createApp({ data() { return { layers: [],// 圖層數組,方便管理 sketchpad: null,// 畫板 currentLayer: '',// 當前圖層的id preview: '',// 預覽圖的base64數據 } }, methods: { /** * 改變圖層的顯示/隱藏 * @param id 圖層的id */ changeVisible(id) { const index = this.layers.findIndex(v => v.id === id); if (index > -1) { this.layers[index].show = !this.layers[index].show; } this.sketchpad.changeLayerVisible(id) }, /** * 刪除圖層 * @param id 圖層的id */ deleteLayer(id) { const index = this.layers.findIndex(v => v.id === id); if (index > -1) { this.layers.splice(index, 1) this.sketchpad.deleteLayer(id) } }, /** * 增加圖層 */ addLayer() { const item = { ...LayerData } item.id = new Date().getTime() item.name = `圖層${this.layers.length + 1}` this.layers.push(item) this.sketchpad.addLayer(item.id) this.changeCurrentLayer(item.id) }, /** 選擇當前要操作的圖層 */ changeCurrentLayer(id) { this.currentLayer = id this.sketchpad.changeCurrentLayer(id) }, /** * 更新預覽圖 */ updatePreview() { this.preview = this.sketchpad.getImage() }, /** 圖層數據更新的回調 */ onChangeData(id, data) { const index = this.layers.findIndex(v => v.id === id); if (index > -1) { this.layers[index].data = data; } } }, mounted() { this.sketchpad = new Sketchpad('sketchpad', { change: this.onChangeData }); this.addLayer() } }).mount('#app') </script> </body> </html>
console.log('Sketchpad load'); class Sketchpad { /** fabric實例 */ instance = null; /** 當前所在圖層的id */ currentLayer = ''; /** 畫布寬度 */ width = 600; /** 畫布高度 */ height = 600 /** 事件訂閱 */ listeners = { /** * 圖層內容變化時的回調 * @param {string} id 圖層id * @param {base64} data 圖層內容的base64格式 */ change: (id, data) => {} } constructor(id, listeners) { this.instance = new fabric.Canvas(id); this.width = this.instance.width; this.height = this.instance.height; this.instance.isDrawingMode = true; this.listeners.change = listeners.change this.instance.on('object:added', ((options) => { if (options.target.type === 'group') return; const groups = this.instance.getObjects() groups.forEach(v => { if (v.layerId === this.currentLayer && v.type === 'group') { v.addWithUpdate(options.target); this.instance.remove(options.target); this.listeners.change(v.layerId, v.toDataURL({ width: this.width, height: this.height })) } }) })) console.log('Sketchpad init') } /** 添加圖層 */ addLayer(id) { const group = new fabric.Group([], { width: this.width, height: this.width, }); // 在這里增加一個自定義屬性 layerId ,用于區分圖層 group.layerId = id this.instance.add(group) this.currentLayer = id; this.listeners.change(id, group.toDataURL({ width: this.width, height: this.height })) } /** 改變圖層的顯示/隱藏 */ changeLayerVisible(id) { const groups = this.instance.getObjects() groups.forEach(v => { if (v.layerId === id && v.type === 'group') { v.visible = !v.visible; this.instance.renderAll() // 刷新畫布,改變group的visible屬性,必須通過刷新畫布,才能應用新屬性值 } }) } /** 選擇要操作的圖層 */ changeCurrentLayer(id) { this.currentLayer = id } /** 刪除圖層 */ deleteLayer(id) { const groups = this.instance.getObjects() groups.forEach(v => { if (v.layerId === id && v.type === 'group') { this.instance.remove(v) this.instance.renderAll() // 刷新畫布 } }) } /** 獲取畫布數據,以img標簽可以識別的base64格式 */ getImage() { return this.instance.toDataURL() } }
將以上這兩個文件代碼直接復制粘貼到編輯器里,然后再去打包個fabric.js也放進編輯器里,就可以運行啦
關于“fabric.js圖層功能獨立顯隱、添加、刪除、預覽怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。