From 378593047d0e9c8e4b93e3e2fa8657171b223946 Mon Sep 17 00:00:00 2001 From: 24kycj <1637269896@qq.com> Date: Tue, 9 Dec 2025 19:50:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=8C=E7=BB=B4=E7=A0=81?= =?UTF-8?q?=E3=80=81=E6=9D=A1=E5=BD=A2=E7=A0=81=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/design1/output.js | 77 +++++++++++++++++++++++++++++++++++++++++-- lib/design2/output.js | 76 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 149 insertions(+), 4 deletions(-) diff --git a/lib/design1/output.js b/lib/design1/output.js index 60e7bb5..a7f1594 100644 --- a/lib/design1/output.js +++ b/lib/design1/output.js @@ -867,6 +867,50 @@ function output(callback = null, _save = save) { }) } +// 重新生成二维码和条形码(加载文件后调用) +function regenerateQrCodesAndBarcodes(canvas, objsArray) { + if (!canvas || !objsArray || !Array.isArray(objsArray)) return; + + const objects = canvas.getObjects(); + + // 遍历对象(跳过背景图片,索引 0) + for (let i = 1; i < objects.length; i++) { + const obj = objects[i]; + if (!obj || obj.type !== 'image') continue; + + const objIndex = i - 1; + if (objIndex >= objsArray.length) continue; + + const objMeta = objsArray[objIndex]; + if (!objMeta || (objMeta.type !== 8 && objMeta.type !== 9)) continue; + + // type == 8: 二维码 - 复用 ui.js 中的生成逻辑 + if (objMeta.type === 8) { + const qr = jrQrcode.getQrBase64(objMeta.val || 'https://www.cardsoon.com', { + padding: 0, + foreground: objMeta.color || '#000000' + }); + obj.setSrc(qr, function(img) { + canvas.renderAll(); + }); + } + // type == 9: 条形码 - 复用 ui.js 中的生成逻辑 + else if (objMeta.type === 9) { + JsBarcode("#barcode", objMeta.val || '123456789', { + margin: 0, + lineColor: objMeta.color || '#000000', + fontSize: objMeta.fontSize || 18, + font: objMeta.font || 'Arial' + }); + const barcode = document.getElementById('barcode'); + const bar = barcode.toDataURL("image/png"); + obj.setSrc(bar, function(img) { + canvas.renderAll(); + }); + } + } +} + // 清理不需要的 src 字段(保留自定义图片的 src) function cleanupSrcFields(jsonObjects, objsArray) { if (!jsonObjects || !Array.isArray(jsonObjects)) return; @@ -1072,9 +1116,38 @@ function open(file) { if (j.b.objects && j.b.objects.length > 0 && j.b.objects[0] && !j.b.objects[0].src) { j.b.objects[0].src = './public/images/bg_back.png' } + + // 为二维码和条形码对象创建临时的 src(Fabric.js 需要 src 来创建 Image 对象) + // 加载完成后会重新生成,所以这里只需要一个占位符 + const fo = j.fo || []; + const bo = j.bo || []; + const placeholder = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='; + + // 为正面二维码和条形码创建临时 src + fo.forEach((objMeta, idx) => { + if ((objMeta.type === 8 || objMeta.type === 9) && j.f.objects[idx + 1] && !j.f.objects[idx + 1].src) { + j.f.objects[idx + 1].src = placeholder; + } + }); + + // 为背面二维码和条形码创建临时 src + bo.forEach((objMeta, idx) => { + if ((objMeta.type === 8 || objMeta.type === 9) && j.b.objects && j.b.objects[idx + 1] && !j.b.objects[idx + 1].src) { + j.b.objects[idx + 1].src = placeholder; + } + }); + console.log(j.f) - canvas1.loadFromJSON(j.f); - canvas2.loadFromJSON(j.b); + + // 加载 JSON,并在回调中重新生成二维码和条形码 + canvas1.loadFromJSON(j.f, function() { + regenerateQrCodesAndBarcodes(canvas1, fo); + canvas1.renderAll(); + }); + canvas2.loadFromJSON(j.b, function() { + regenerateQrCodesAndBarcodes(canvas2, bo); + canvas2.renderAll(); + }); // 安全检查:确保加载后 canvas 中有对象 let objects1 = canvas1.getObjects(); let objects2 = canvas2.getObjects(); diff --git a/lib/design2/output.js b/lib/design2/output.js index b2366b3..80ff3a2 100644 --- a/lib/design2/output.js +++ b/lib/design2/output.js @@ -859,6 +859,50 @@ function output(callback = null, _save = save) { }) } +// 重新生成二维码和条形码(加载文件后调用) +function regenerateQrCodesAndBarcodes(canvas, objsArray) { + if (!canvas || !objsArray || !Array.isArray(objsArray)) return + + const objects = canvas.getObjects() + + // 遍历对象(跳过背景图片,索引 0) + for (let i = 1; i < objects.length; i++) { + const obj = objects[i] + if (!obj || obj.type !== 'image') continue + + const objIndex = i - 1 + if (objIndex >= objsArray.length) continue + + const objMeta = objsArray[objIndex] + if (!objMeta || (objMeta.type !== 8 && objMeta.type !== 9)) continue + + // type == 8: 二维码 - 复用 ui.js 中的生成逻辑 + if (objMeta.type === 8) { + const qr = jrQrcode.getQrBase64(objMeta.val || 'https://www.cardsoon.com', { + padding: 0, + foreground: objMeta.color || '#000000' + }) + obj.setSrc(qr, function(img) { + canvas.renderAll() + }) + } + // type == 9: 条形码 - 复用 ui.js 中的生成逻辑 + else if (objMeta.type === 9) { + JsBarcode("#barcode", objMeta.val || '123456789', { + margin: 0, + lineColor: objMeta.color || '#000000', + fontSize: objMeta.fontSize || 18, + font: objMeta.font || 'Arial' + }) + const barcode = document.getElementById('barcode') + const bar = barcode.toDataURL("image/png") + obj.setSrc(bar, function(img) { + canvas.renderAll() + }) + } + } +} + // 清理不需要的 src 字段(保留自定义图片的 src) function cleanupSrcFields(jsonObjects, objsArray) { if (!jsonObjects || !Array.isArray(jsonObjects)) return; @@ -1017,8 +1061,36 @@ function open(file) { if (j.b.objects[0] && !j.b.objects[0].src) { j.b.objects[0].src = './public/images/bg_back_2.png' } - canvas1.loadFromJSON(j.f) - canvas2.loadFromJSON(j.b) + + // 为二维码和条形码对象创建临时的 src(Fabric.js 需要 src 来创建 Image 对象) + // 加载完成后会重新生成,所以这里只需要一个占位符 + const fo = j.fo || [] + const bo = j.bo || [] + const placeholder = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==' + + // 为正面二维码和条形码创建临时 src + fo.forEach((objMeta, idx) => { + if ((objMeta.type === 8 || objMeta.type === 9) && j.f.objects[idx + 1] && !j.f.objects[idx + 1].src) { + j.f.objects[idx + 1].src = placeholder + } + }) + + // 为背面二维码和条形码创建临时 src + bo.forEach((objMeta, idx) => { + if ((objMeta.type === 8 || objMeta.type === 9) && j.b.objects && j.b.objects[idx + 1] && !j.b.objects[idx + 1].src) { + j.b.objects[idx + 1].src = placeholder + } + }) + + // 加载 JSON,并在回调中重新生成二维码和条形码 + canvas1.loadFromJSON(j.f, function() { + regenerateQrCodesAndBarcodes(canvas1, fo) + canvas1.renderAll() + }) + canvas2.loadFromJSON(j.b, function() { + regenerateQrCodesAndBarcodes(canvas2, bo) + canvas2.renderAll() + }) background_image1 = canvas1.getObjects()[0] background_image2 = canvas2.getObjects()[0]