这可能不是fabricjs的问题,而是某种一般的js问题。
我们有一个网上商店来创建贴纸,当我们导出订单时(每天20到100个),我遍历每个贴纸,将它们加载到画布上(使用JSON数据),放置画布的图像在pdf上并应用切割线。有时(不是很经常)两个图像在画布上合并。就像画布在开始加载新贴纸之前没有清除。我尝试使用node生成导出文件,但是在遇到很多文本排列不正确的问题后,我决定使用浏览器来处理导出,因为它更可靠。
那么关于如何防止合并的任何想法?
正如您在下面看到的,我什至尝试添加睡眠以使画布有时间在每个标签之间进行清理,但这似乎无济于事。
function loadfromJsonExp(jsonstring, filename, type ){
canvas.clear();
canvas.renderAll();
sleep(1000);
jsonstring = JSON.stringify(jsonstring);
if (jsonstring == 'missmatch')
{
return;
}
jsonstring = jsonstring.replace(/(['"])src(['"]):(['"])http:\/\/.*?\//, '$1src$2:$3' + server_path);
jsonstring = jsonstring.replace(/\n/g, "\\n");
var json = JSON.parse(jsonstring);
// console.log(json);
var objectsToAdd = [];
var numReplaced = 0;
var mmWidth = parseInt(json.width);
var mmHeight = parseInt(json.height);
canvas.loadFromJSON(json.canvas, function() {
if(type == 3 || type == 4) {
json.outlineInfo.fill = '#ffffff';
setBackgroundColor('#ffffff');
} else {
outlineOptions.fill = json.outlineInfo.fill;
}
var outlinePath;
resizeOutlineExp(mmWidth, mmHeight);
if (json.shape == 'rect')
{
currentOutline = rectOutlineInfo;
outlinePath = getRectClipPath();
}
else if (json.shape == 'ellipse')
{
currentOutline = ellipseOutlineInfo;
outlinePath = getEllipseClipPath();
}
else if(json.shape == 'outline') {
currentOutline = customOutlineInfo;
Outliner.initialize(json);
outlineInfo = json.outlineInfo;
}
if (outlinePath != null){
var overlay = outlinePath.cloneAsImage();
}
canvas.setOverlayImage(overlay);
canvas.renderAll();
if (json.backImgInfo.beingUsed)
{
var backImg = new Image();
backImg.src = json.backImgInfo.src;
backImgInfo.isLocal = false;
addBackgroundFromImgElement(backImg);
}
canvas.renderAll.bind(canvas);
var destination = new fabric.Canvas('myCanvas');
var source = "";
if(type == 6 || type == 7) {
filename = filename + ".png";
var postthumbnail = stickerToImage(canvas, mmWidth, mmHeight);
var img = new Image();
img.src = postthumbnail;
var url = img.src.replace(/^data:image\/[^;]/, 'data:application/octet-stream');
var uri = postthumbnail;
var downloadLink = document.createElement("a");
downloadLink.href = uri;
downloadLink.download = filename;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
} else {
filename = filename + ".pdf";
if (json.backImgInfo.beingUsed) {
if (json.shape == 'rect') {
imageRectToPDF(source, destination, filename, mmWidth, mmHeight);
} else if (json.shape == 'ellipse') {
imageEllipseToPDF(source, destination, filename, mmWidth, mmHeight);
} else if (json.shape == 'outline'){
outlineToPDF(filename, json.outlineInfo, mmWidth, mmHeight, true);
}
} else {
if (json.shape == 'rect') {
rectToPDF(source, destination, filename, mmWidth, mmHeight);
} else if (json.shape == 'ellipse') {
ellipseToPDF(source, destination, filename, mmWidth, mmHeight);
} else if (json.shape == 'outline'){
outlineToPDF(filename, json.outlineInfo, mmWidth, mmHeight, false);
}
}
}
},
function(o, object){
if (o.type == 'image')
{
applyClipartSettings(object);
}
else if (o.type == 'path' || o.type == 'path-group')
{
object.isSVG = true;
applyClipartSettings(object);
}
else if (o.type == 'text')
{
applyTextSettings(object);
}
else if (o.type == 'i-text')
{
applyTextSettings(object);
}
});
setBorderColor();
setPrice();
//*/
canvas.calcOffset();
canvas.renderAll();
}
这是生成PDF的功能之一(我们正在使用jsPDF库)。
function imageEllipseToPDF(source, destination, filename, mmWidth, mmHeight) {
// destination.loadFromJSON(source, function() {
// destination.renderAll.bind(destination);
//});
//according to the web, on a 600 dpi pdf, there are 24 pixels per millimeter
var mm2pixels = 24;
//original height and width of the background
var width = canvas.backgroundImage.width;
var height = canvas.backgroundImage.height;
//the stickers width and height in pixels based on the print size
var stickerWidth = mmWidth * mm2pixels;
var stickerHeight = mmHeight * mm2pixels;
//the factor by which the sticker must be multiplied to obtain the correct DPI
var mult = stickerWidth/width;
//the scale by which we want to multiply the background to pad the cutline
var bgScalePx = 0 * mm2pixels;
var bgScaleMM = 0;
bgScalePx /= mult;
//remove the stroke on the background (we're going to add our own path) and scale it to add some padding
canvas.backgroundImage.strokeWidth = 0;
var bgWidth = width + bgScalePx;
var bgHeight = height + bgScalePx;
//destination.backgroundImage.scaleToWidth(bgWidth);
//destination.backgroundImage.scaleToHeight(bgHeight);
//get the margin for the cutline.
//(bgWidth - width)/2 is the difference on each side
var marginL = 0.5 + (parseInt(mmWidth)) / 2;
var marginT = 0.5 + (parseInt(mmHeight)) / 2;
//remove the old cutline and render the canvas
canvas.overlayImage = "";
canvas.renderAll();
var margin = 36;
//The location of the sticker in the canvas
var pathStartX = 900 - (450 + (bgWidth / 2));
var pathStartY = 450 - (225 + (bgHeight / 2));
//get the image data from the canvas and crop it so that its only the sticker
var imgData = canvas.toDataURL({
format: 'png',
multiplier: mult,
width: bgWidth,
height: bgHeight,
left: pathStartX,
top: pathStartY
});
//the pdf width and height with a margin around them
var pdfWidth = (margin * 2) + parseInt(mmWidth);
var pdfHeight = (margin * 2) + parseInt(mmHeight);
//create a new pdf
var pdf = new jsPDF('l', 'mm', [pdfWidth, pdfHeight]);
//add the image in the left most corner (we can change the 0s as they are the margin)
pdf.addImage(imgData, 'png', margin, margin, parseInt(mmWidth) +1, parseInt(mmHeight) +1, '', 'FAST');
//set the stroke line width to somethign small
pdf.setLineWidth(0.1);
//create the cutline
//pdf.ellipse(margin + marginL, margin + marginT , (parseInt(mmWidth)-1)/2 , (parseInt(mmHeight)-1)/2 ,'S');
pdf.ellipse(margin + marginL, margin + marginT , (parseInt(mmWidth))/2 , (parseInt(mmHeight))/2 ,'S');
pdf.save(filename);
}