中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

fabric.js圖層功能獨立顯隱、添加、刪除、預覽怎么實現

發布時間:2023-05-04 17:11:08 來源:億速云 閱讀:134 作者:iii 欄目:開發技術

這篇文章主要介紹“fabric.js圖層功能獨立顯隱、添加、刪除、預覽怎么實現”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“fabric.js圖層功能獨立顯隱、添加、刪除、預覽怎么實現”文章能幫助大家解決問題。

原理

fabric本身有提供group功能,本意是讓你將畫布上的一些元素組合起來,這也將成為本次圖層功能的基礎 既以一個group代表一個圖層,畫布下第一層children只有圖層(group),而在group中,才是用戶實際繪制的內容

效果預覽

本次demo實現:

  • 用戶可手動添加/刪除圖層

  • 可對每個圖層進行獨立顯隱操作,并反饋到畫布中

  • 可對每個圖層單獨預覽

效果圖:

fabric.js圖層功能獨立顯隱、添加、刪除、預覽怎么實現

小Tips

首先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功能代碼

fabric.js圖層功能獨立顯隱、添加、刪除、預覽怎么實現

index.html代碼

<!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>

sketchpad.js代碼

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圖層功能獨立顯隱、添加、刪除、預覽怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

屯留县| 五家渠市| 平乡县| 平武县| 云南省| 梅河口市| 克东县| 长治市| 万荣县| 靖远县| 东乌珠穆沁旗| 永定县| 崇礼县| 平舆县| 全南县| 务川| 兴国县| 广安市| 宝应县| 伽师县| 抚州市| 海丰县| 青河县| 隆尧县| 同江市| 上杭县| 东源县| 义马市| 临武县| 大冶市| 岳阳市| 微山县| 太谷县| 卓尼县| 泸定县| 韶关市| 达拉特旗| 吉木萨尔县| 思茅市| 济源市| 大兴区|