fabric image 替换图片

在之前的基础上调整部分代码,实现上传图片后的替换图片,及可以直接上传替换图片

首先需要上传一张图片,后续操作的前提都需要 canvas 中有选中的 image 对象:

 

之后可以点击【直接替换】,内置了2中方式:一种直接 url (需要实际存在资源文件);另一种则为 dataUrl(base64...):

 

第二种就是再次点击上传【选择文件】,正常画布内无选中元素时,会将上传文件添加到 画布中去;而有选中元素,则会替换选中图片的内容

 

代码记录:

import { fabric } from 'fabric';
import { Image } from './image';

/**
 * 上传文件
 * 添加到 canvas 中
 * 增加上传替换(上传时如果有选中图片,则直接替换)
 * 代码直接替换图片(url / dataURL)
 */
export class Upload {
    num = 0;

    constructor(canvas) {
        // 添加 input
        this.addTarget(canvas);

        // 测试替换图片
        this.testChange(canvas);
    }

    /**
     * 添加必要元素
     */
    addTarget(canvas) {
        let ele = `
            <div class="warp">
                <div class="warp-content">点击上传</div>
                <input type="file" id="file"/>
            </div>
            <img src="" alt="" class="img" />
        `;
        $('body').append(ele);
        let _self = this; // 保存当前对象引用
        let file = document.getElementById('file');
        let image = document.getElementsByClassName('img')[0];
        file.onchange = function () {
            // 获取到一个FileList对象中的第一个文件( File 对象),是我们上传的文件
            let fileData = this.files[0];
            let pettern = /^image/;

            console.info(fileData.type)

            if (!pettern.test(fileData.type)) {
                alert("图片格式不正确");
                return;
            }
            let reader = new FileReader();
            // 异步读取文件内容,结果用data:url的字符串形式表示
            reader.readAsDataURL(fileData);
            /*当读取操作成功完成时调用*/
            reader.onload = function (e) {
                console.log(e); //查看对象
                // 要的数据 这里的this指向FileReader()对象的实例reader
                console.log(this.result);
                image.setAttribute("src", this.result);
                // 调用绘图
                // 先调用替换,如果存在选中对象,则执行图片替换;无则返回 false
                let hasActive = _self.doExchange(canvas, this.result);
                if (hasActive === false) {
                    // 界面没有选中,则执行添加图片操作
                    _self.addToCanvasByUrl(canvas, this.result);
                }
            }
        }
    }


    /**
     * 第一种方法,url
     * 异步加载性能最好
     * url 可以是下载 url, 也可以是 dataUrl (data:image/jpg;base64,...)
     */
    addToCanvasByUrl(canvas, data) {
        new fabric.Image.fromURL(data, (img) => {
            img.set(Image.defaultImage(canvas, img));
            canvas.add(img);
            img.center();
            img.sendBackwards();
        });
    }

    /**
     * 测试替换图片(确保有选中的图片再进行替换!)
     */
    testChange(canvas) {
        $('body').append(`<button class="exchange">直接替换</button>`);
        $('.exchange').on('click', (e) => {
            let urls = [
                'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAABHNCSVQICAgIfAhkiAAAAaBJREFUSIntlEFSIkEQRV92t6G76bkB3oAbyA1kixMT00q7Bk5AegKcPQZOEDTLCW+AN+AGtjdgawR0ugAUsJASXfpXVfGz8v/Mqkr4xgcgq5tUsw7Q/KLc1109awFEG0QTuIbZ3efyh6eLXE4RYHbX1d+jz0ik2gfCl444RHYj0WEpwhq+hoJ9RCJmVaAJYccvfh9I+AMzDGJYVCb8mRr/brWWf43IBg6wjhnVaC7a2uS923WhgyTVfsXFLSsyJHbxXpVc6qBsSA+CSaK9Y19jXiJ1zaoznkZGEUMISAxHTrfvYWu70qthW+B/yJHXC9pLpLDiEUCwyZQoB5sY5Lday5ccyGgRPgYwivudiqlmtnq5lzooL9eJ9tbalOiwtL5/5VPtV1LNbLlfG5B1zR4CGJvIeKejdyBmZcMqXf31EzYuXuAvcIJZxXXYFwYYcr6SdzcS7cURh23XP7jR2rnrzCo8RYalCHtwcVPk2DVKvETqmlUNiwECLIZgy1MuWgUymccVuWsqb/2MAg2QEoDNvWxxGzRenYY58EbkGx/CMx2qj7Qd6S9UAAAAAElFTkSuQmCC',
                './assets/111.png'
            ];
            this.num++;
            this.doExchange(canvas, urls[this.num % 2]);
        });
    }

    /**
     * 执行图片替换操作
     * @param canvas
     * @param url
     * @return boolean 如果没有激活元素,不会进行替换操作并返回 false 标记;
     */
    doExchange(canvas, url) {
        let activeObj = canvas.getActiveObject();
        console.log(activeObj);
        if (!activeObj) {
            return false;
        }
        activeObj.setSrc(url, () => {
            canvas.renderAll();
        });
    }
}

 

基于之前一篇文章优化调整:https://www.cnblogs.com/guofan/p/16149788.html

posted @ 2022-09-22 15:12  名字不好起啊  阅读(395)  评论(0编辑  收藏  举报