使用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>
问题原因及解决方案
核心原因
- 跨域图片污染画布:加载的外部域名图片触发浏览器安全限制,污染画布后无法调用
toDataURL()导出图片。 - 未定义变量报错:
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
相关产品推荐
相关产品推荐

