You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fabric.js添加图片后,画布下载功能失效问题咨询

问题:Fabric.js添加图片后画布下载功能失效

我使用Fabric.js在图片上进行绘制,添加图片到画布的代码后,图片可正常显示,但画布的下载功能停止工作;移除该代码块后,下载功能恢复正常。已在Chrome、Edge和Brave浏览器的W3School在线IDE中测试过该代码。

出错代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fabric.js Drawing App</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script>
  </head>
  <body>
    <script>

      // Create canvas element
      const canvasElement = document.createElement('canvas');
      canvasElement.width = 500;
      canvasElement.height = 500;
      canvasElement.id = 'canvas';
      document.body.appendChild(canvasElement);

      // Create save button
      const saveBtn = document.createElement('button');
      saveBtn.textContent = 'Save Image';
      saveBtn.id = 'saveBtn';
      document.body.appendChild(saveBtn);

      const canvas = new fabric.Canvas('canvas', {
        isDrawingMode: true // Enable drawing mode
      });

      canvas.on('mouse:move', function(event) {
        if (event.e.clientX && event.e.clientY) {
          const x = event.e.clientX - canvasRect.left;
          const y = event.e.clientY - canvasRect.top;

          circle.set({
            left: x,
            top: y,
            radius: 5,
            visible: true
          });
          canvas.renderAll();
        }
      });

      fabric.Image.fromURL( 'https://lh3.googleusercontent.com/I1zd_ENZEN0VT23yy0liopnY1aUSDrIAPFH3cW_Ef7XvGt9e5FqhiAEM8Mvd4Zj2PEbK9FNOVWKKgBmCRhRPyCE=s1280-w1280-h800', function(img) {
        img.set({
          left: 100,
          top: 100,
          scaleX: 0.5,
          scaleY: 0.5
        });
        canvas.add(img);
      });

      saveBtn.addEventListener('click', function() {
        const dataURL = canvas.toDataURL({
          format: 'png'
        });
        const link = document.createElement('a');
        link.href = dataURL;
        link.download = 'drawing.png';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });
    </script>
  </body>
</html>

问题原因及解决方案

核心原因

  1. 跨域图片污染画布:加载的外部域名图片触发浏览器安全限制,污染画布后无法调用toDataURL()导出图片。
  2. 未定义变量报错:mouse:move事件中用到的canvasRect和circle未提前定义,代码执行报错会中断后续下载逻辑。

修复后的代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fabric.js Drawing App</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script>
  </head>
  <body>
    <script>

      // Create canvas element
      const canvasElement = document.createElement('canvas');
      canvasElement.width = 500;
      canvasElement.height = 500;
      canvasElement.id = 'canvas';
      document.body.appendChild(canvasElement);

      // Create save button
      const saveBtn = document.createElement('button');
      saveBtn.textContent = 'Save Image';
      saveBtn.id = 'saveBtn';
      document.body.appendChild(saveBtn);

      const canvas = new fabric.Canvas('canvas', {
        isDrawingMode: true // Enable drawing mode
      });

      // 提前定义未声明的变量
      const canvasRect = canvasElement.getBoundingClientRect();
      const circle = new fabric.Circle({
        radius: 5,
        fill: 'black',
        visible: false
      });
      canvas.add(circle);

      canvas.on('mouse:move', function(event) {
        if (event.e.clientX && event.e.clientY) {
          const x = event.e.clientX - canvasRect.left;
          const y = event.e.clientY - canvasRect.top;

          circle.set({
            left: x,
            top: y,
            visible: true
          });
          canvas.renderAll();
        }
      });

      // 添加跨域参数,避免画布污染
      fabric.Image.fromURL( 'https://lh3.googleusercontent.com/I1zd_ENZEN0VT23yy0liopnY1aUSDrIAPFH3cW_Ef7XvGt9e5FqhiAEM8Mvd4Zj2PEbK9FNOVWKKgBmCRhRPyCE=s1280-w1280-h800', function(img) {
        img.set({
          left: 100,
          top: 100,
          scaleX: 0.5,
          scaleY: 0.5
        });
        canvas.add(img);
      }, { crossOrigin: 'anonymous' });

      saveBtn.addEventListener('click', function() {
        const dataURL = canvas.toDataURL({
          format: 'png'
        });
        const link = document.createElement('a');
        link.href = dataURL;
        link.download = 'drawing.png';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });
    </script>
  </body>
</html>

关键修复点

  • 给fabric.Image.fromURL()添加{ crossOrigin: 'anonymous' }参数,请求跨域图片时带上跨域标识,避免画布被污染。
  • 提前定义canvasRect和circle变量,消除代码执行错误。

内容的提问来源于stack exchange,提问作者salem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:30:29