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)
同样,打印现在也不工作。
使用 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)
它会在文档中创建一个不可见的链接,然后单击它以触发下载。