// design1.js - 主入口文件 // 导入公共模块(不依赖jQuery的部分);网页端由页面 script 标签提前加载 if (typeof require !== 'undefined') { try { require('./common/fabric-ext.js'); } catch (e) {} } // 过滤 Canvas2D willReadFrequently 警告(不影响功能,只是性能提示) if (typeof console !== 'undefined' && console.warn) { const originalWarn = console.warn; console.warn = function (...args) { const message = args.join(' '); // 过滤掉 willReadFrequently 相关的警告 if (message.includes('willReadFrequently') || message.includes('getImageData')) { return; // 不输出这个警告 } originalWarn.apply(console, args); }; } // 使用平台桥(桌面端由 design1.html 先加载 lib/platform/electron.js 注入) var remote = typeof window !== 'undefined' ? window.remote : null; var path = typeof window !== 'undefined' ? window.path : null; var exePath = typeof window !== 'undefined' ? window.exePath : ''; var ipcRenderer = typeof window !== 'undefined' ? window.ipcRenderer : null; var dialog = typeof window !== 'undefined' ? window.dialog : null; var clipboard = typeof window !== 'undefined' ? window.clipboard : null; var jrQrcode, JsBarcode; if (typeof require !== 'undefined') { try { jrQrcode = require('jr-qrcode'); } catch (e) {} try { JsBarcode = require('jsbarcode'); } catch (e) {} } var dpi = 600; if (ipcRenderer) { ipcRenderer.send('get-sys-fonts'); ipcRenderer.send('get-scale-rate'); } // 使用layui layui.use(['layer', 'slider', 'form', 'colorpicker'], function () { let myDate = new Date(); let s_lan = ""; // 确保 s_lan 在全局作用域中可用(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.s_lan = s_lan; } if (typeof global !== 'undefined') { global.s_lan = s_lan; } if (ipcRenderer) ipcRenderer.send('get-sys-language'); var $ = layui.$; var layer = layui.layer; layer.config({ skin: 'soon-layer' }); var slider = layui.slider; var form = layui.form; var colorpicker = layui.colorpicker; // 确保所有必要的变量在全局作用域中可用(用于 .jsc 文件加载) // 在 Electron 的渲染进程中,需要同时设置 window 和 global if (typeof window !== 'undefined') { window.$ = $; window.jQuery = $; window.ipcRenderer = ipcRenderer; window.layer = layer; window.slider = slider; window.form = form; window.colorpicker = colorpicker; window.dialog = dialog; window.remote = remote; window.path = path; window.jrQrcode = jrQrcode; window.JsBarcode = JsBarcode; window.clipboard = clipboard; window.dpi = dpi; // language_str 会在后面定义,但先确保引用正确 } // 在 Node.js 上下文中也设置(require 加载 .jsc 文件时使用) if (typeof global !== 'undefined') { global.$ = $; global.jQuery = $; global.ipcRenderer = ipcRenderer; global.layer = layer; global.slider = slider; global.form = form; global.colorpicker = colorpicker; global.dialog = dialog; global.remote = remote; global.path = path; global.jrQrcode = jrQrcode; global.JsBarcode = JsBarcode; global.clipboard = clipboard; global.dpi = dpi; } var layer = layui.layer; var slider = layui.slider; var colorpicker = layui.colorpicker; // 历史记录文件路径(供 output.js 使用) var fullPath = (path && exePath) ? path.join(exePath, 'data.json') : (typeof window !== 'undefined' ? window.fullPath : ''); // 确保 fullPath 在全局作用域中可用(用于 .jsc 文件加载) if (typeof window !== 'undefined') { window.fullPath = fullPath; window.exePath = exePath; } if (typeof global !== 'undefined') { global.fullPath = fullPath; global.exePath = exePath; } // ========================================== // 公共函数定义(需要在layui.use回调内部,因为依赖jQuery) // 注意:所有函数都附加到 window 对象,确保在 eval() 加载 .jsc 文件时也能访问 // ========================================== // DES加密函数 window.desEncrypt = function desEncrypt(str, key = "df6a551ca43181fc485f3043bcdd2fbc") { var APIFMS; try { // 确保输入字符串是 UTF-8 编码 var keyHex = CryptoJS.enc.Utf8.parse(key); var encrypted = CryptoJS.DES.encrypt(str, keyHex, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); // 使用 Base64 编码确保中文字符正确输出 APIFMS = CryptoJS.enc.Base64.stringify(encrypted.ciphertext); } catch (err) { APIFMS = ''; } return APIFMS; }; // 向后兼容 function desEncrypt(str, key = "df6a551ca43181fc485f3043bcdd2fbc") { return window.desEncrypt(str, key); } // 多语言切换 window.langua_ge = function langua_ge(lan = 'zh') { $("[language='m']").each(function (i) { $(this).html($(this).attr(lan)); }); $("[language='t']").each(function (i) { $(this).attr("title", $(this).attr(lan)); }); }; // 向后兼容 function langua_ge(lan = 'zh') { return window.langua_ge(lan); } // 多语言字符串获取 window.language_str = function language_str(str) { let t = { "whetherSave": { zh: "是否保存当前文件?", ozh: "是否保存當前文件?", en: "Do you want to save the current file?" }, "save": { zh: "保存", ozh: "保存", en: "Save" }, "noSave": { zh: "不保存", ozh: "不保存", en: "No saving" }, "cancel": { zh: "取消", ozh: "取消", en: "Cancel" }, "saveSucc": { zh: "保存成功至", ozh: "保存成功至", en: "Save successfully to" }, "saveFile": { zh: "保存文件", ozh: "保存文件", en: "Save file" }, "display": { zh: "预览", ozh: "預覽", en: "Display" }, "output": { zh: "导出", ozh: "導出", en: "Export" }, "bg": { zh: "背景", ozh: "背景", en: "Background" }, "selectPic": { zh: "请选择图片", ozh: "請選擇圖片", en: "Please select a picture" }, "img": { zh: "圖片", ozh: "圖片", en: "Image" }, "simg": { zh: "合成圖片", ozh: "合成圖片", en: "Synthesized Image" }, "text": { zh: "文本", ozh: "文本", en: "Text" }, "ctext": { zh: "圆形文本", ozh: "圆形文本", en: "Circle Text" }, "stext": { zh: "合成文本", ozh: "合成文本", en: "Synthesized Text" }, "rect": { zh: "矩形", ozh: "矩形", en: "Rectangle" }, "circ": { zh: "圓形", ozh: "圓形", en: "Circle" }, "line": { zh: "直線", ozh: "直線", en: "Line" }, "qrc": { zh: "二維碼", ozh: "二維碼", en: "QR code" }, "barc": { zh: "條形碼", ozh: "條形碼", en: "Barcode" }, "counter": { zh: "計數器", ozh: "计数器", en: "Counter" }, "about": { zh: "关于Soon Design", ozh: "關於Soon Design", en: "About Soon Design" }, "vers": { zh: "版本", ozh: "版本", en: "Version" }, "comf": { zh: "确认", ozh: "確認", en: "Select" }, "copyright": { zh: "© 2022 cardsoon Co., Ltd. All rights reserved.", ozh: "© 2022 cardsoon Co., Ltd. All rights reserved.", en: "© 2022 cardsoon Co., Ltd. All rights reserved." } }; // 从全局作用域获取 s_lan(支持 .jsc 文件加载) const currentLang = (typeof global !== 'undefined' && global.s_lan) ? global.s_lan : (typeof window !== 'undefined' && window.s_lan) ? window.s_lan : s_lan; return t[str] ? (t[str][currentLang] || t[str]['zh'] || str) : str; }; // 确保 language_str 在 global 作用域中也可用(用于 .jsc 文件加载) if (typeof global !== 'undefined') { global.language_str = window.language_str; } // 向后兼容 function language_str(str) { return window.language_str(str); } // 获取URL参数 window.GetFile = function GetFile() { const params = new URLSearchParams(window.location.search); return params; }; // 向后兼容 function GetFile() { return window.GetFile(); } // 日期格式化 window.getDate = function getDate() { let date = new Date(); return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(); }; // 向后兼容 function getDate() { return window.getDate(); } // 获取对象的绝对坐标 window.getAbsoluteXY = function getAbsoluteXY(_obj) { let coord = _obj.get("lineCoords"); return [_obj.get("left"), _obj.get("top")]; }; // 向后兼容 function getAbsoluteXY(_obj) { return window.getAbsoluteXY(_obj); } // 计算两点之间的距离 window.getDisdance = function getDisdance(x1, y1, x2, y2) { var dx = Math.abs(x2 - x1); var dy = Math.abs(y2 - y1); var distance = Math.sqrt(dx * dx + dy * dy); return distance; }; // 向后兼容 function getDisdance(x1, y1, x2, y2) { return window.getDisdance(x1, y1, x2, y2); } // 计算角度(相对于画布中心) window.getDeg = function getDeg(pointer, canvas) { var centerX = canvas.width / 2; var centerY = canvas.height / 2; var mouseX = pointer.x; var mouseY = pointer.y; var dx = mouseX - centerX; var dy = mouseY - centerY; var angleRad = Math.atan2(dy, dx); var angleDeg = angleRad * (180 / Math.PI); if (angleDeg < 0) { angleDeg += 360; } angleDeg += 90; return angleDeg; }; // 向后兼容 function getDeg(pointer, canvas) { return window.getDeg(pointer, canvas); } // 检查字段名是否重复 window.checkName = function checkName(name, objs1, objs2) { for (let item of objs1) { if (item.name == name) { return false; } } for (let item of objs2) { if (item.name == name) { return false; } } return true; }; // 向后兼容 function checkName(name, objs1, objs2) { return window.checkName(name, objs1, objs2); } // 返回不重复的字段名 window.resName = function resName(pre_name, objs1, objs2) { let num = (objs1.length + objs2.length) - 1; do { num++; } while (!window.checkName(pre_name + num, objs1, objs2)); return pre_name + num; }; // 向后兼容 function resName(pre_name, objs1, objs2) { return window.resName(pre_name, objs1, objs2); } // 获取对象在画布中的索引 window.getIndex = function getIndex(target, canvas, _canvas = null) { let temp_objs; let useCanvas = (_canvas == null) ? canvas : _canvas; if (_canvas == null) { temp_objs = canvas.getObjects(); } else { temp_objs = _canvas.getObjects(); } let i = 0; for (let res of temp_objs) { if (target == res) { return i; } i++; } return 0; }; // 向后兼容 function getIndex(target, canvas, _canvas = null) { return window.getIndex(target, canvas, _canvas); } // 获取对象类型 window.getType = function getType(target, canvas, objs) { let temp_objs = canvas.getObjects(); let i = 0; for (let res of temp_objs) { if (target == res) { return objs[i].type; } i++; } }; // 向后兼容 function getType(target, canvas, objs) { return window.getType(target, canvas, objs); } // 获取坐标的最小X值 window.getCoordsMinX = function getCoordsMinX(acoords) { let x = acoords[0].x; for (let item of acoords) { if (item.x < x) { x = item.x; } } return x; }; // 向后兼容 function getCoordsMinX(acoords) { return window.getCoordsMinX(acoords); } // 获取坐标的最大X值 window.getCoordsMaxX = function getCoordsMaxX(acoords) { let x = acoords[0].x; for (let item of acoords) { if (item.x > x) { x = item.x; } } return x; }; // 向后兼容 function getCoordsMaxX(acoords) { return window.getCoordsMaxX(acoords); } // 获取坐标的最小Y值 window.getCoordsMinY = function getCoordsMinY(acoords) { let y = acoords[0].y; for (let item of acoords) { if (item.y < y) { y = item.y; } } return y; }; // 向后兼容 function getCoordsMinY(acoords) { return window.getCoordsMinY(acoords); } // 获取坐标的最大Y值 window.getCoordsMaxY = function getCoordsMaxY(acoords) { let y = acoords[0].y; for (let item of acoords) { if (item.y > y) { y = item.y; } } return y; }; // 向后兼容 function getCoordsMaxY(acoords) { return window.getCoordsMaxY(acoords); } // ========================================== // 全局变量定义(所有模块共享) // 注意:所有变量都附加到 window 对象,确保在 eval() 加载 .jsc 文件时也能访问 // ========================================== window.addState = 0; // 0是不添加 window.background_image = undefined; window.background_image1 = undefined; window.background_image2 = undefined; window.bg_version = 1; // front_bg1.png front_bg2.png window.zoom = 1; window.pre_add_image = undefined; // 预添加的图片对象(用于addPic) // 内部剪贴板 window.clipboardData = { data: null, offset: 10 // 粘贴位置偏移量 }; // 文件管理 window.openAs = { _name: "", set name(val) { if (val == "") { $("title").html('Soon Design'); } else { $("title").html('Soon Design - ' + val); } this._name = val; }, get name() { return this._name }, }; // 对象数组和历史记录 window.objs1 = []; window.objs2 = []; window.step1 = { val: 0 }; window.step2 = { val: 0 }; window.step = window.step1; window.objs = window.objs1; window.recordJson1 = []; window.recordJson2 = []; window.recordJson = window.recordJson1; window.recordObjs1 = []; window.recordObjs2 = []; window.recordObjs = window.recordObjs1; window.pre_objs1 = []; window.pre_objs2 = []; window.next_objs1 = []; window.next_objs2 = []; window.pre_objs = window.pre_objs1; window.next_objs = window.next_objs1; window.pre_json1 = []; window.pre_json2 = []; window.next_json1 = []; window.next_json2 = []; window.pre_json = window.pre_json1; window.next_json = window.next_json1; // Canvas对象(将在core.js中初始化) window.canvas1 = undefined; window.canvas2 = undefined; window.canvas = undefined; // 当前活动的画布(canvas1 或 canvas2) window.ctx1 = undefined; window.ctx2 = undefined; window.is_bgi_add = false; // 为了兼容性,同时创建局部变量引用(向后兼容) let addState = window.addState; let background_image = window.background_image; let background_image1 = window.background_image1; let background_image2 = window.background_image2; let bg_version = window.bg_version; var zoom = window.zoom; let pre_add_image = window.pre_add_image; let clipboardData = window.clipboardData; var openAs = window.openAs; let objs1 = window.objs1; let objs2 = window.objs2; let step1 = window.step1; let step2 = window.step2; let step = window.step; let objs = window.objs; let recordJson1 = window.recordJson1; let recordJson2 = window.recordJson2; let recordJson = window.recordJson; let recordObjs1 = window.recordObjs1; let recordObjs2 = window.recordObjs2; let recordObjs = window.recordObjs; let pre_objs1 = window.pre_objs1; let pre_objs2 = window.pre_objs2; let next_objs1 = window.next_objs1; let next_objs2 = window.next_objs2; let pre_objs = window.pre_objs; let next_objs = window.next_objs; let pre_json1 = window.pre_json1; let pre_json2 = window.pre_json2; let next_json1 = window.next_json1; let next_json2 = window.next_json2; let pre_json = window.pre_json; let next_json = window.next_json; var canvas1 = window.canvas1; var canvas2 = window.canvas2; var canvas = window.canvas; var ctx1 = window.ctx1; var ctx2 = window.ctx2; let is_bgi_add = window.is_bgi_add; // 加载 design1 模块:网页端在回调内动态加载(保证 $ 已存在),桌面端用 require+eval var fs = typeof window !== 'undefined' ? window.fs : null; var appPath = (remote && remote.app && remote.app.getAppPath) ? remote.app.getAppPath() : (typeof __dirname !== 'undefined' ? __dirname : '.'); if (typeof require === 'undefined') { // 网页端:按顺序动态插入 script,确保 core/ui 执行时 window.$ 已存在 function loadScript(src, next) { var s = document.createElement('script'); s.src = (typeof window.soonWithVersion === 'function') ? window.soonWithVersion(src) : src; s.onload = s.onerror = function () { if (typeof next === 'function') next(); }; document.body.appendChild(s); } loadScript('../js/design1/output.js', function () { loadScript('../js/design1/core.js', function () { loadScript('../js/design1/ui.js', function () {}); }); }); return; } const loadModule = (moduleName) => { if (!path || !fs) return; const jsPath = path.join(appPath, 'js', 'design1', moduleName + '.js'); if (fs.existsSync(jsPath)) { try { eval(fs.readFileSync(jsPath, 'utf8')); } catch (e) { alert('加载 ' + moduleName + ' 失败!\n\n错误: ' + e.message); } } else { alert('文件不存在!\n\n请检查:' + jsPath); } }; loadModule('output'); loadModule('core'); loadModule('ui'); });