将fabricjs画布保存为PNG不起作用

cod*_*ver 0 html javascript canvas fabricjs

我想弄清楚为什么这不会将画布保存为 PNG。

我包含了很多代码,因为我确信它会干扰自身但不知道如何干扰。我修改过类似的应用程序,但没有遇到过这个问题:请注意,当您选择“保存”时,它会炸毁画布,但没有执行应有的操作,即将画布作为 PNG 保存到您的计算机上。

我得到的一个错误是:

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
at n.__toDataURL (https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js:1:111706)
at n.__toDataURLWithMultiplier (https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js:1:111496)
at n.toDataURL (https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js:1:111060)
at downloadFabric (file://portrait.js:207:21)
at HTMLButtonElement.onclick (file://index.html:62:114)
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
at n.__toDataURL (https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js:1:111706)
at n.__toDataURLWithMultiplier (https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js:1:111496)
at n.toDataURL (https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js:1:111060)
at downloadFabric (file://portrait.js:207:21)
at HTMLButtonElement.onclick (file://index.html:62:114)
Run Code Online (Sandbox Code Playgroud)
var canvas = new fabric.Canvas('c', {
  preserveObjectStacking: true
});
canvas.setHeight(412);
canvas.setWidth(637);
var oImg, oImg2, isImageLoaded;


// oImgObj bread and butter, kudos @grunt
function replaceImage(oImgObj, imgUrl) {
  if (!isImageLoaded) return; //return if initial image not loaded
  var imgElem = oImgObj._element; //reference to actual image element
  imgElem.src = imgUrl; //set image source
  imgElem.onload = () => canvas.renderAll(); //render on image load
}

// initialize default frame (light brown wood oval)
fabric.Image.fromURL('https://i.imgur.com/DrzSWSa.png', function(img) {
  isImageLoaded = true;
  oImg = img.set({
    selectable: false,
    evented: false,
  }).scale(0.5);
  canvas.add(oImg).renderAll();
  canvas.sendToBack(oImg);
});

// add photo (link)
$(function() {
  $("#upload_link").on('click', function(e) {
    e.preventDefault();
    $("#file:hidden").trigger('click');
  });
});

// add photo
document.getElementById('file').addEventListener("change", function(e) {
  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) {
      var oImg = img.set({
        left: 400,
        top: 102,
        centeredScaling: true,
        lockUniScaling: true,
        cornerStyle: 'circle',
        transparentCorners: false,
      }).scale(.8);
      canvas.add(oImg);
      canvas.setActiveObject(oImg);
      var image = canvas.getActiveObject();
      image.moveTo(-1);
      canvas.discardActiveObject();
      canvas.renderAll();
      canvas.sendToBack(oImg);
    });
  };
  reader.readAsDataURL(file);
});

// Some Text
canvas.add(new fabric.IText('Some Text', {
  left: 475,
  top: 25,
  fontSize: 27,
  hasBorders: true,
  hasControls: false,
  selectable: true,
  lockRotation: true,
  lockMovementX: true,
  lockMovementY: true,
  align: 'mid',
  originX: 'center',
  originY: 'center',
  centeredScaling: true,
}));

// Some Text
canvas.add(new fabric.IText('Some Text', {
  left: 475,
  top: 60,
  fontSize: 27,
  hasBorders: true,
  hasControls: false,
  selectable: true,
  lockRotation: true,
  lockMovementX: true,
  lockMovementY: true,
  align: 'mid',
  originX: 'center',
  originY: 'center',
  centeredScaling: true,
}));

// Text Style Options
var underline = document.getElementById('btn-underline');
var bold = document.getElementById('btn-bold');
var italic = document.getElementById('btn-italic');

underline.addEventListener('click', function() {
  dtEditText('underline');
});
bold.addEventListener('click', function() {
  dtEditText('bold');
});
italic.addEventListener('click', function() {
  dtEditText('italic');
});

// Font Styling
function dtEditText(action) {
  var a = action;
  var o = canvas.getActiveObject();
  var t;
  // If object selected, what type?
  if (o) {
    t = o.get('type');
  }
  if (o && t === 'i-text') {
    switch (a) {
      case 'bold':
        var isBold = dtGetStyle(o, 'fontWeight') === 'bold';
        dtSetStyle(o, 'fontWeight', isBold ? '' : 'bold');
        break;

      case 'italic':
        var isItalic = dtGetStyle(o, 'fontStyle') === 'italic';
        dtSetStyle(o, 'fontStyle', isItalic ? '' : 'italic');
        break;

      case 'underline':
        var isUnderline = dtGetStyle(o, 'textDecoration') === 'underline';
        dtSetStyle(o, 'textDecoration', isUnderline ? '' : 'underline');
        break;
        canvas.renderAll();
    }
  }
}
// Get the style
function dtGetStyle(object, styleName) {
  return object[styleName];
}
// Set the style
function dtSetStyle(object, styleName, value) {
  object[styleName] = value;
  object.set({
    dirty: true
  });
  canvas.renderAll();
}

// Switching Fonts
document.getElementById("cinzel").addEventListener("click", function(e) {
  canvas.getActiveObject().set("fontFamily", "Cinzel");
  canvas.renderAll();
});

document
  .getElementById("cinzelDecorative")
  .addEventListener("click", function(e) {
    canvas.getActiveObject().set("fontFamily", "Cinzel Decorative");
    canvas.renderAll();
  });

document
  .getElementById("monsieurladoulaise")
  .addEventListener("click", function(e) {
    canvas.getActiveObject().set("fontFamily", "Monsieur La Doulaise");
    canvas.renderAll();
  });
document.getElementById("opensans").addEventListener("click", function(e) {
  canvas.getActiveObject().set("fontFamily", "Open Sans");
  canvas.renderAll();
});

document.getElementById("montserrat").addEventListener("click", function(e) {
  canvas.getActiveObject().set("fontFamily", "Montserrat");
  canvas.renderAll();
});

document.getElementById("times").addEventListener("click", function(e) {
  canvas.getActiveObject().set("fontFamily", "Times New Roman");
  canvas.renderAll();
});

// Centered Line
var line = new fabric.Line([canvas.width / 2, 0, canvas.width / 2, canvas.height], {
  strokeWidth: 1,
  stroke: '#dddddd',
  selectable: false,
});
canvas.add(line);

// Save
function download(url, name) {
  // make the link. set the href and download. emulate dom click
  $('<a>').attr({
    href: url,
    download: name
  })[0].click();
}

function downloadFabric(canvas, name) {
  //  convert the canvas to a data url and download it.
  download(canvas.toDataURL({
    multiplier: 4
  }), name + '.png');
}

// Print
function printCanvas() {
  var dataUrl = document.getElementById('c').toDataURL( /* data multiplier?*/ ); //attempt to save base64 string to server using this var  
  var windowContent = '<!DOCTYPE html>';
  windowContent += '<html>'
  windowContent += '<head><title>Print canvas</title></head>';
  windowContent += '<body>'
  windowContent += '<img src="' + dataUrl + '" onload=window.print();window.close();>';
  windowContent += '</body>';
  windowContent += '</html>';
  var printWin = window.open('', '', 'width=340,height=260');
  printWin.document.open();
  printWin.document.write(windowContent);
}
Run Code Online (Sandbox Code Playgroud)
canvas {
  border: 1px solid #dddddd;
  margin-top: 5px;
}

a:visited {
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
  cursor: pointer;
}

a.dropdown-item {
  cursor: pointer;
}

.btn {
  margin-top: 10px;
  cursor: pointer;
}

#upload_link {
  text-decoration: none;
}

#file {
  display: none;
}
Run Code Online (Sandbox Code Playgroud)

同样,打印现在也不工作。

use*_*287 7

使用 toDataURL 方法:

const dataURL = canvas.toDataURL({
     width: canvas.width,
     height: canvas.height,
     left: 0,
     top: 0,
     format: 'png',
});
const link = document.createElement('a');
link.download = 'image.png';
link.href = dataURL;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
Run Code Online (Sandbox Code Playgroud)

它会在文档中创建一个不可见的链接,然后单击它以触发下载。