// design1核心功能模块 // 注意:此代码在layui.use回调函数内部执行,不需要$(function())包装 // 全局变量已在主入口文件中定义,这里只需要初始化 $("#object_attribute").css("height", "470px"); $("#obj_list").css("height", document.body.clientHeight - 520); $(".obj_list").css("height", $("#obj_list").height() - 32); $(".main").show(); $(".canvas_box").css("height", document.body.clientHeight - 100); zoom = $(".canvas_bg_img").width() / 2787 $("#canvas1").attr("width", $(".canvas_box").width() / zoom); $("#canvas1").attr("height", $(".canvas_box").height() / zoom); $("#canvas2").attr("width", $(".canvas_box").width() / zoom); $("#canvas2").attr("height", $(".canvas_box").height() / zoom); // 优化性能:在创建 Fabric Canvas 之前,先设置 canvas context 的 willReadFrequently // 注意:这需要在 Fabric.js 创建 canvas 之前执行 try { const canvas1El = document.getElementById('canvas1'); const canvas2El = document.getElementById('canvas2'); if (canvas1El) { // 先获取 context 并设置 willReadFrequently,这样 Fabric.js 创建时会复用这个 context canvas1El.getContext('2d', { willReadFrequently: true }); } if (canvas2El) { canvas2El.getContext('2d', { willReadFrequently: true }); } } catch (e) { // 如果浏览器不支持 willReadFrequently,忽略错误 } // 初始化Canvas对象 canvas1 = new fabric.Canvas('canvas1'); canvas2 = new fabric.Canvas('canvas2'); // 同步到 window 对象,确保在 eval() 加载 .jsc 文件时也能访问 window.canvas1 = canvas1; window.canvas2 = canvas2; fabric.Object.prototype.objectCaching = false; ctx1 = canvas1.getSelectionContext(); ctx2 = canvas2.getSelectionContext(); is_bgi_add = false; // 撤销/重做过程中使用的标志位,防止并发操作和误记录历史 window._isApplyingHistory = false; // 同步到 window 对象 window.ctx1 = ctx1; window.ctx2 = ctx2; window.is_bgi_add = is_bgi_add; canvas1.zoomToPoint(new fabric.Point(0, 0), 1); canvas2.zoomToPoint(new fabric.Point(0, 0), 1); // 初始化标尺 initRulers(); $("#source_front").width(zoom * $("#source_front").width()); $("#source_back").width(zoom * $("#source_back").width()); $(".canvas-container:eq(0)").css('transform', 'scale(' + zoom + ')') $(".canvas-container:eq(1)").css('transform', 'scale(' + zoom + ')') $(".canvas-container:eq(0)").css('width', 0) $(".canvas-container:eq(1)").hide(); canvas = canvas1; window.canvas = canvas; fabric.Object.prototype.set({ borderColor: "#9013FE", cornerColor: "#9013FE", //激活状态角落图标的填充颜色 cornerStrokeColor: "#9013FE", //激活状态角落图标的边框颜色 borderOpacityWhenMoving: 1, borderScaleFactor: 6, cornerSize: 24, cornerStyle: "circle", //rect,circle centeredScaling: false, //角落放大缩小是否是以图形中心为放大原点 centeredRotation: true, //旋转按钮旋转是否是左上角为圆心旋转 transparentCorners: false, //激活状态角落的图标是否透明 rotatingPointOffset: 20, //旋转距旋转体的距离 padding: 0, }); canvas1.preserveObjectStacking = true; canvas2.preserveObjectStacking = true; var front_list = []; function applyFontList(data) { var newFontList = []; (data || []).map(function(item) { if (item.indexOf('"') === 0) { newFontList.push(item.replace(/^"|"$/g, '')); } else { newFontList.push(item); } }); front_list = newFontList; for (var i = 0; i < front_list.length; i++) { var item = front_list[i]; $("#text_font_family").append(""); $("#circle_text_font_family").append(""); $("#out_text_font_family").append(""); $("#barcode_font_family").append(""); $("#count_font_family").append(""); } } if (typeof ipcRenderer !== 'undefined' && ipcRenderer) { ipcRenderer.on('font-list', function(event, data) { applyFontList(data); }); } else if (typeof window !== 'undefined' && window.platformBridge && window.platformBridge.getSystemFonts) { window.platformBridge.getSystemFonts().then(applyFontList); } function applySysLan(data) { let lang = localStorage.getItem("lang"); if (lang) { s_lan = lang; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge(lang); $("#language_select").val(lang); return; } switch (data) { case 'zh-CN': s_lan = "zh"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("zh"); $("#language_select").val("zh"); localStorage.setItem("lang", "zh"); break; case 'zh': s_lan = "zh"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("zh"); $("#language_select").val("zh"); localStorage.setItem("lang", "zh"); break; case 'zh-TW': s_lan = "ozh"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("ozh"); $("#language_select").val("ozh"); localStorage.setItem("lang", "ozh"); break; case 'en': s_lan = "en"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("en"); $("#language_select").val("en"); localStorage.setItem("lang", "en"); break; case 'en-AU': s_lan = "en"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("en"); $("#language_select").val("en"); localStorage.setItem("lang", "en"); break; case 'en-CA': s_lan = "en"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("en"); $("#language_select").val("en"); localStorage.setItem("lang", "en"); break; case 'en-GB': s_lan = "en"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("en"); $("#language_select").val("en"); localStorage.setItem("lang", "en"); break; case 'en-NZ': s_lan = "en"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("en"); $("#language_select").val("en"); localStorage.setItem("lang", "en"); break; case 'en-US': s_lan = "en"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("en"); $("#language_select").val("en"); localStorage.setItem("lang", "en"); break; case 'en-ZA': s_lan = "en"; // 同步到全局作用域(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } langua_ge("en"); $("#language_select").val("en"); localStorage.setItem("lang", "en"); break; } } if (typeof ipcRenderer !== 'undefined' && ipcRenderer) { ipcRenderer.on('sys-lan', function(event, data) { applySysLan(data); }); } else if (typeof window !== 'undefined' && window.platformBridge && window.platformBridge.getLocale) { applySysLan(window.platformBridge.getLocale()); } function onCloseConfirm() { layer.confirm('' + language_str("whetherSave") + '', { btn: [language_str("save"), language_str("noSave"), language_str("cancel")] , btn3: function (index, layero) {} }, function (index, layero) { if (typeof window.output === 'function') { window.output(function() { if (ipcRenderer) ipcRenderer.send('run-close'); else if (window.platformBridge && window.platformBridge.runClose) window.platformBridge.runClose(); }); } }, function (index) { if (ipcRenderer) ipcRenderer.send('run-close'); else if (window.platformBridge && window.platformBridge.runClose) window.platformBridge.runClose(); }); } if (typeof ipcRenderer !== 'undefined' && ipcRenderer) { ipcRenderer.on('close', function(event, message) { onCloseConfirm(); }); } else if (typeof window !== 'undefined' && window.platformBridge && window.platformBridge.onClose) { window.platformBridge.onClose(onCloseConfirm); } addBackground();//添加背景 白色卡片 initAligningGuidelines(canvas1); initAligningGuidelines(canvas2); //canvas.setZoom(0.5) //recordObjs1.push(JSON.stringify(objs1)); //recordJson1.push(canvas1.toJSON(["selectable","hoverable","hoverCursor","text","fontStyle","fontWeight","underline"])); //recordObjs2.push(JSON.stringify(objs2)); //recordJson2.push(canvas2.toJSON(["selectable","hoverable","hoverCursor","text","fontStyle","fontWeight","underline"])); canvas.renderAll();//重新渲染画布 // 立即启动事件初始化(必须在 slider 初始化之前) initCanvasEvents(); var zoomSlider = slider.render({ elem: '#zoomSlide', //绑定元素 min: 25, max: 500, value: 100, change(val) { canvas.zoomToPoint( new fabric.Point(0, 0), val / 100 ); // zoom = val / 100; //$(".canvas-container").css("transform","scale(" + val / 100 + ")") } }); // =========================================================== // Slider 滑块初始化 // =========================================================== var circle_text_size = slider.render({ elem: '#circle_text_size', min: 10, max: 120, change: function (value) { if (canvas.getActiveObject()) { canvas.getActiveObject().set("fontSize", value); canvas.renderAll(); } } }); var circle_text_diameter = slider.render({ elem: '#circle_text_diameter', min: 500, max: 4000, change: function (value) { if (canvas.getActiveObject()) { canvas.getActiveObject().set("diameter", value); canvas.renderAll(); } } }); var out_pic_op = slider.render({ elem: '#out_pic_op', change: function (value) { if (canvas.getActiveObject()) { canvas.getActiveObject().set('opacity', (100 - value) / 100); canvas.renderAll(); } } }); var pic_op = slider.render({ elem: '#pic_op', change: function (value) { if (canvas.getActiveObject()) { canvas.getActiveObject().set("opacity", (100 - value) / 100); canvas.renderAll(); } } }); var rect_op = slider.render({ elem: '#rect_op', change: function (value) { if (canvas.getActiveObject()) { canvas.getActiveObject().set("opacity", (100 - value) / 100); canvas.renderAll(); } } }); var circle_op = slider.render({ elem: '#circle_op', change: function (value) { if (canvas.getActiveObject()) { canvas.getActiveObject().set("opacity", (100 - value) / 100); canvas.renderAll(); } } }); window.rotate = function (id) { let angle = $(`#${id}`).attr("angle") - 0; angle += 90; $(`#${id}`).css("transform", `rotate(${angle}deg)`); $(`#${id}`).attr("angle", angle); } function addBackground() { // 类型改变 fabric.Image.fromURL(soonAsset('bg_front_1.png'), function (image) { let width = $("#canvas1").width() image.left = ($("#canvas1").width() - image.width * image.get("scaleX")) / 2; image.top = ($("#canvas1").height() - image.height * image.get("scaleY")) / 2; image.selectable = false; image.hoverable = false; image.hoverCursor = "default" image.setSrc(image.toDataURL(), function (image) { image.scale(1, 1); background_image1 = image; background_image = background_image1; window.background_image1 = background_image1; window.background_image = background_image; canvas.add(image); canvas.renderAll(); //pre_objs1.push(JSON.stringify(objs1)); //pre_json1.push(canvas1.toJSON(["selectable","hoverable","hoverCursor"])); recordObjs1.push(JSON.stringify(objs1)); recordJson1.push(canvas1.toJSON(TO_JSON_PROPERTIES)); }); // 类型改变 fabric.Image.fromURL(soonAsset('bg_back.png'), function (image) { image.left = ($("#canvas2").width() - image.width) / 2; image.top = ($("#canvas2").height() - image.height) / 2; image.selectable = false; image.hoverable = false; image.hoverCursor = "default" image.setSrc(image.toDataURL(), function (image) { background_image2 = image; window.background_image2 = background_image2; canvas2.add(image); canvas2.renderAll(); //pre_objs2.push(JSON.stringify(objs2)); //pre_json2.push(canvas2.toJSON(["selectable","hoverable","hoverCursor"])); recordObjs2.push(JSON.stringify(objs2)); recordJson2.push(canvas2.toJSON(TO_JSON_PROPERTIES)); let file = GetFile().get('file'); if (!file && typeof sessionStorage !== 'undefined' && !window.ipcRenderer) { try { file = sessionStorage.getItem('soondesign_open_file'); if (file) { sessionStorage.removeItem('soondesign_open_file'); sessionStorage.removeItem('soondesign_open_type'); } } catch (e) {} } if (file && file != 'empty') { var p = window.openFile(file) if (p && p.then) p.then(function() {}, function() {}) } }); }); is_bgi_add = true; }); } // 将 updateControls 附加到 window 对象,确保在 eval() 加载 .jsc 文件时也能访问 window.updateControls = function updateControls() { // 使用 window.canvas 和 window.background_image 作为后备,确保在 eval() 执行时也能访问 const currentCanvas = window.canvas || canvas; const currentBackgroundImage = window.background_image || background_image; if (!currentCanvas || !currentCanvas.getActiveObject()) return; $("#text_r").val(currentCanvas.getActiveObject().get("angle").toFixed(0)); $("#text_x").val((currentCanvas.getActiveObject().get("left") - currentBackgroundImage.left).toFixed(0)); $("#text_y").val((currentCanvas.getActiveObject().get("top") - currentBackgroundImage.top).toFixed(0)); $("#text_h").val((currentCanvas.getActiveObject().get("scaleY") * currentCanvas.getActiveObject().get("height")).toFixed(0)); $("#text_w").val((currentCanvas.getActiveObject().get("scaleX") * currentCanvas.getActiveObject().get("width")).toFixed(0)); // 根据锁定状态显示图标(使用lockMovementX判断,因为锁定时会设置所有lock属性) if (currentCanvas.getActiveObject().get("lockMovementX")) { $("#lock_img").attr("src", soonAsset("lock20.png"))//已锁定 } else { $("#lock_img").attr("src", soonAsset("unlock20.png"))//未锁定 } }; // 向后兼容 function updateControls() { return window.updateControls(); } function selectObject(target, index) { updateControls(); $("#base_control").show(); //$("#text_x").val((target.left - background_image.left).toFixed(1)); //$("#text_y").val((target.top - background_image.top).toFixed(1)); //$("#text_w").val(parseFloat(target.get("scaleX") * target.get("width")).toFixed(1)); //$("#text_h").val(parseFloat(target.get("scaleY") * target.get("height")).toFixed(1)); //$("#text_r").val(target.get("angle").toFixed(0)); } function addPic(pointer) { pre_add_image.left = pointer.x; pre_add_image.top = pointer.y; canvas.add(pre_add_image); objs.push({ type: 1, black: false }); canvas.renderAll(); updateList(); window.recordState(); //OpenDialog(); //function OpenDialog() //{ // dialog.showOpenDialog({ // title: "请选择图片", // buttonLabel: "确认", // filters: [ // { name: 'Image File Type', extensions: ['png', 'jpg'] }, // ] // }).then(result => { // if(result.canceled)return; // //console.log(result.filePaths) // fabric.Image.fromURL(result.filePaths[0], function(image) { // image.left = pointer.x; // image.top = pointer.y; // // canvas.add(image); // objs.push({type: 1}); // canvas.renderAll(); // updateList(); // window.recordState(); // } ); // }).catch(err => { // console.log(err) // }) //} } function selectPic(target, index) { //透明度 $("#pic_control").show(); $("#set_bg").show(); let activeObj = canvas.getActiveObject(); if (typeof pic_op !== 'undefined' && pic_op.setValue) { pic_op.setValue(100 - (activeObj.get("opacity") * 100)); } else { $("#pic_op").next().children(".layui-slider-bar").css("width", (1 - activeObj.get("opacity")) * 100 + "%"); $("#pic_op").next().children(".layui-slider-handle").css("left", (1 - activeObj.get("opacity")) * 100 + "%"); } let idx = getIndex(canvas.getActiveObject()); // $("#pic_black").prop("checked", objs[idx-1].black ? 'checked' : ''); $("#out_pic_control").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#line_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } function addOutPic(pointer) { fabric.Image.fromURL(soonAsset('outpic_extra.png'), function (image) { let width = canvas.getWidth(); let height = canvas.getHeight(); image.left = pointer.x; image.top = pointer.y; image.opacity = 1; //image.on("selected",function(){//test well // console.log(222); //}); image.setSrc(image.toDataURL(), function (image) { canvas.add(image); objs.push({ type: 2, name: resName("OUT_PIC_"), black: false }); canvas.renderAll(); updateList(); window.recordState(); }); }); } function selectOutPic(target, index) { //字段名 $("#out_pic_control").show(); if (typeof out_pic_op !== 'undefined' && out_pic_op.setValue) { out_pic_op.setValue(100 - (canvas.getActiveObject().get("opacity") * 100)); } else { $("#out_pic_op").next().children(".layui-slider-bar").css("width", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%"); $("#out_pic_op").next().children(".layui-slider-handle").css("left", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%"); } let idx = getIndex(canvas.getActiveObject()); $("#out_pic_field_name").val(objs[idx - 1].name); // $("#out_pic_black").prop("checked", objs[idx-1].black ? 'checked' : ''); $("#pic_control").hide(); $("#set_bg").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#line_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } function addText(pointer) { let text = new fabric.Text('TEXT', {//源:文本 left: pointer.x, top: pointer.y, fill: "#000000", textBackgroundColor: "", fontStyle: "normal", fontWeight: "normal", fontSize: 100, underline: false, linethrough: false, fontFamily: 'Arial' }); text.setControlVisible("ml", false); text.setControlVisible("mt", false); text.setControlVisible("mr", false); text.setControlVisible("mb", false); canvas.add(text); objs.push({ type: 3, black: false }); canvas.renderAll(); updateList(); window.recordState(); } function selectText(target, index) { //console.log(canvas.getActiveObject().get("fontFamily")); $("#text_control").show(); $("#text_color").val(canvas.getActiveObject().get("fill")); $("#text_back_color").val(canvas.getActiveObject().get("textBackgroundColor") == "" ? '#ffffff' : canvas.getActiveObject().get("textBackgroundColor")); let val = parseFloat(canvas.getActiveObject().get("fontSize")) * 72 / dpi if (val % 0.5 !== 0) val = Math.round(val * 2) / 2 $("#text_size").val(val); $("#text_text").val(canvas.getActiveObject().get("text")); $("#text_font_family").val(canvas.getActiveObject().get("fontFamily")); if (canvas.getActiveObject().get("underline") == true) { $("#text_underline").addClass("ui-radio-acitve") } else { $("#text_underline").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("fontWeight") == "bold") { $("#text_bold").addClass("ui-radio-acitve") } else { $("#text_bold").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("fontStyle") == "italic") { $("#text_italics").addClass("ui-radio-acitve") } else { $("#text_italics").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("linethrough") == true) { $("#text_linethrough").addClass("ui-radio-acitve") } else { $("#text_linethrough").removeClass("ui-radio-acitve") } $("#circle_text_control").hide(); $("#pic_control").hide(); $("#set_bg").hide(); $("#out_pic_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#line_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } function addCircleText(pointer) { let distance = getDisdance(pointer.x, pointer.y, canvas.width / 2, canvas.height / 2) let angleDeg = getDeg(pointer) let text = new fabric.CurvedText('Circle TEXT', {//源:圆形文本 left: pointer.x, top: pointer.y, fill: "#000000", textBackgroundColor: "", fontStyle: "normal", fontWeight: "normal", diameter: distance * 2, fontSize: 100, underline: false, linethrough: false, lockScalingX: true, lockScalingY: true, fontFamily: 'Arial', originX: 'center', // originY: 'center', angle: angleDeg, flipped: pointer.y > canvas.height / 2 ? true : false }); // distance = getDisdance(pointer.x+text.width/2, pointer.y, canvas.width/2,canvas.height/2) // text.set({diameter: distance*2}) text.setControlVisible("ml", false); text.setControlVisible("mt", false); text.setControlVisible("mr", false); text.setControlVisible("mb", false); canvas.add(text); objs.push({ type: 11, black: false }); canvas.renderAll(); updateList(); window.recordState(); } function selectCircleText() { // 检查是否有选中对象 if (!canvas || !canvas.getActiveObject()) return; let idx = getIndex(canvas.getActiveObject()); $("#circle_text_control").show(); $("#circle_text_color").val(canvas.getActiveObject().get("fill")); $("#circle_text_back_color").val(canvas.getActiveObject().get("textBackgroundColor") == "" ? '#ffffff' : canvas.getActiveObject().get("textBackgroundColor")); // 检查 circle_text_size 是否存在且有 setValue 方法 if (typeof circle_text_size !== 'undefined' && circle_text_size && typeof circle_text_size.setValue === 'function') { circle_text_size.setValue(canvas.getActiveObject().get("fontSize") - 10); } else { $("#circle_text_size").next().children(".layui-slider-bar").css("width", ((canvas.getActiveObject().get("fontSize") - 10 - 10) / (120 - 10)) * 100 + "%"); $("#circle_text_size").next().children(".layui-slider-handle").css("left", ((canvas.getActiveObject().get("fontSize") - 10 - 10) / (120 - 10)) * 100 + "%"); } // 检查 circle_text_diameter 是否存在且有 setValue 方法 if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter && typeof circle_text_diameter.setValue === 'function') { circle_text_diameter.setValue(canvas.getActiveObject().get("diameter") - 500); } else { $("#circle_text_diameter").next().children(".layui-slider-bar").css("width", ((canvas.getActiveObject().get("diameter") - 500 - 500) / (4000 - 500)) * 100 + "%"); $("#circle_text_diameter").next().children(".layui-slider-handle").css("left", ((canvas.getActiveObject().get("diameter") - 500 - 500) / (4000 - 500)) * 100 + "%"); } $("#circle_text_center").prop("checked", objs[idx - 1].circleCenter ? 'checked' : ''); $("#circle_text_text").val(canvas.getActiveObject().get("text")); $("#circle_text_font_family").val(canvas.getActiveObject().get("fontFamily")); if (canvas.getActiveObject().get("underline") == true) { $("#circle_text_underline").addClass("ui-radio-acitve") } else { $("#circle_text_underline").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("fontWeight") == "bold") { $("#circle_text_bold").addClass("ui-radio-acitve") } else { $("#circle_text_bold").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("fontStyle") == "italic") { $("#circle_text_italics").addClass("ui-radio-acitve") } else { $("#circle_text_italics").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("linethrough") == true) { $("#circle_text_linethrough").addClass("ui-radio-acitve") } else { $("#circle_text_linethrough").removeClass("ui-radio-acitve") } $("#pic_control").hide(); $("#set_bg").hide(); $("#rotate").hide(); $("#out_pic_control").hide(); $("#text_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#line_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } function addOutText(pointer) { //MERGE_TEXT_1 let text = new fabric.Text("MERGE TEXT", {//源:合成文本 left: pointer.x, top: pointer.y, fill: "#000000", fontStyle: "normal", fontWeight: "normal", fontSize: 100, textBackgroundColor: "", underline: false, linethrough: false, fontFamily: 'Arial', textAlign: 'center' }); //text.on({ // 'scaling': function(e) { // var obj = this, // w = obj.width * obj.scaleX, // h = obj.height * obj.scaleY; // // obj.set({ // 'height' : h, // 'width' : w, // 'scaleX' : 1, // 'scaleY' : 1 // }); // } //}); text.setControlVisible("ml", false); text.setControlVisible("mt", false); text.setControlVisible("mr", false); text.setControlVisible("mb", false); canvas.add(text); objs.push({ type: 4, name: resName("OUT_TEXT_"), exceed: false, autoWrap: false, fixSize: false, black: false, align: 'center' }); canvas.renderAll(); updateList(); window.recordState(); } function selectOutText(target, index) { //color //size const align = canvas.getActiveObject().get('textAlign') if (align === 'left') { $('#out_left_alignment').parent().addClass('tool1') } else if (align === 'right') { $('#out_right_alignment').parent().addClass('tool1') } else { $('#out_center_alignment').parent().addClass('tool1') } $("#out_text_control").show(); $("#out_text_color").val(canvas.getActiveObject().get("fill")); $("#out_text_text").val(canvas.getActiveObject().get("text")); let val = parseFloat(canvas.getActiveObject().get("fontSize")) * 72 / dpi if (val % 0.5 !== 0) val = Math.round(val * 2) / 2 $("#out_text_size").val(val); $("#out_text_back_color").val(canvas.getActiveObject().get("textBackgroundColor") == "" ? '#ffffff' : canvas.getActiveObject().get("textBackgroundColor")); let idx = getIndex(canvas.getActiveObject()); $("#out_text_field_name").val(objs[idx - 1].name); $("#out_text_font_family").val(canvas.getActiveObject().get("fontFamily")); $("#exceed").prop("checked", objs[idx - 1].exceed ? 'checked' : ''); $("#autoWrap").prop("checked", objs[idx - 1].autoWrap ? 'checked' : ''); $("#fixSize").prop("checked", objs[idx - 1].fixSize ? 'checked' : ''); if (canvas.getActiveObject().get("underline") == true) { $("#out_text_underline").addClass("ui-radio-acitve") } else { $("#out_text_underline").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("fontWeight") == "bold") { $("#out_text_bold").addClass("ui-radio-acitve") } else { $("#out_text_bold").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("fontStyle") == "italic") { $("#out_text_italics").addClass("ui-radio-acitve") } else { $("#out_text_italics").removeClass("ui-radio-acitve") } if (canvas.getActiveObject().get("linethrough") == true) { $("#out_text_linethrough").addClass("ui-radio-acitve") } else { $("#out_text_linethrough").removeClass("ui-radio-acitve") } $("#pic_control").hide(); $("#set_bg").hide(); $("#out_pic_control").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#line_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } function addRect(pointer) { let rect = new fabric.Rect({ left: pointer.x, top: pointer.y, fill: '', stroke: "#ff0000", strokeWidth: 10, width: 300, height: 300 }); canvas.add(rect); objs.push({ type: 5, black: false }); canvas.renderAll(); updateList(); window.recordState(); } function selectRect(target, index) { //color $("#rect_control").show(); $("#rect_color").val(canvas.getActiveObject().get("fill") == "" ? "#ffffff" : canvas.getActiveObject().get("fill")); $("#rect_stroke").val(canvas.getActiveObject().get("stroke") == "" ? "#ffffff" : canvas.getActiveObject().get("stroke")); $("#rect_stroke_width").val(canvas.getActiveObject().get("strokeWidth")); $("#rect_radius").val(canvas.getActiveObject().get("rx")); if (typeof rect_op !== 'undefined' && rect_op.setValue) { rect_op.setValue(100 - (canvas.getActiveObject().get("opacity") * 100)); } else { $("#rect_op").next().children(".layui-slider-bar").css("width", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%"); $("#rect_op").next().children(".layui-slider-handle").css("left", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%"); } let a = canvas.getActiveObject().getCoords(); $("#pic_control").hide(); $("#set_bg").hide(); $("#out_pic_control").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#out_text_control").hide(); $("#circle_control").hide(); $("#line_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } function addCircle(pointer) { let circle = new fabric.Circle({ left: pointer.x, top: pointer.y, fill: '', stroke: '#ff0000', strokeWidth: 10, radius: 150, strokeUniform: true, }); canvas.add(circle); objs.push({ type: 6, black: false }); canvas.renderAll(); updateList(); window.recordState(); } function selectCircle(target, index) { //border-color //color $("#circle_control").show(); $("#circle_color").val(canvas.getActiveObject().get("fill") == "" ? "#ffffff" : canvas.getActiveObject().get("fill")); $("#circle_stroke").val(canvas.getActiveObject().get("stroke") == "" ? "#ffffff" : canvas.getActiveObject().get("stroke")); $("#circle_stroke_width").val(canvas.getActiveObject().get("strokeWidth")); if (typeof circle_op !== 'undefined' && circle_op.setValue) { circle_op.setValue(100 - (canvas.getActiveObject().get("opacity") * 100)); } else { $("#circle_op").next().children(".layui-slider-bar").css("width", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%"); $("#circle_op").next().children(".layui-slider-handle").css("left", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%"); } $("#pic_control").hide(); $("#set_bg").hide(); $("#out_pic_control").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#line_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } function addLine(pointer) { let line = new fabric.Line([100, 200, 400, 200], { left: pointer.x, top: pointer.y, stroke: '#ff0000', strokeWidth: 10, strokeDashArray: [0, 0], }); line.setControlVisible("tl", false); line.setControlVisible("tr", false); line.setControlVisible("br", false); line.setControlVisible("bl", false); line.setControlVisible("mt", false); line.setControlVisible("mb", false); canvas.add(line); objs.push({ type: 7, black: false }); canvas.renderAll(); updateList(); window.recordState(); } function selectLine(target, index) { //color //weight $("#line_control").show(); let idx = getIndex(canvas.getActiveObject()); $("#line_color").val(canvas.getActiveObject().get("stroke")); $("#line_dist").val(canvas.getActiveObject().get("strokeDashArray")[0]); $("#text_h").val(canvas.getActiveObject().get("strokeWidth")) $("#pic_control").hide(); $("#set_bg").hide(); $("#out_pic_control").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } function addQrCode(pointer) { let qr = jrQrcode.getQrBase64('https://www.cardsoon.com', { padding: 0 }); fabric.Image.fromURL(qr, function (image) { image.left = pointer.x; image.top = pointer.y; image.scale(2.4, 2.4) canvas.add(image); objs.push({ type: 8, name: resName("QR_CODE_"), color: "#000000", val: "https://www.cardsoon.com", black: false }); canvas.renderAll(); updateList(); window.recordState(); }); } function selectQrCode(target, index) { //字段名 //background-color //color $("#qrcode_Controll").show(); let idx = getIndex(canvas.getActiveObject()); $("#qrcode_field_name").val(objs[idx - 1].name); $("#qrcode_color").val(objs[idx - 1].color); $("#qrcode_val").val(objs[idx - 1].val); $("#line_control").hide(); $("#pic_control").hide(); $("#set_bg").hide(); $("#out_pic_control").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#counter_control").hide(); $("#barcode_controll").hide(); } function addBarCode(pointer) { JsBarcode("#barcode", "123456789", { margin: 0, lineColor: "#000000", fontSize: 18, font: "Arial" }); let barcode = document.getElementById('barcode'); let bar = barcode.toDataURL("image/png"); fabric.Image.fromURL(bar, function (image) { image.left = pointer.x; image.top = pointer.y; image.scale(2.4, 2.4) canvas.add(image); objs.push({ type: 9, name: resName("BAR_CODE_"), val: "123456789", color: "#000000", fontSize: 18, font: "Arial", show: false, black: false });//show是取消文字显示 canvas.renderAll(); updateList(); window.recordState(); }); } function selectBarCode(target, index) { //字段名 //background-color //color $("#barcode_controll").show(); let idx = getIndex(canvas.getActiveObject()); $("#barcode_field_name").val(objs[idx - 1].name); $("#barcode_font_family").val(objs[idx - 1].font); let val = parseFloat(objs[idx - 1].fontSize) * 72 / dpi if (val % 0.5 !== 0) val = Math.round(val * 2) / 2 $("#barcode_size").val(val); $("#barcode_val").val(objs[idx - 1].val); $("#barcode_show").prop("checked", objs[idx - 1].show ? 'checked' : ''); $("#line_control").hide(); $("#pic_control").hide(); $("#set_bg").hide(); $("#out_pic_control").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#counter_control").hide(); $("#qrcode_Controll").hide(); } function addCounter(pointer) { let text = new fabric.Text('0', { left: pointer.x, top: pointer.y, fontSize: 100, fill: "#000000", }); canvas.add(text); objs.push({ type: 10, name: resName("COUNTER_"), start: 0, add: 1, black: false }); canvas.renderAll(); updateList(); window.recordState(); } function selectCounter(target, index) { //起始 //终止 //增量 $("#counter_control").show(); let idx = getIndex(canvas.getActiveObject()); $("#counter_start").val(objs[idx - 1].start); $("#counter_add").val(objs[idx - 1].add); $("#counter_color").val(canvas.getActiveObject().get("fill")); $("#count_font_family").val(canvas.getActiveObject().get("fontFamily")); let val = parseFloat(canvas.getActiveObject().get("fontSize")) * 72 / dpi if (val % 0.5 !== 0) val = Math.round(val * 2) / 2 $("#count_size").val(val); $("#line_control").hide(); $("#pic_control").hide(); $("#set_bg").hide(); $("#out_pic_control").hide(); $("#text_control").hide(); $("#circle_text_control").hide(); $("#out_text_control").hide(); $("#rect_control").hide(); $("#circle_control").hide(); $("#qrcode_Controll").hide(); $("#barcode_controll").hide(); } // 将 updateList 附加到 window 对象,确保全局可访问 window.updateList = function updateList() { let str = ""; let i = 0; const rowStyle = "display:flex; justify-content:space-between; align-items:center; height:32px; padding:0 5px; cursor:pointer; border-bottom:1px solid #444; color:#ccc; font-size:12px; position:relative;"; const leftStyle = "display:flex; align-items:center; overflow:hidden; white-space:nowrap; max-width:180px;"; const indexStyle = "min-width:24px; text-align:center; padding-left:5px; color:#666; border-left:1px solid #555;"; for (let item of objs) { let displayIndex = i + 1; let iconName = "rect.svg"; switch (item.type) { case 1: iconName = "images.svg"; break; case 2: iconName = "images_add.svg"; break; case 3: iconName = "text.svg"; break; case 4: iconName = "text2.svg"; break; case 5: iconName = "rect.svg"; break; case 6: iconName = "round.svg"; break; case 7: iconName = "line.svg"; break; case 8: iconName = "qrcode.svg"; break; case 9: iconName = "barcode.svg"; break; case 10: iconName = "counter.svg"; break; case 11: iconName = "text3.svg"; break; } let nameText = item.name ? item.name : (item.type === 3 ? "TEXT_" + displayIndex : (item.type === 1 ? "IMG_" + displayIndex : "OBJ_" + displayIndex)); str = `