321 lines
12 KiB
JavaScript
321 lines
12 KiB
JavaScript
// design1.js - 主入口文件
|
||
// 导入公共模块(不依赖jQuery的部分)
|
||
require('./common/fabric-ext.js');
|
||
|
||
// 过滤 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);
|
||
};
|
||
}
|
||
|
||
// Electron相关导入
|
||
const remote = require('@electron/remote');
|
||
var path = require('path');
|
||
const exePath = remote.app.getPath('userData');
|
||
const { ipcRenderer } = require('electron');
|
||
const { dialog } = require('@electron/remote');
|
||
var jrQrcode = require('jr-qrcode');
|
||
var JsBarcode = require('jsbarcode');
|
||
const { clipboard } = require('electron');
|
||
const dpi = 600;
|
||
|
||
// 发送IPC消息
|
||
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 = "";
|
||
ipcRenderer.send('get-sys-language');
|
||
|
||
var $ = layui.$;
|
||
var layer = layui.layer;
|
||
var slider = layui.slider;
|
||
var colorpicker = layui.colorpicker;
|
||
|
||
// 历史记录文件路径(供 output.js 使用)
|
||
var fullPath = path.join(exePath, 'data.json');
|
||
|
||
// ==========================================
|
||
// 公共函数定义(需要在layui.use回调内部,因为依赖jQuery)
|
||
// ==========================================
|
||
|
||
// DES加密函数
|
||
function desEncrypt(str, key = "df6a551ca43181fc485f3043bcdd2fbc") {
|
||
var keyHex = CryptoJS.enc.Utf8.parse(key);
|
||
var encrypted = CryptoJS.DES.encrypt(str, keyHex, {
|
||
mode: CryptoJS.mode.ECB,
|
||
padding: CryptoJS.pad.Pkcs7
|
||
});
|
||
return encrypted.toString();
|
||
}
|
||
|
||
// 多语言切换
|
||
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 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." }
|
||
};
|
||
return t[str] ? t[str][s_lan] : str;
|
||
}
|
||
|
||
// 获取URL参数
|
||
function GetFile() {
|
||
const params = new URLSearchParams(window.location.search);
|
||
return params;
|
||
}
|
||
|
||
// 日期格式化
|
||
function getDate() {
|
||
let date = new Date();
|
||
return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
|
||
}
|
||
|
||
// 获取对象的绝对坐标
|
||
function getAbsoluteXY(_obj) {
|
||
let coord = _obj.get("lineCoords");
|
||
return [_obj.get("left"), _obj.get("top")];
|
||
}
|
||
|
||
// 计算两点之间的距离
|
||
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 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 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 resName(pre_name, objs1, objs2) {
|
||
let num = (objs1.length + objs2.length) - 1;
|
||
do {
|
||
num++;
|
||
}
|
||
while (!checkName(pre_name + num, objs1, objs2));
|
||
return pre_name + num;
|
||
}
|
||
|
||
// 获取对象在画布中的索引
|
||
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 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++;
|
||
}
|
||
}
|
||
|
||
// 获取坐标的最小X值
|
||
function getCoordsMinX(acoords) {
|
||
let x = acoords[0].x;
|
||
for (let item of acoords) {
|
||
if (item.x < x) {
|
||
x = item.x;
|
||
}
|
||
}
|
||
return x;
|
||
}
|
||
|
||
// 获取坐标的最大X值
|
||
function getCoordsMaxX(acoords) {
|
||
let x = acoords[0].x;
|
||
for (let item of acoords) {
|
||
if (item.x > x) {
|
||
x = item.x;
|
||
}
|
||
}
|
||
return x;
|
||
}
|
||
|
||
// 获取坐标的最小Y值
|
||
function getCoordsMinY(acoords) {
|
||
let y = acoords[0].y;
|
||
for (let item of acoords) {
|
||
if (item.y < y) {
|
||
y = item.y;
|
||
}
|
||
}
|
||
return y;
|
||
}
|
||
|
||
// 获取坐标的最大Y值
|
||
function getCoordsMaxY(acoords) {
|
||
let y = acoords[0].y;
|
||
for (let item of acoords) {
|
||
if (item.y > y) {
|
||
y = item.y;
|
||
}
|
||
}
|
||
return y;
|
||
}
|
||
|
||
// ==========================================
|
||
// 全局变量定义(所有模块共享)
|
||
// ==========================================
|
||
let addState = 0; // 0是不添加
|
||
let background_image, background_image1, background_image2;
|
||
let bg_version = 1; // front_bg1.png front_bg2.png
|
||
var zoom = 1;
|
||
let pre_add_image; // 预添加的图片对象(用于addPic)
|
||
|
||
// 内部剪贴板
|
||
let clipboardData = {
|
||
data: null,
|
||
offset: 10 // 粘贴位置偏移量
|
||
};
|
||
|
||
// 文件管理
|
||
var 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
|
||
},
|
||
};
|
||
|
||
// 对象数组和历史记录
|
||
let objs1 = [];
|
||
let objs2 = [];
|
||
let step1 = { val: 0 }, step2 = { val: 0 };
|
||
let step = step1;
|
||
let objs = objs1;
|
||
let recordJson1 = [], recordJson2 = [], recordJson = recordJson1, recordObjs1 = [], recordObjs2 = [], recordObjs = recordObjs1;
|
||
let pre_objs1 = [], pre_objs2 = [], next_objs1 = [], next_objs2 = [], pre_objs = pre_objs1, next_objs = next_objs1;
|
||
let pre_json1 = [], pre_json2 = [], next_json1 = [], next_json2 = [], pre_json = pre_json1, next_json = next_json1;
|
||
|
||
// Canvas对象(将在core.js中初始化)
|
||
var canvas1, canvas2;
|
||
var canvas; // 当前活动的画布(canvas1 或 canvas2)
|
||
var ctx1, ctx2;
|
||
let is_bgi_add = false;
|
||
|
||
// 加载design1模块
|
||
// 由于模块代码需要在layui.use内部执行,我们通过动态加载的方式
|
||
const fs = require('fs');
|
||
|
||
// 加载core.js(核心功能)
|
||
try {
|
||
const coreCode = fs.readFileSync(__dirname + '/design1/core.js', 'utf8');
|
||
eval(coreCode);
|
||
} catch (e) {
|
||
console.error('加载core.js失败:', e);
|
||
}
|
||
|
||
// 加载output.js(输出功能,需要在ui.js之前加载,因为ui.js中的saveAs会调用output.js中的函数)
|
||
try {
|
||
const outputCode = fs.readFileSync(__dirname + '/design1/output.js', 'utf8');
|
||
eval(outputCode);
|
||
} catch (e) {
|
||
console.error('加载output.js失败:', e);
|
||
}
|
||
|
||
// 加载ui.js(UI控制)
|
||
try {
|
||
const uiCode = fs.readFileSync(__dirname + '/design1/ui.js', 'utf8');
|
||
eval(uiCode);
|
||
} catch (e) {
|
||
console.error('加载ui.js失败:', e);
|
||
}
|
||
});
|