从数据 url 设置 fabric.js 画布背景

Posted

技术标签:

【中文标题】从数据 url 设置 fabric.js 画布背景【英文标题】:Set fabric.js canvas background from a data url 【发布时间】:2021-11-26 17:34:31 【问题描述】:

我正在尝试在单击图像时从 URL 设置 fabric.js 画布背景。

我试图在单击带有以下代码的图像时使其正常工作,该代码从元素传递photoURL

//Change background using Image
export function selectCanvasEdit(photoURL) 
    // replace the map on select
    let theMap = document.getElementById('google-map')
    let theCanvas = document.getElementById('canvasContainer')


    let canH = theMap.offsetHeight
    let canW = theMap.offsetWidth

    theCanvas.style.display = ''
    theMap.style.display = 'none'

    canvas.setBackgroundColor('', canvas.renderAll.bind(canvas));
    canvas.setBackgroundImage(0, canvas.renderAll.bind(canvas));


    var request = new XMLHttpRequest();
    request.open('GET', photoURL, true);
    request.responseType = 'blob';
    request.onload = function () 
        var reader = new FileReader();
        reader.readAsDataURL(request.response);
        reader.onload = function (e) 
            console.log('DataURL:', e.target.result);
            fabric.Image.fromURL(e.target.result, function (img) 
                canvas.setHeight(canH);
                canvas.setWidth(canW);
                let imgWidth = img.width;
                let imgHeight = img.height;
                let canvasWidth = canvas.getWidth();
                let canvasHeight = canvas.getHeight();


                img.scaleToWidth(canvasWidth);

                canvas.setBackgroundImage(photoURL, canvas.renderAll.bind(canvas), 
                    scaleX: canvas.width / img.width,
                    scaleY: canvas.height / img.height
                );
            );
        ;
    ;
    request.send();
;

我还尝试将photoURL 参数直接传递给fabric.Image.fromURL() 函数,有或没有以下onload() 事件。

var img = new Image();

img.onload = function() 
    var f_img = new fabric.Image(img);

    canvas.setBackgroundImage(f_img);

    canvas.renderAll();
;

img.src = photoURL;

这也不行,我得到的只是一张空白画布。

现在当我使用这段代码时:

//Change background using Image
document.getElementById('bg_image').addEventListener('change', function (e) 

    // replace the map on select
    let theMap = document.getElementById('google-map')
    let theCanvas = document.getElementById('canvasContainer')


    let canH = theMap.offsetHeight
    let canW = theMap.offsetWidth

    theCanvas.style.display = ''
    theMap.style.display = 'none'

    canvas.setBackgroundColor('', canvas.renderAll.bind(canvas));
    canvas.setBackgroundImage(0, canvas.renderAll.bind(canvas));
    var file = e.target.files[0];
    var reader = new FileReader();
    reader.onload = function (f) 
        var data = f.target.result;
        fabric.Image.fromURL(data, function (img) 
            debugger;
            canvas.setHeight(canH);
            canvas.setWidth(canW);
            let imgWidth = img.width;
            let imgHeight = img.height;
            let canvasWidth = canvas.getWidth();
            let canvasHeight = canvas.getHeight();

            let imgRatio = imgWidth / imgHeight;
            let canvasRatio = canvasWidth / canvasHeight;

            img.scaleToWidth(canvasWidth);
            //img.scaleToHeight(canvasHeight);

            canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), 
                scaleX: canvas.width / img.width,
                scaleY: canvas.height / img.height
            );
        );
    ;
    reader.readAsDataURL(file);
);

一切都很好,尽管来自fabric.Image.fromURL()img._element.attributes.src 仍然是一个base64 数据url,并且在复制到浏览器时会加载图像,就像selectCanvasEdit() 一样。

非常感谢任何帮助,我不明白传递给 fabric.js 画布的相同类型的 img.src 如何以不同方式处理,即使结果数据 url 可以加载到浏览器中而不管使用哪个函数接收数据。

【问题讨论】:

【参考方案1】:

在尝试了一切之后,函数中的代码没有任何问题,这让这有点混乱。

我突然想到我正在导出这个函数,并且画布是在这个函数之外定义的var canvas = new fabric.Canvas('canvas-tools');

如果我在函数中再次抓住那个元素,一切都会正常运行。

【讨论】:

以上是关于从数据 url 设置 fabric.js 画布背景的主要内容,如果未能解决你的问题,请参考以下文章

使用fabric js时需要更改画布背景颜色

前端开发Vue + Fabric.js + Element-plus 实现简易的H5可视化图片编辑器

Fabric.js 背景仅在更改缩放值后出现

将图像数据URI(base64)设置为画布背景

Fabric.js 3个api设置画布宽高

在组合fabric.js和jQuery时,将图像拖放到画布不起作用