调整优化
This commit is contained in:
+146
-153
@@ -17,23 +17,23 @@ if (typeof console !== 'undefined' && console.warn) {
|
|||||||
|
|
||||||
// Electron相关导入
|
// Electron相关导入
|
||||||
const remote = require('@electron/remote');
|
const remote = require('@electron/remote');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
const exePath = remote.app.getPath('userData');
|
const exePath = remote.app.getPath('userData');
|
||||||
const { ipcRenderer } = require('electron');
|
const { ipcRenderer } = require('electron');
|
||||||
const { dialog } = require('@electron/remote');
|
const { dialog } = require('@electron/remote');
|
||||||
var jrQrcode = require('jr-qrcode');
|
var jrQrcode = require('jr-qrcode');
|
||||||
var JsBarcode = require('jsbarcode');
|
var JsBarcode = require('jsbarcode');
|
||||||
const { clipboard } = require('electron');
|
const { clipboard } = require('electron');
|
||||||
const dpi = 600;
|
const dpi = 600;
|
||||||
|
|
||||||
// 发送IPC消息
|
// 发送IPC消息
|
||||||
ipcRenderer.send('get-sys-fonts');
|
ipcRenderer.send('get-sys-fonts');
|
||||||
ipcRenderer.send('get-scale-rate');
|
ipcRenderer.send('get-scale-rate');
|
||||||
|
|
||||||
// 使用layui
|
// 使用layui
|
||||||
layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
||||||
let myDate = new Date();
|
let myDate = new Date();
|
||||||
let s_lan = "";
|
let s_lan = "";
|
||||||
// 确保 s_lan 在全局作用域中可用(用于 .jsc 文件加载)
|
// 确保 s_lan 在全局作用域中可用(用于 .jsc 文件加载)
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
window.s_lan = s_lan;
|
window.s_lan = s_lan;
|
||||||
@@ -41,8 +41,8 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
if (typeof global !== 'undefined') {
|
if (typeof global !== 'undefined') {
|
||||||
global.s_lan = s_lan;
|
global.s_lan = s_lan;
|
||||||
}
|
}
|
||||||
ipcRenderer.send('get-sys-language');
|
ipcRenderer.send('get-sys-language');
|
||||||
|
|
||||||
var $ = layui.$;
|
var $ = layui.$;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var slider = layui.slider;
|
var slider = layui.slider;
|
||||||
@@ -88,7 +88,7 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var slider = layui.slider;
|
var slider = layui.slider;
|
||||||
var colorpicker = layui.colorpicker;
|
var colorpicker = layui.colorpicker;
|
||||||
|
|
||||||
// 历史记录文件路径(供 output.js 使用)
|
// 历史记录文件路径(供 output.js 使用)
|
||||||
var fullPath = path.join(exePath, 'data.json');
|
var fullPath = path.join(exePath, 'data.json');
|
||||||
// 确保 fullPath 在全局作用域中可用(用于 .jsc 文件加载)
|
// 确保 fullPath 在全局作用域中可用(用于 .jsc 文件加载)
|
||||||
@@ -100,26 +100,25 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
global.fullPath = fullPath;
|
global.fullPath = fullPath;
|
||||||
global.exePath = exePath;
|
global.exePath = exePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 公共函数定义(需要在layui.use回调内部,因为依赖jQuery)
|
// 公共函数定义(需要在layui.use回调内部,因为依赖jQuery)
|
||||||
// 注意:所有函数都附加到 window 对象,确保在 eval() 加载 .jsc 文件时也能访问
|
// 注意:所有函数都附加到 window 对象,确保在 eval() 加载 .jsc 文件时也能访问
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|
||||||
// DES加密函数
|
// DES加密函数
|
||||||
window.desEncrypt = function desEncrypt(str, key = "df6a551ca43181fc485f3043bcdd2fbc") {
|
window.desEncrypt = function desEncrypt(str, key = "df6a551ca43181fc485f3043bcdd2fbc") {
|
||||||
var APIFMS;
|
var APIFMS;
|
||||||
try {
|
try {
|
||||||
// 确保输入字符串是 UTF-8 编码
|
// 确保输入字符串是 UTF-8 编码
|
||||||
var keyHex = CryptoJS.enc.Utf8.parse(key);
|
var keyHex = CryptoJS.enc.Utf8.parse(key);
|
||||||
var encrypted = CryptoJS.DES.encrypt(str, keyHex, {
|
var encrypted = CryptoJS.DES.encrypt(str, keyHex, {
|
||||||
mode: CryptoJS.mode.ECB,
|
mode: CryptoJS.mode.ECB,
|
||||||
padding: CryptoJS.pad.Pkcs7
|
padding: CryptoJS.pad.Pkcs7
|
||||||
});
|
});
|
||||||
// 使用 Base64 编码确保中文字符正确输出
|
// 使用 Base64 编码确保中文字符正确输出
|
||||||
APIFMS = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
|
APIFMS = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('des 加密错误:', err);
|
|
||||||
APIFMS = '';
|
APIFMS = '';
|
||||||
}
|
}
|
||||||
return APIFMS;
|
return APIFMS;
|
||||||
@@ -128,49 +127,49 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
function desEncrypt(str, key = "df6a551ca43181fc485f3043bcdd2fbc") {
|
function desEncrypt(str, key = "df6a551ca43181fc485f3043bcdd2fbc") {
|
||||||
return window.desEncrypt(str, key);
|
return window.desEncrypt(str, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 多语言切换
|
// 多语言切换
|
||||||
window.langua_ge = function langua_ge(lan = 'zh') {
|
window.langua_ge = function langua_ge(lan = 'zh') {
|
||||||
$("[language='m']").each(function (i) {
|
$("[language='m']").each(function (i) {
|
||||||
$(this).html($(this).attr(lan));
|
$(this).html($(this).attr(lan));
|
||||||
});
|
});
|
||||||
$("[language='t']").each(function (i) {
|
$("[language='t']").each(function (i) {
|
||||||
$(this).attr("title", $(this).attr(lan));
|
$(this).attr("title", $(this).attr(lan));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function langua_ge(lan = 'zh') {
|
function langua_ge(lan = 'zh') {
|
||||||
return window.langua_ge(lan);
|
return window.langua_ge(lan);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 多语言字符串获取
|
// 多语言字符串获取
|
||||||
window.language_str = function language_str(str) {
|
window.language_str = function language_str(str) {
|
||||||
let t = {
|
let t = {
|
||||||
"whetherSave": { zh: "是否保存当前文件?", ozh: "是否保存當前文件?", en: "Do you want to save the current file?" },
|
"whetherSave": { zh: "是否保存当前文件?", ozh: "是否保存當前文件?", en: "Do you want to save the current file?" },
|
||||||
"save": { zh: "保存", ozh: "保存", en: "Save" },
|
"save": { zh: "保存", ozh: "保存", en: "Save" },
|
||||||
"noSave": { zh: "不保存", ozh: "不保存", en: "No saving" },
|
"noSave": { zh: "不保存", ozh: "不保存", en: "No saving" },
|
||||||
"cancel": { zh: "取消", ozh: "取消", en: "Cancel" },
|
"cancel": { zh: "取消", ozh: "取消", en: "Cancel" },
|
||||||
"saveSucc": { zh: "保存成功至", ozh: "保存成功至", en: "Save successfully to" },
|
"saveSucc": { zh: "保存成功至", ozh: "保存成功至", en: "Save successfully to" },
|
||||||
"saveFile": { zh: "保存文件", ozh: "保存文件", en: "Save file" },
|
"saveFile": { zh: "保存文件", ozh: "保存文件", en: "Save file" },
|
||||||
"display": { zh: "预览", ozh: "預覽", en: "Display" },
|
"display": { zh: "预览", ozh: "預覽", en: "Display" },
|
||||||
"output": { zh: "导出", ozh: "導出", en: "Export" },
|
"output": { zh: "导出", ozh: "導出", en: "Export" },
|
||||||
"bg": { zh: "背景", ozh: "背景", en: "Background" },
|
"bg": { zh: "背景", ozh: "背景", en: "Background" },
|
||||||
"selectPic": { zh: "请选择图片", ozh: "請選擇圖片", en: "Please select a picture" },
|
"selectPic": { zh: "请选择图片", ozh: "請選擇圖片", en: "Please select a picture" },
|
||||||
"img": { zh: "圖片", ozh: "圖片", en: "Image" },
|
"img": { zh: "圖片", ozh: "圖片", en: "Image" },
|
||||||
"simg": { zh: "合成圖片", ozh: "合成圖片", en: "Synthesized Image" },
|
"simg": { zh: "合成圖片", ozh: "合成圖片", en: "Synthesized Image" },
|
||||||
"text": { zh: "文本", ozh: "文本", en: "Text" },
|
"text": { zh: "文本", ozh: "文本", en: "Text" },
|
||||||
"ctext": { zh: "圆形文本", ozh: "圆形文本", en: "Circle Text" },
|
"ctext": { zh: "圆形文本", ozh: "圆形文本", en: "Circle Text" },
|
||||||
"stext": { zh: "合成文本", ozh: "合成文本", en: "Synthesized Text" },
|
"stext": { zh: "合成文本", ozh: "合成文本", en: "Synthesized Text" },
|
||||||
"rect": { zh: "矩形", ozh: "矩形", en: "Rectangle" },
|
"rect": { zh: "矩形", ozh: "矩形", en: "Rectangle" },
|
||||||
"circ": { zh: "圓形", ozh: "圓形", en: "Circle" },
|
"circ": { zh: "圓形", ozh: "圓形", en: "Circle" },
|
||||||
"line": { zh: "直線", ozh: "直線", en: "Line" },
|
"line": { zh: "直線", ozh: "直線", en: "Line" },
|
||||||
"qrc": { zh: "二維碼", ozh: "二維碼", en: "QR code" },
|
"qrc": { zh: "二維碼", ozh: "二維碼", en: "QR code" },
|
||||||
"barc": { zh: "條形碼", ozh: "條形碼", en: "Barcode" },
|
"barc": { zh: "條形碼", ozh: "條形碼", en: "Barcode" },
|
||||||
"counter": { zh: "計數器", ozh: "计数器", en: "Counter" },
|
"counter": { zh: "計數器", ozh: "计数器", en: "Counter" },
|
||||||
"about": { zh: "关于Soon Design", ozh: "關於Soon Design", en: "About Soon Design" },
|
"about": { zh: "关于Soon Design", ozh: "關於Soon Design", en: "About Soon Design" },
|
||||||
"vers": { zh: "版本", ozh: "版本", en: "Version" },
|
"vers": { zh: "版本", ozh: "版本", en: "Version" },
|
||||||
"comf": { zh: "确认", ozh: "確認", en: "Select" },
|
"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." }
|
"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 文件加载)
|
// 从全局作用域获取 s_lan(支持 .jsc 文件加载)
|
||||||
const currentLang = (typeof global !== 'undefined' && global.s_lan) ? global.s_lan :
|
const currentLang = (typeof global !== 'undefined' && global.s_lan) ? global.s_lan :
|
||||||
@@ -185,7 +184,7 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
function language_str(str) {
|
function language_str(str) {
|
||||||
return window.language_str(str);
|
return window.language_str(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取URL参数
|
// 获取URL参数
|
||||||
window.GetFile = function GetFile() {
|
window.GetFile = function GetFile() {
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
@@ -195,27 +194,27 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
function GetFile() {
|
function GetFile() {
|
||||||
return window.GetFile();
|
return window.GetFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 日期格式化
|
// 日期格式化
|
||||||
window.getDate = function getDate() {
|
window.getDate = function getDate() {
|
||||||
let date = new Date();
|
let date = new Date();
|
||||||
return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
|
return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function getDate() {
|
function getDate() {
|
||||||
return window.getDate();
|
return window.getDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取对象的绝对坐标
|
// 获取对象的绝对坐标
|
||||||
window.getAbsoluteXY = function getAbsoluteXY(_obj) {
|
window.getAbsoluteXY = function getAbsoluteXY(_obj) {
|
||||||
let coord = _obj.get("lineCoords");
|
let coord = _obj.get("lineCoords");
|
||||||
return [_obj.get("left"), _obj.get("top")];
|
return [_obj.get("left"), _obj.get("top")];
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function getAbsoluteXY(_obj) {
|
function getAbsoluteXY(_obj) {
|
||||||
return window.getAbsoluteXY(_obj);
|
return window.getAbsoluteXY(_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算两点之间的距离
|
// 计算两点之间的距离
|
||||||
window.getDisdance = function getDisdance(x1, y1, x2, y2) {
|
window.getDisdance = function getDisdance(x1, y1, x2, y2) {
|
||||||
var dx = Math.abs(x2 - x1);
|
var dx = Math.abs(x2 - x1);
|
||||||
@@ -227,7 +226,7 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
function getDisdance(x1, y1, x2, y2) {
|
function getDisdance(x1, y1, x2, y2) {
|
||||||
return window.getDisdance(x1, y1, x2, y2);
|
return window.getDisdance(x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算角度(相对于画布中心)
|
// 计算角度(相对于画布中心)
|
||||||
window.getDeg = function getDeg(pointer, canvas) {
|
window.getDeg = function getDeg(pointer, canvas) {
|
||||||
var centerX = canvas.width / 2;
|
var centerX = canvas.width / 2;
|
||||||
@@ -248,138 +247,138 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
function getDeg(pointer, canvas) {
|
function getDeg(pointer, canvas) {
|
||||||
return window.getDeg(pointer, canvas);
|
return window.getDeg(pointer, canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查字段名是否重复
|
// 检查字段名是否重复
|
||||||
window.checkName = function checkName(name, objs1, objs2) {
|
window.checkName = function checkName(name, objs1, objs2) {
|
||||||
for (let item of objs1) {
|
for (let item of objs1) {
|
||||||
if (item.name == name) {
|
if (item.name == name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let item of objs2) {
|
for (let item of objs2) {
|
||||||
if (item.name == name) {
|
if (item.name == name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function checkName(name, objs1, objs2) {
|
function checkName(name, objs1, objs2) {
|
||||||
return window.checkName(name, objs1, objs2);
|
return window.checkName(name, objs1, objs2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回不重复的字段名
|
// 返回不重复的字段名
|
||||||
window.resName = function resName(pre_name, objs1, objs2) {
|
window.resName = function resName(pre_name, objs1, objs2) {
|
||||||
let num = (objs1.length + objs2.length) - 1;
|
let num = (objs1.length + objs2.length) - 1;
|
||||||
do {
|
do {
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
while (!window.checkName(pre_name + num, objs1, objs2));
|
while (!window.checkName(pre_name + num, objs1, objs2));
|
||||||
return pre_name + num;
|
return pre_name + num;
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function resName(pre_name, objs1, objs2) {
|
function resName(pre_name, objs1, objs2) {
|
||||||
return window.resName(pre_name, objs1, objs2);
|
return window.resName(pre_name, objs1, objs2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取对象在画布中的索引
|
// 获取对象在画布中的索引
|
||||||
window.getIndex = function getIndex(target, canvas, _canvas = null) {
|
window.getIndex = function getIndex(target, canvas, _canvas = null) {
|
||||||
let temp_objs;
|
let temp_objs;
|
||||||
let useCanvas = (_canvas == null) ? canvas : _canvas;
|
let useCanvas = (_canvas == null) ? canvas : _canvas;
|
||||||
if (_canvas == null) {
|
if (_canvas == null) {
|
||||||
temp_objs = canvas.getObjects();
|
temp_objs = canvas.getObjects();
|
||||||
} else {
|
} else {
|
||||||
temp_objs = _canvas.getObjects();
|
temp_objs = _canvas.getObjects();
|
||||||
}
|
}
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (let res of temp_objs) {
|
for (let res of temp_objs) {
|
||||||
if (target == res) {
|
if (target == res) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function getIndex(target, canvas, _canvas = null) {
|
function getIndex(target, canvas, _canvas = null) {
|
||||||
return window.getIndex(target, canvas, _canvas);
|
return window.getIndex(target, canvas, _canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取对象类型
|
// 获取对象类型
|
||||||
window.getType = function getType(target, canvas, objs) {
|
window.getType = function getType(target, canvas, objs) {
|
||||||
let temp_objs = canvas.getObjects();
|
let temp_objs = canvas.getObjects();
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (let res of temp_objs) {
|
for (let res of temp_objs) {
|
||||||
if (target == res) {
|
if (target == res) {
|
||||||
return objs[i].type;
|
return objs[i].type;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function getType(target, canvas, objs) {
|
function getType(target, canvas, objs) {
|
||||||
return window.getType(target, canvas, objs);
|
return window.getType(target, canvas, objs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取坐标的最小X值
|
// 获取坐标的最小X值
|
||||||
window.getCoordsMinX = function getCoordsMinX(acoords) {
|
window.getCoordsMinX = function getCoordsMinX(acoords) {
|
||||||
let x = acoords[0].x;
|
let x = acoords[0].x;
|
||||||
for (let item of acoords) {
|
for (let item of acoords) {
|
||||||
if (item.x < x) {
|
if (item.x < x) {
|
||||||
x = item.x;
|
x = item.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function getCoordsMinX(acoords) {
|
function getCoordsMinX(acoords) {
|
||||||
return window.getCoordsMinX(acoords);
|
return window.getCoordsMinX(acoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取坐标的最大X值
|
// 获取坐标的最大X值
|
||||||
window.getCoordsMaxX = function getCoordsMaxX(acoords) {
|
window.getCoordsMaxX = function getCoordsMaxX(acoords) {
|
||||||
let x = acoords[0].x;
|
let x = acoords[0].x;
|
||||||
for (let item of acoords) {
|
for (let item of acoords) {
|
||||||
if (item.x > x) {
|
if (item.x > x) {
|
||||||
x = item.x;
|
x = item.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function getCoordsMaxX(acoords) {
|
function getCoordsMaxX(acoords) {
|
||||||
return window.getCoordsMaxX(acoords);
|
return window.getCoordsMaxX(acoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取坐标的最小Y值
|
// 获取坐标的最小Y值
|
||||||
window.getCoordsMinY = function getCoordsMinY(acoords) {
|
window.getCoordsMinY = function getCoordsMinY(acoords) {
|
||||||
let y = acoords[0].y;
|
let y = acoords[0].y;
|
||||||
for (let item of acoords) {
|
for (let item of acoords) {
|
||||||
if (item.y < y) {
|
if (item.y < y) {
|
||||||
y = item.y;
|
y = item.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return y;
|
return y;
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function getCoordsMinY(acoords) {
|
function getCoordsMinY(acoords) {
|
||||||
return window.getCoordsMinY(acoords);
|
return window.getCoordsMinY(acoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取坐标的最大Y值
|
// 获取坐标的最大Y值
|
||||||
window.getCoordsMaxY = function getCoordsMaxY(acoords) {
|
window.getCoordsMaxY = function getCoordsMaxY(acoords) {
|
||||||
let y = acoords[0].y;
|
let y = acoords[0].y;
|
||||||
for (let item of acoords) {
|
for (let item of acoords) {
|
||||||
if (item.y > y) {
|
if (item.y > y) {
|
||||||
y = item.y;
|
y = item.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return y;
|
return y;
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
function getCoordsMaxY(acoords) {
|
function getCoordsMaxY(acoords) {
|
||||||
return window.getCoordsMaxY(acoords);
|
return window.getCoordsMaxY(acoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 全局变量定义(所有模块共享)
|
// 全局变量定义(所有模块共享)
|
||||||
@@ -392,20 +391,20 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
window.bg_version = 1; // front_bg1.png front_bg2.png
|
window.bg_version = 1; // front_bg1.png front_bg2.png
|
||||||
window.zoom = 1;
|
window.zoom = 1;
|
||||||
window.pre_add_image = undefined; // 预添加的图片对象(用于addPic)
|
window.pre_add_image = undefined; // 预添加的图片对象(用于addPic)
|
||||||
|
|
||||||
// 内部剪贴板
|
// 内部剪贴板
|
||||||
window.clipboardData = {
|
window.clipboardData = {
|
||||||
data: null,
|
data: null,
|
||||||
offset: 10 // 粘贴位置偏移量
|
offset: 10 // 粘贴位置偏移量
|
||||||
};
|
};
|
||||||
|
|
||||||
// 文件管理
|
// 文件管理
|
||||||
window.openAs = {
|
window.openAs = {
|
||||||
_name: "",
|
_name: "",
|
||||||
set name(val) {
|
set name(val) {
|
||||||
if (val == "") {
|
if (val == "") {
|
||||||
$("title").html('Soon Design');
|
$("title").html('Soon Design');
|
||||||
} else {
|
} else {
|
||||||
$("title").html('Soon Design - ' + val);
|
$("title").html('Soon Design - ' + val);
|
||||||
}
|
}
|
||||||
this._name = val;
|
this._name = val;
|
||||||
@@ -414,7 +413,7 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
return this._name
|
return this._name
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 对象数组和历史记录
|
// 对象数组和历史记录
|
||||||
window.objs1 = [];
|
window.objs1 = [];
|
||||||
window.objs2 = [];
|
window.objs2 = [];
|
||||||
@@ -440,7 +439,7 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
window.next_json2 = [];
|
window.next_json2 = [];
|
||||||
window.pre_json = window.pre_json1;
|
window.pre_json = window.pre_json1;
|
||||||
window.next_json = window.next_json1;
|
window.next_json = window.next_json1;
|
||||||
|
|
||||||
// Canvas对象(将在core.js中初始化)
|
// Canvas对象(将在core.js中初始化)
|
||||||
window.canvas1 = undefined;
|
window.canvas1 = undefined;
|
||||||
window.canvas2 = undefined;
|
window.canvas2 = undefined;
|
||||||
@@ -489,17 +488,16 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
var ctx1 = window.ctx1;
|
var ctx1 = window.ctx1;
|
||||||
var ctx2 = window.ctx2;
|
var ctx2 = window.ctx2;
|
||||||
let is_bgi_add = window.is_bgi_add;
|
let is_bgi_add = window.is_bgi_add;
|
||||||
|
|
||||||
// 加载design1模块
|
// 加载design1模块
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
let bytenode;
|
let bytenode;
|
||||||
try {
|
try {
|
||||||
bytenode = require('bytenode');
|
bytenode = require('bytenode');
|
||||||
require.extensions['.dl'] = require.extensions['.jsc'];
|
require.extensions['.dl'] = require.extensions['.jsc'];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[加载模块] bytenode 未安装,无法加载 .jsc 文件');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const appPath = (() => { try { return remote.app.getAppPath(); } catch (e) { return __dirname || process.cwd(); } })();
|
const appPath = (() => { try { return remote.app.getAppPath(); } catch (e) { return __dirname || process.cwd(); } })();
|
||||||
|
|
||||||
// 读取模块映射配置(从 lib 目录读取,跨平台兼容)
|
// 读取模块映射配置(从 lib 目录读取,跨平台兼容)
|
||||||
@@ -510,7 +508,6 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
|
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[加载模块] 无法读取模块映射配置,使用默认文件名');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取映射后的文件名(跨平台兼容)
|
// 获取映射后的文件名(跨平台兼容)
|
||||||
@@ -530,10 +527,8 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
if (fs.existsSync(jscPath) && bytenode) {
|
if (fs.existsSync(jscPath) && bytenode) {
|
||||||
try {
|
try {
|
||||||
require(jscPath);
|
require(jscPath);
|
||||||
console.log(`[加载模块] ✅ ${moduleName} → ${mappedName}.jsc`);
|
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`[加载模块] ❌ ${moduleName}.jsc 加载失败:`, e.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,14 +536,12 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
|
|||||||
if (fs.existsSync(jsPath)) {
|
if (fs.existsSync(jsPath)) {
|
||||||
try {
|
try {
|
||||||
eval(fs.readFileSync(jsPath, 'utf8'));
|
eval(fs.readFileSync(jsPath, 'utf8'));
|
||||||
console.log(`[加载模块] ✅ ${moduleName} → ${moduleName}.js`);
|
} catch (e) {
|
||||||
} catch (e) {
|
|
||||||
console.error(`[加载模块] ❌ ${moduleName}.js 加载失败:`, e.message);
|
|
||||||
alert(`加载 ${moduleName} 失败!\n\n错误: ${e.message}`);
|
alert(`加载 ${moduleName} 失败!\n\n错误: ${e.message}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert(`文件不存在!\n\n请检查:\n1. ${jscPath}\n2. ${jsPath}`);
|
alert(`文件不存在!\n\n请检查:\n1. ${jscPath}\n2. ${jsPath}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
loadModule('output'); // 先加载 output,因为 core 中的 addBackground() 需要调用 output 中的 open()
|
loadModule('output'); // 先加载 output,因为 core 中的 addBackground() 需要调用 output 中的 open()
|
||||||
loadModule('core');
|
loadModule('core');
|
||||||
|
|||||||
+126
-36
@@ -280,7 +280,6 @@ var zoomSlider = slider.render({
|
|||||||
max: 500,
|
max: 500,
|
||||||
value: 100,
|
value: 100,
|
||||||
change(val) {
|
change(val) {
|
||||||
console.log(val, zoomSlider)
|
|
||||||
canvas.zoomToPoint(
|
canvas.zoomToPoint(
|
||||||
new fabric.Point(0, 0),
|
new fabric.Point(0, 0),
|
||||||
val / 100
|
val / 100
|
||||||
@@ -379,7 +378,7 @@ function addBackground() {
|
|||||||
//pre_json1.push(canvas1.toJSON(["selectable","hoverable","hoverCursor"]));
|
//pre_json1.push(canvas1.toJSON(["selectable","hoverable","hoverCursor"]));
|
||||||
|
|
||||||
recordObjs1.push(JSON.stringify(objs1));
|
recordObjs1.push(JSON.stringify(objs1));
|
||||||
recordJson1.push(canvas1.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]));
|
recordJson1.push(canvas1.toJSON(TO_JSON_PROPERTIES));
|
||||||
});
|
});
|
||||||
// 类型改变
|
// 类型改变
|
||||||
fabric.Image.fromURL('./public/images/bg_back.png', function (image) {
|
fabric.Image.fromURL('./public/images/bg_back.png', function (image) {
|
||||||
@@ -399,7 +398,7 @@ function addBackground() {
|
|||||||
//pre_json2.push(canvas2.toJSON(["selectable","hoverable","hoverCursor"]));
|
//pre_json2.push(canvas2.toJSON(["selectable","hoverable","hoverCursor"]));
|
||||||
|
|
||||||
recordObjs2.push(JSON.stringify(objs2));
|
recordObjs2.push(JSON.stringify(objs2));
|
||||||
recordJson2.push(canvas2.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]));
|
recordJson2.push(canvas2.toJSON(TO_JSON_PROPERTIES));
|
||||||
|
|
||||||
let file = GetFile().get('file')
|
let file = GetFile().get('file')
|
||||||
if (file && file != 'empty') {
|
if (file && file != 'empty') {
|
||||||
@@ -663,18 +662,25 @@ function addCircleText(pointer) {
|
|||||||
window.recordState();
|
window.recordState();
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCircleText(target, index) {
|
function selectCircleText() {
|
||||||
|
// 检查是否有选中对象
|
||||||
|
if (!canvas || !canvas.getActiveObject()) return;
|
||||||
|
|
||||||
let idx = getIndex(canvas.getActiveObject());
|
let idx = getIndex(canvas.getActiveObject());
|
||||||
$("#circle_text_control").show();
|
$("#circle_text_control").show();
|
||||||
$("#circle_text_color").val(canvas.getActiveObject().get("fill"));
|
$("#circle_text_color").val(canvas.getActiveObject().get("fill"));
|
||||||
$("#circle_text_back_color").val(canvas.getActiveObject().get("textBackgroundColor") == "" ? '#ffffff' : canvas.getActiveObject().get("textBackgroundColor"));
|
$("#circle_text_back_color").val(canvas.getActiveObject().get("textBackgroundColor") == "" ? '#ffffff' : canvas.getActiveObject().get("textBackgroundColor"));
|
||||||
if (typeof circle_text_size !== 'undefined' && circle_text_size.setValue) {
|
|
||||||
|
// 检查 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);
|
circle_text_size.setValue(canvas.getActiveObject().get("fontSize") - 10);
|
||||||
} else {
|
} 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-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_size").next().children(".layui-slider-handle").css("left", ((canvas.getActiveObject().get("fontSize") - 10 - 10) / (120 - 10)) * 100 + "%");
|
||||||
}
|
}
|
||||||
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter.setValue) {
|
|
||||||
|
// 检查 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);
|
circle_text_diameter.setValue(canvas.getActiveObject().get("diameter") - 500);
|
||||||
} else {
|
} 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-bar").css("width", ((canvas.getActiveObject().get("diameter") - 500 - 500) / (4000 - 500)) * 100 + "%");
|
||||||
@@ -851,7 +857,6 @@ function selectRect(target, index) {
|
|||||||
$("#rect_op").next().children(".layui-slider-handle").css("left", (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();
|
let a = canvas.getActiveObject().getCoords();
|
||||||
console.log(getCoordsMinX(a));
|
|
||||||
$("#pic_control").hide();
|
$("#pic_control").hide();
|
||||||
$("#set_bg").hide();
|
$("#set_bg").hide();
|
||||||
$("#out_pic_control").hide();
|
$("#out_pic_control").hide();
|
||||||
@@ -1045,7 +1050,6 @@ function addCounter(pointer) {
|
|||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
updateList();
|
updateList();
|
||||||
window.recordState();
|
window.recordState();
|
||||||
console.log(canvas.getObjects())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCounter(target, index) {
|
function selectCounter(target, index) {
|
||||||
@@ -1126,7 +1130,7 @@ window.updateList = function updateList() {
|
|||||||
const lockIcon = isLocked ?
|
const lockIcon = isLocked ?
|
||||||
'<img src="public/images/lock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.7;" title="已锁定">' :
|
'<img src="public/images/lock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.7;" title="已锁定">' :
|
||||||
'<img src="public/images/unlock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.5;" title="未锁定">';
|
'<img src="public/images/unlock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.5;" title="未锁定">';
|
||||||
|
|
||||||
// 组装 HTML
|
// 组装 HTML
|
||||||
str = `<div style="${rowStyle}">
|
str = `<div style="${rowStyle}">
|
||||||
<div style="${leftStyle}">
|
<div style="${leftStyle}">
|
||||||
@@ -1151,6 +1155,9 @@ window.updateList = function updateList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 将 selectObj 附加到 window 对象,确保全局可访问
|
// 将 selectObj 附加到 window 对象,确保全局可访问
|
||||||
|
// 标记是否通过对象列表选中(用于区分鼠标点击和列表点击)
|
||||||
|
window._selectingFromList = false;
|
||||||
|
|
||||||
window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
|
window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
|
||||||
let indicesArray = (Array.isArray(objIndices)) ? objIndices : ((typeof objIndices === 'number' && objIndices >= 0) ? [objIndices] : []);
|
let indicesArray = (Array.isArray(objIndices)) ? objIndices : ((typeof objIndices === 'number' && objIndices >= 0) ? [objIndices] : []);
|
||||||
|
|
||||||
@@ -1166,16 +1173,6 @@ window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
|
|||||||
|
|
||||||
if (indicesArray.includes(idIndex)) {
|
if (indicesArray.includes(idIndex)) {
|
||||||
$(this).css("background-color", "#6F7A84");
|
$(this).css("background-color", "#6F7A84");
|
||||||
// 如果对象被锁定,临时允许选中以便解锁
|
|
||||||
if (idIndex >= 0 && canvas.getObjects()[idIndex + 1]) {
|
|
||||||
let obj = canvas.getObjects()[idIndex + 1];
|
|
||||||
if (obj && obj.get('lockMovementX') === true) {
|
|
||||||
obj.set({
|
|
||||||
selectable: true,
|
|
||||||
evented: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自动滚动到可视区域
|
// 自动滚动到可视区域
|
||||||
if (isFromCanvas && indicesArray[0] === idIndex) {
|
if (isFromCanvas && indicesArray[0] === idIndex) {
|
||||||
@@ -1188,15 +1185,39 @@ window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
|
|||||||
if (!isFromCanvas && indicesArray.length === 1) {
|
if (!isFromCanvas && indicesArray.length === 1) {
|
||||||
let target = canvas.getObjects()[indicesArray[0] + 1];
|
let target = canvas.getObjects()[indicesArray[0] + 1];
|
||||||
if (target) {
|
if (target) {
|
||||||
// 如果对象被锁定,临时允许选中以便解锁
|
// 检查对象是否被锁定
|
||||||
if (target.get('lockMovementX') === true) {
|
let isLocked = isObjectLocked(target);
|
||||||
|
|
||||||
|
// 设置标志位,表示这是通过对象列表选中的(无论是否锁定)
|
||||||
|
window._selectingFromList = true;
|
||||||
|
|
||||||
|
// 如果被锁定,临时设置 selectable 和 evented 为 true,以便能够选中
|
||||||
|
if (isLocked) {
|
||||||
target.set({
|
target.set({
|
||||||
selectable: true,
|
selectable: true,
|
||||||
evented: true
|
evented: true
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.setActiveObject(target);
|
canvas.setActiveObject(target);
|
||||||
canvas.requestRenderAll();
|
canvas.requestRenderAll();
|
||||||
|
|
||||||
|
// 如果对象被锁定,选中后立即恢复锁定状态(但保持选中状态)
|
||||||
|
if (isLocked) {
|
||||||
|
setTimeout(() => {
|
||||||
|
target.set({
|
||||||
|
selectable: false,
|
||||||
|
evented: false
|
||||||
|
});
|
||||||
|
canvas.requestRenderAll();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除标志位(延迟清除,确保事件处理完成)
|
||||||
|
setTimeout(() => {
|
||||||
|
window._selectingFromList = false;
|
||||||
|
}, 10);
|
||||||
|
|
||||||
handleObjectSelected();
|
handleObjectSelected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1217,7 +1238,7 @@ window.recordState = function recordState() {
|
|||||||
//recordObjs.splice(step.val, 1, JSON.stringify(objs))
|
//recordObjs.splice(step.val, 1, JSON.stringify(objs))
|
||||||
//recordJson.splice(step.val, 1, canvas.toJSON(["selectable","hoverable","hoverCursor","text","fontStyle","fontWeight","underline"]))
|
//recordJson.splice(step.val, 1, canvas.toJSON(["selectable","hoverable","hoverCursor","text","fontStyle","fontWeight","underline"]))
|
||||||
recordObjs.push(JSON.stringify(objs))
|
recordObjs.push(JSON.stringify(objs))
|
||||||
j = canvas.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
j = canvas.toJSON(TO_JSON_PROPERTIES);
|
||||||
j.objects[0].hoverCursor = "default";
|
j.objects[0].hoverCursor = "default";
|
||||||
recordJson.push(j);
|
recordJson.push(j);
|
||||||
}
|
}
|
||||||
@@ -1228,7 +1249,6 @@ window.getIndex = function getIndex(target, _canvas = null) {
|
|||||||
// 使用 window.canvas 作为默认值,确保在 eval() 执行时也能访问
|
// 使用 window.canvas 作为默认值,确保在 eval() 执行时也能访问
|
||||||
const currentCanvas = _canvas || window.canvas || canvas;
|
const currentCanvas = _canvas || window.canvas || canvas;
|
||||||
if (!currentCanvas) {
|
if (!currentCanvas) {
|
||||||
console.error('getIndex: canvas is undefined');
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
temp_objs = currentCanvas.getObjects();
|
temp_objs = currentCanvas.getObjects();
|
||||||
@@ -1377,6 +1397,16 @@ function handleObjectSelected(e) {
|
|||||||
|
|
||||||
// 2. 获取索引
|
// 2. 获取索引
|
||||||
let i = getIndex(select_obj, canvas);
|
let i = getIndex(select_obj, canvas);
|
||||||
|
|
||||||
|
// 如果不是通过对象列表选中的,且对象被锁定,则取消选中
|
||||||
|
if (!window._selectingFromList && isObjectLocked(select_obj)) {
|
||||||
|
canvas.discardActiveObject();
|
||||||
|
canvas.renderAll();
|
||||||
|
$("#base_control, #line_control, #pic_control, #out_pic_control, #text_control, #circle_text_control, #out_text_control, #rect_control, #circle_control, #counter_control, #qrcode_Controll, #barcode_controll").hide();
|
||||||
|
$("#component_type").text(language_str("bg"));
|
||||||
|
selectObj(-1, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
// --- 选中了普通对象 ---
|
// --- 选中了普通对象 ---
|
||||||
@@ -1450,6 +1480,61 @@ function handleObjectMoving(e) {
|
|||||||
updateControls();
|
updateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 辅助函数:检查对象是否被锁定
|
||||||
|
// 只有当 lockMovementX 为 true 时才认为对象被锁定
|
||||||
|
// selectable 为 false 可能是其他原因(如背景图),所以只检查 lockMovementX
|
||||||
|
function isObjectLocked(obj) {
|
||||||
|
if (!obj) return false;
|
||||||
|
// 主要检查 lockMovementX,这是锁定的主要标志
|
||||||
|
return obj.get('lockMovementX') === true;
|
||||||
|
}
|
||||||
|
// 暴露到全局作用域,确保其他模块可以访问
|
||||||
|
window.isObjectLocked = isObjectLocked;
|
||||||
|
|
||||||
|
// 统一的 toJSON 属性列表,不包含锁定相关属性(锁定状态不应被保存)
|
||||||
|
const TO_JSON_PROPERTIES = [
|
||||||
|
"selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline", "evented"
|
||||||
|
];
|
||||||
|
// 暴露到全局作用域
|
||||||
|
window.TO_JSON_PROPERTIES = TO_JSON_PROPERTIES;
|
||||||
|
|
||||||
|
// 辅助函数:解锁所有对象(加载时使用)
|
||||||
|
function unlockAllObjects(canvas) {
|
||||||
|
if (!canvas) return;
|
||||||
|
const objects = canvas.getObjects();
|
||||||
|
objects.forEach((obj, index) => {
|
||||||
|
// 背景对象(索引0)保持锁定状态
|
||||||
|
if (index === 0) {
|
||||||
|
obj.set({
|
||||||
|
lockMovementX: true,
|
||||||
|
lockMovementY: true,
|
||||||
|
lockRotation: true,
|
||||||
|
lockScalingX: true,
|
||||||
|
lockScalingY: true,
|
||||||
|
lockSkewingX: true,
|
||||||
|
lockSkewingY: true,
|
||||||
|
selectable: false,
|
||||||
|
evented: false
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 其他对象默认解锁
|
||||||
|
obj.set({
|
||||||
|
lockMovementX: false,
|
||||||
|
lockMovementY: false,
|
||||||
|
lockRotation: false,
|
||||||
|
lockScalingX: false,
|
||||||
|
lockScalingY: false,
|
||||||
|
lockSkewingX: false,
|
||||||
|
lockSkewingY: false,
|
||||||
|
selectable: true,
|
||||||
|
evented: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 暴露到全局作用域
|
||||||
|
window.unlockAllObjects = unlockAllObjects;
|
||||||
|
|
||||||
// 将 handleObjectSelected 附加到 window 对象,确保全局可访问
|
// 将 handleObjectSelected 附加到 window 对象,确保全局可访问
|
||||||
window.handleObjectSelected = handleObjectSelected;
|
window.handleObjectSelected = handleObjectSelected;
|
||||||
|
|
||||||
@@ -1489,6 +1574,17 @@ function initCanvasEvents() {
|
|||||||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||||||
handleObjectSelected(e);
|
handleObjectSelected(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 阻止被锁定的对象被框选选中(只过滤被锁定的对象,保留未锁定的对象)
|
||||||
|
currentCanvas.on('before:selection:created', (e) => {
|
||||||
|
if (!e.targets || e.targets.length === 0) return;
|
||||||
|
// 过滤掉被锁定的对象,保留辅助线和未锁定的对象
|
||||||
|
e.targets = e.targets.filter(target => {
|
||||||
|
if (target.isGuideLine) return true; // 保留辅助线
|
||||||
|
return !isObjectLocked(target); // 移除被锁定的对象,保留未锁定的对象
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// 添加 selection 事件以确保对象选中时正确显示属性面板
|
// 添加 selection 事件以确保对象选中时正确显示属性面板
|
||||||
currentCanvas.on('selection:created', (e) => {
|
currentCanvas.on('selection:created', (e) => {
|
||||||
canvas = currentCanvas;
|
canvas = currentCanvas;
|
||||||
@@ -1504,16 +1600,12 @@ function initCanvasEvents() {
|
|||||||
canvas = currentCanvas;
|
canvas = currentCanvas;
|
||||||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||||||
|
|
||||||
// 阻止背景图(索引0)被选中(如果已锁定)
|
// 如果不是通过对象列表选中的,且对象被锁定,则取消选中
|
||||||
let selectedObj = e.target;
|
// 注意:只有真正被锁定的对象才会被取消选中,未锁定的对象应该正常选中
|
||||||
let idx = getIndex(selectedObj);
|
if (!window._selectingFromList && e.target && isObjectLocked(e.target)) {
|
||||||
if (idx === 0) {
|
currentCanvas.discardActiveObject();
|
||||||
let bgObj = currentCanvas.getObjects()[0];
|
currentCanvas.renderAll();
|
||||||
if (bgObj && (bgObj.get('lockMovementX') === true || bgObj.get('selectable') === false)) {
|
return;
|
||||||
currentCanvas.discardActiveObject();
|
|
||||||
currentCanvas.renderAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleObjectSelected(e);
|
handleObjectSelected(e);
|
||||||
@@ -1582,7 +1674,6 @@ function initCanvasEvents() {
|
|||||||
if (typeof window.updateList === 'function') {
|
if (typeof window.updateList === 'function') {
|
||||||
window.updateList();
|
window.updateList();
|
||||||
}
|
}
|
||||||
console.warn('objData is undefined or missing type at index', idx - 1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let target = event.target;
|
let target = event.target;
|
||||||
@@ -2081,7 +2172,6 @@ window.copySelection = function copySelection() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
clipboardData.offset = 10; // 重置偏移量
|
clipboardData.offset = 10; // 重置偏移量
|
||||||
console.log(`已复制 ${activeObjects.length} 个对象`);
|
|
||||||
layer.msg("已复制");
|
layer.msg("已复制");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-14
@@ -25,17 +25,14 @@ async function saveImageAsPNG(buffer) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
console.log('用户取消了保存操作');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将Buffer写入PNG文件到用户选择的路径
|
// 将Buffer写入PNG文件到用户选择的路径
|
||||||
fs.writeFile(filePath, buffer, (err) => {
|
fs.writeFile(filePath, buffer, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('写入文件失败:', err);
|
|
||||||
} else {
|
} else {
|
||||||
layer.msg(language_str("saveSucc") + filePath);//'保存成功至'
|
layer.msg(language_str("saveSucc") + filePath);//'保存成功至'
|
||||||
console.log('PNG文件已保存至:', filePath);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1110,15 +1107,31 @@ window.openFile = function open(file) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
canvas1.loadFromJSON(j.f, function () {
|
canvas1.loadFromJSON(j.f, function () {
|
||||||
|
// 加载后解锁所有对象(背景除外)
|
||||||
|
if (typeof window.unlockAllObjects === 'function') {
|
||||||
|
window.unlockAllObjects(canvas1);
|
||||||
|
}
|
||||||
if (typeof window.regenerateQrCodesAndBarcodes === 'function') {
|
if (typeof window.regenerateQrCodesAndBarcodes === 'function') {
|
||||||
window.regenerateQrCodesAndBarcodes(canvas1, fo);
|
window.regenerateQrCodesAndBarcodes(canvas1, fo);
|
||||||
}
|
}
|
||||||
|
// 加载后更新列表和图标显示
|
||||||
|
if (typeof window.updateList === 'function') {
|
||||||
|
window.updateList();
|
||||||
|
}
|
||||||
canvas1.renderAll();
|
canvas1.renderAll();
|
||||||
});
|
});
|
||||||
canvas2.loadFromJSON(j.b, function () {
|
canvas2.loadFromJSON(j.b, function () {
|
||||||
|
// 加载后解锁所有对象(背景除外)
|
||||||
|
if (typeof window.unlockAllObjects === 'function') {
|
||||||
|
window.unlockAllObjects(canvas2);
|
||||||
|
}
|
||||||
if (typeof window.regenerateQrCodesAndBarcodes === 'function') {
|
if (typeof window.regenerateQrCodesAndBarcodes === 'function') {
|
||||||
window.regenerateQrCodesAndBarcodes(canvas2, bo);
|
window.regenerateQrCodesAndBarcodes(canvas2, bo);
|
||||||
}
|
}
|
||||||
|
// 加载后更新列表和图标显示
|
||||||
|
if (typeof window.updateList === 'function') {
|
||||||
|
window.updateList();
|
||||||
|
}
|
||||||
canvas2.renderAll();
|
canvas2.renderAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1165,12 +1178,13 @@ window.openFile = function open(file) {
|
|||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
recordObjs1.push(JSON.stringify(objs1))
|
recordObjs1.push(JSON.stringify(objs1))
|
||||||
let j1 = canvas1.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
const props = window.TO_JSON_PROPERTIES || ["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline", "evented"];
|
||||||
|
let j1 = canvas1.toJSON(props);
|
||||||
j1.objects[0].hoverCursor = "default";
|
j1.objects[0].hoverCursor = "default";
|
||||||
recordJson1.push(j1);
|
recordJson1.push(j1);
|
||||||
|
|
||||||
recordObjs2.push(JSON.stringify(objs2))
|
recordObjs2.push(JSON.stringify(objs2))
|
||||||
let j2 = canvas2.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
let j2 = canvas2.toJSON(props);
|
||||||
recordJson2.push(j2);
|
recordJson2.push(j2);
|
||||||
}, 0);
|
}, 0);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -1229,8 +1243,9 @@ function saveAs(op1, callback) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let j = canvas1.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
const props = window.TO_JSON_PROPERTIES || ["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline", "lockMovementX", "lockMovementY", "lockRotation", "lockScalingX", "lockScalingY", "lockSkewingX", "lockSkewingY", "evented"];
|
||||||
let b = canvas2.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
let j = canvas1.toJSON(props);
|
||||||
|
let b = canvas2.toJSON(props);
|
||||||
|
|
||||||
// 恢复辅助线
|
// 恢复辅助线
|
||||||
guideLines1.forEach(obj => canvas1.add(obj));
|
guideLines1.forEach(obj => canvas1.add(obj));
|
||||||
@@ -1271,7 +1286,6 @@ function saveAs(op1, callback) {
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1292,8 +1306,9 @@ function save(op1, callback) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let j = canvas1.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
const props = window.TO_JSON_PROPERTIES || ["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline", "lockMovementX", "lockMovementY", "lockRotation", "lockScalingX", "lockScalingY", "lockSkewingX", "lockSkewingY", "evented"];
|
||||||
let b = canvas2.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
let j = canvas1.toJSON(props);
|
||||||
|
let b = canvas2.toJSON(props);
|
||||||
|
|
||||||
// 恢复辅助线
|
// 恢复辅助线
|
||||||
guideLines1.forEach(obj => canvas1.add(obj));
|
guideLines1.forEach(obj => canvas1.add(obj));
|
||||||
@@ -1346,7 +1361,6 @@ function save(op1, callback) {
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1365,7 +1379,6 @@ window.saveHistory = function saveHistory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("读取历史记录失败,将重置:", e);
|
|
||||||
// 出错时使用默认空数组,不中断流程
|
// 出错时使用默认空数组,不中断流程
|
||||||
j = { history: [] };
|
j = { history: [] };
|
||||||
}
|
}
|
||||||
@@ -1398,7 +1411,6 @@ window.saveHistory = function saveHistory() {
|
|||||||
try {
|
try {
|
||||||
fs.writeFileSync(fullPath, JSON.stringify(j), 'utf8');
|
fs.writeFileSync(fullPath, JSON.stringify(j), 'utf8');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("写入历史记录失败:", e);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 向后兼容
|
// 向后兼容
|
||||||
@@ -1448,7 +1460,6 @@ function clearAll() {
|
|||||||
if (typeof window.updateList === 'function') {
|
if (typeof window.updateList === 'function') {
|
||||||
window.updateList();
|
window.updateList();
|
||||||
}
|
}
|
||||||
console.log();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将 clearAll 附加到 window 对象,确保全局可访问
|
// 将 clearAll 附加到 window 对象,确保全局可访问
|
||||||
|
|||||||
+2417
-2338
File diff suppressed because one or more lines are too long
@@ -108,8 +108,6 @@ ipcRenderer.send('get-scale-rate');
|
|||||||
});
|
});
|
||||||
APIFMS = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
|
APIFMS = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('des 加密 -------------------------');
|
|
||||||
console.log(err);
|
|
||||||
}
|
}
|
||||||
return APIFMS;
|
return APIFMS;
|
||||||
};
|
};
|
||||||
@@ -491,7 +489,6 @@ ipcRenderer.send('get-scale-rate');
|
|||||||
bytenode = require('bytenode');
|
bytenode = require('bytenode');
|
||||||
require.extensions['.dl'] = require.extensions['.jsc'];
|
require.extensions['.dl'] = require.extensions['.jsc'];
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.warn('[加载模块] bytenode 未安装,无法加载 .jsc 文件');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })();
|
const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })();
|
||||||
@@ -504,7 +501,6 @@ ipcRenderer.send('get-scale-rate');
|
|||||||
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
|
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[加载模块] 无法读取模块映射配置,使用默认文件名');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取映射后的文件名(跨平台兼容)
|
// 获取映射后的文件名(跨平台兼容)
|
||||||
@@ -524,10 +520,8 @@ ipcRenderer.send('get-scale-rate');
|
|||||||
if (fs.existsSync(jscPath) && bytenode) {
|
if (fs.existsSync(jscPath) && bytenode) {
|
||||||
try {
|
try {
|
||||||
require(jscPath);
|
require(jscPath);
|
||||||
console.log(`[加载模块] ✅ ${moduleName} → ${mappedName}.jsc`);
|
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`[加载模块] ❌ ${moduleName}.jsc 加载失败:`, e.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,9 +529,7 @@ ipcRenderer.send('get-scale-rate');
|
|||||||
if (fs.existsSync(jsPath)) {
|
if (fs.existsSync(jsPath)) {
|
||||||
try {
|
try {
|
||||||
eval(fs.readFileSync(jsPath, 'utf8'));
|
eval(fs.readFileSync(jsPath, 'utf8'));
|
||||||
console.log(`[加载模块] ✅ ${moduleName} → ${moduleName}.js`);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`[加载模块] ❌ ${moduleName}.js 加载失败:`, e.message);
|
|
||||||
alert(`加载 ${moduleName} 失败!\n\n错误: ${e.message}`);
|
alert(`加载 ${moduleName} 失败!\n\n错误: ${e.message}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+173
-77
@@ -425,17 +425,17 @@ function initRulers() {
|
|||||||
function createFabricGuide(type, domX, domY) {
|
function createFabricGuide(type, domX, domY) {
|
||||||
// domX 和 domY 是相对于 canvas-wrapper 的坐标
|
// domX 和 domY 是相对于 canvas-wrapper 的坐标
|
||||||
// 需要转换为相对于 canvas 的坐标,然后再转换为 Fabric 画布坐标
|
// 需要转换为相对于 canvas 的坐标,然后再转换为 Fabric 画布坐标
|
||||||
|
|
||||||
// 获取 canvas 相对于 canvas-wrapper 的位置
|
// 获取 canvas 相对于 canvas-wrapper 的位置
|
||||||
let canvas1El = $('#canvas1');
|
let canvas1El = $('#canvas1');
|
||||||
let canvasPosition = canvas1El.position();
|
let canvasPosition = canvas1El.position();
|
||||||
let canvasMarginLeft = parseFloat(canvas1El.css('margin-left')) || 0;
|
let canvasMarginLeft = parseFloat(canvas1El.css('margin-left')) || 0;
|
||||||
let canvasMarginTop = parseFloat(canvas1El.css('margin-top')) || 0;
|
let canvasMarginTop = parseFloat(canvas1El.css('margin-top')) || 0;
|
||||||
|
|
||||||
// 计算相对于 canvas 的坐标(减去 canvas 在 wrapper 中的位置和 margin)
|
// 计算相对于 canvas 的坐标(减去 canvas 在 wrapper 中的位置和 margin)
|
||||||
let relX = domX - canvasPosition.left - canvasMarginLeft;
|
let relX = domX - canvasPosition.left - canvasMarginLeft;
|
||||||
let relY = domY - canvasPosition.top - canvasMarginTop;
|
let relY = domY - canvasPosition.top - canvasMarginTop;
|
||||||
|
|
||||||
// 转为 Fabric 坐标 (除以 zoom)
|
// 转为 Fabric 坐标 (除以 zoom)
|
||||||
let canvasX = relX / zoom;
|
let canvasX = relX / zoom;
|
||||||
let canvasY = relY / zoom;
|
let canvasY = relY / zoom;
|
||||||
@@ -555,22 +555,18 @@ function selectObject(target, index) {
|
|||||||
function selectPic(target, index) {
|
function selectPic(target, index) {
|
||||||
// 检查是否有选中对象,如果没有则直接返回
|
// 检查是否有选中对象,如果没有则直接返回
|
||||||
if (!canvas || !canvas.getActiveObject()) return;
|
if (!canvas || !canvas.getActiveObject()) return;
|
||||||
|
|
||||||
$("#pic_control").show();
|
$("#pic_control").show();
|
||||||
$("#set_bg").show();
|
$("#set_bg").show();
|
||||||
let activeObj = canvas.getActiveObject();
|
let activeObj = canvas.getActiveObject();
|
||||||
|
|
||||||
// 检查对象是否被锁定或设为背景(索引0且已锁定)
|
// 检查对象是否被锁定
|
||||||
let idx = getIndex(activeObj, canvas);
|
if (isObjectLocked(activeObj)) {
|
||||||
if (idx === 0) {
|
canvas.discardActiveObject();
|
||||||
// 如果是背景图且已锁定,不应该显示图片控件
|
canvas.renderAll();
|
||||||
if (activeObj.get('lockMovementX') === true || activeObj.get('selectable') === false) {
|
return;
|
||||||
canvas.discardActiveObject();
|
|
||||||
canvas.renderAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof pic_op !== 'undefined' && pic_op && typeof pic_op.setValue === 'function') {
|
if (typeof pic_op !== 'undefined' && pic_op && typeof pic_op.setValue === 'function') {
|
||||||
pic_op.setValue(100 - (activeObj.get("opacity") * 100));
|
pic_op.setValue(100 - (activeObj.get("opacity") * 100));
|
||||||
} else {
|
} else {
|
||||||
@@ -656,44 +652,48 @@ function selectText(target, index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function selectCircleText(target, index) {
|
function selectCircleText(target, index) {
|
||||||
let idx = getIndex(canvas.getActiveObject(), canvas);
|
const activeObj = target || canvas.getActiveObject();
|
||||||
|
if (!activeObj) return;
|
||||||
|
|
||||||
|
let idx = getIndex(activeObj);
|
||||||
$("#circle_text_control").show();
|
$("#circle_text_control").show();
|
||||||
$("#circle_text_color").val(canvas.getActiveObject().get("fill"));
|
$("#circle_text_color").val(activeObj.get("fill"));
|
||||||
$("#circle_text_back_color").val(canvas.getActiveObject().get("textBackgroundColor") == "" ? '#ffffff' : canvas.getActiveObject().get("textBackgroundColor"));
|
$("#circle_text_back_color").val(activeObj.get("textBackgroundColor") == "" ? '#ffffff' : activeObj.get("textBackgroundColor"));
|
||||||
if (typeof circle_text_size !== 'undefined' && circle_text_size.setValue) {
|
|
||||||
circle_text_size_updating = true; // 设置标志位
|
if (typeof circle_text_size !== 'undefined' && circle_text_size && typeof circle_text_size.setValue === 'function') {
|
||||||
circle_text_size.setValue(canvas.getActiveObject().get("fontSize"));
|
if (typeof circle_text_size_updating !== 'undefined') {
|
||||||
circle_text_size_updating = false; // 清除标志位
|
circle_text_size_updating = true;
|
||||||
} else {
|
}
|
||||||
$("#circle_text_size").next().children(".layui-slider-bar").css("width", ((canvas.getActiveObject().get("fontSize") - 10) / (120 - 10)) * 100 + "%");
|
circle_text_size.setValue(activeObj.get("fontSize") - 10);
|
||||||
$("#circle_text_size").next().children(".layui-slider-handle").css("left", ((canvas.getActiveObject().get("fontSize") - 10) / (120 - 10)) * 100 + "%");
|
if (typeof circle_text_size_updating !== 'undefined') {
|
||||||
|
circle_text_size_updating = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter.setValue) {
|
|
||||||
circle_text_diameter.setValue(canvas.getActiveObject().get("diameter"));
|
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter && typeof circle_text_diameter.setValue === 'function') {
|
||||||
} else {
|
circle_text_diameter.setValue(activeObj.get("diameter") - 50);
|
||||||
$("#circle_text_diameter").next().children(".layui-slider-bar").css("width", ((canvas.getActiveObject().get("diameter") - 50) / (1100 - 50)) * 100 + "%");
|
|
||||||
$("#circle_text_diameter").next().children(".layui-slider-handle").css("left", ((canvas.getActiveObject().get("diameter") - 50) / (1100 - 50)) * 100 + "%");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#circle_text_center").prop("checked", objs[idx - 1].circleCenter ? 'checked' : '');
|
$("#circle_text_center").prop("checked", objs[idx - 1].circleCenter ? 'checked' : '');
|
||||||
$("#circle_text_text").val(canvas.getActiveObject().get("text"));
|
$("#circle_text_text").val(activeObj.get("text"));
|
||||||
$("#circle_text_font_family").val(canvas.getActiveObject().get("fontFamily"));
|
$("#circle_text_font_family").val(activeObj.get("fontFamily"));
|
||||||
|
|
||||||
if (canvas.getActiveObject().get("underline") == true) {
|
if (activeObj.get("underline") == true) {
|
||||||
$("#circle_text_underline").addClass("ui-radio-acitve")
|
$("#circle_text_underline").addClass("ui-radio-acitve")
|
||||||
} else {
|
} else {
|
||||||
$("#circle_text_underline").removeClass("ui-radio-acitve")
|
$("#circle_text_underline").removeClass("ui-radio-acitve")
|
||||||
}
|
}
|
||||||
if (canvas.getActiveObject().get("fontWeight") == "bold") {
|
if (activeObj.get("fontWeight") == "bold") {
|
||||||
$("#circle_text_bold").addClass("ui-radio-acitve")
|
$("#circle_text_bold").addClass("ui-radio-acitve")
|
||||||
} else {
|
} else {
|
||||||
$("#circle_text_bold").removeClass("ui-radio-acitve")
|
$("#circle_text_bold").removeClass("ui-radio-acitve")
|
||||||
}
|
}
|
||||||
if (canvas.getActiveObject().get("fontStyle") == "italic") {
|
if (activeObj.get("fontStyle") == "italic") {
|
||||||
$("#circle_text_italics").addClass("ui-radio-acitve")
|
$("#circle_text_italics").addClass("ui-radio-acitve")
|
||||||
} else {
|
} else {
|
||||||
$("#circle_text_italics").removeClass("ui-radio-acitve")
|
$("#circle_text_italics").removeClass("ui-radio-acitve")
|
||||||
}
|
}
|
||||||
if (canvas.getActiveObject().get("linethrough") == true) {
|
if (activeObj.get("linethrough") == true) {
|
||||||
$("#circle_text_linethrough").addClass("ui-radio-acitve")
|
$("#circle_text_linethrough").addClass("ui-radio-acitve")
|
||||||
} else {
|
} else {
|
||||||
$("#circle_text_linethrough").removeClass("ui-radio-acitve")
|
$("#circle_text_linethrough").removeClass("ui-radio-acitve")
|
||||||
@@ -931,18 +931,15 @@ function handleObjectSelected(e) {
|
|||||||
|
|
||||||
// 3. 获取索引
|
// 3. 获取索引
|
||||||
let i = getIndex(select_obj, canvas);
|
let i = getIndex(select_obj, canvas);
|
||||||
|
|
||||||
// 检查对象是否被锁定或设为背景(索引0且已锁定)
|
// 如果不是通过对象列表选中的,且对象被锁定,则取消选中
|
||||||
if (i === 0) {
|
if (!window._selectingFromList && isObjectLocked(select_obj)) {
|
||||||
if (select_obj.get('lockMovementX') === true || select_obj.get('selectable') === false) {
|
canvas.discardActiveObject();
|
||||||
// 如果是背景图且已锁定,取消选中
|
canvas.renderAll();
|
||||||
canvas.discardActiveObject();
|
$("#base_control, #line_control, #pic_control, #out_pic_control, #text_control, #circle_text_control, #out_text_control, #rect_control, #circle_control, #counter_control, #qrcode_Controll, #barcode_controll").hide();
|
||||||
canvas.renderAll();
|
$("#component_type").text(language_str("bg"));
|
||||||
$("#base_control, #line_control, #pic_control, #out_pic_control, #text_control, #circle_text_control, #out_text_control, #rect_control, #circle_control, #counter_control, #qrcode_Controll, #barcode_controll").hide();
|
selectObj(-1, true);
|
||||||
$("#component_type").text(language_str("bg"));
|
return;
|
||||||
selectObj(-1, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
@@ -1026,6 +1023,61 @@ function handleObjectMoving(e) {
|
|||||||
updateControls();
|
updateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 辅助函数:检查对象是否被锁定
|
||||||
|
// 只有当 lockMovementX 为 true 时才认为对象被锁定
|
||||||
|
// selectable 为 false 可能是其他原因(如背景图),所以只检查 lockMovementX
|
||||||
|
function isObjectLocked(obj) {
|
||||||
|
if (!obj) return false;
|
||||||
|
// 主要检查 lockMovementX,这是锁定的主要标志
|
||||||
|
return obj.get('lockMovementX') === true;
|
||||||
|
}
|
||||||
|
// 暴露到全局作用域,确保其他模块可以访问
|
||||||
|
window.isObjectLocked = isObjectLocked;
|
||||||
|
|
||||||
|
// 统一的 toJSON 属性列表,不包含锁定相关属性(锁定状态不应被保存)
|
||||||
|
const TO_JSON_PROPERTIES = [
|
||||||
|
"selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline", "evented"
|
||||||
|
];
|
||||||
|
// 暴露到全局作用域
|
||||||
|
window.TO_JSON_PROPERTIES = TO_JSON_PROPERTIES;
|
||||||
|
|
||||||
|
// 辅助函数:解锁所有对象(加载时使用)
|
||||||
|
function unlockAllObjects(canvas) {
|
||||||
|
if (!canvas) return;
|
||||||
|
const objects = canvas.getObjects();
|
||||||
|
objects.forEach((obj, index) => {
|
||||||
|
// 背景对象(索引0)保持锁定状态
|
||||||
|
if (index === 0) {
|
||||||
|
obj.set({
|
||||||
|
lockMovementX: true,
|
||||||
|
lockMovementY: true,
|
||||||
|
lockRotation: true,
|
||||||
|
lockScalingX: true,
|
||||||
|
lockScalingY: true,
|
||||||
|
lockSkewingX: true,
|
||||||
|
lockSkewingY: true,
|
||||||
|
selectable: false,
|
||||||
|
evented: false
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 其他对象默认解锁
|
||||||
|
obj.set({
|
||||||
|
lockMovementX: false,
|
||||||
|
lockMovementY: false,
|
||||||
|
lockRotation: false,
|
||||||
|
lockScalingX: false,
|
||||||
|
lockScalingY: false,
|
||||||
|
lockSkewingX: false,
|
||||||
|
lockSkewingY: false,
|
||||||
|
selectable: true,
|
||||||
|
evented: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 暴露到全局作用域
|
||||||
|
window.unlockAllObjects = unlockAllObjects;
|
||||||
|
|
||||||
// 将 handleObjectSelected 附加到 window 对象,确保全局可访问
|
// 将 handleObjectSelected 附加到 window 对象,确保全局可访问
|
||||||
window.handleObjectSelected = handleObjectSelected;
|
window.handleObjectSelected = handleObjectSelected;
|
||||||
|
|
||||||
@@ -1087,6 +1139,16 @@ function initCanvasEvents() {
|
|||||||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||||||
handleObjectSelected(e);
|
handleObjectSelected(e);
|
||||||
});
|
});
|
||||||
|
// 阻止被锁定的对象被框选选中(只过滤被锁定的对象,保留未锁定的对象)
|
||||||
|
currentCanvas.on('before:selection:created', (e) => {
|
||||||
|
if (!e.targets || e.targets.length === 0) return;
|
||||||
|
// 过滤掉被锁定的对象,保留辅助线和未锁定的对象
|
||||||
|
e.targets = e.targets.filter(target => {
|
||||||
|
if (target.isGuideLine) return true; // 保留辅助线
|
||||||
|
return !isObjectLocked(target); // 移除被锁定的对象,保留未锁定的对象
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// 添加 selection 事件以确保对象选中时正确显示属性面板
|
// 添加 selection 事件以确保对象选中时正确显示属性面板
|
||||||
currentCanvas.on('selection:created', (e) => {
|
currentCanvas.on('selection:created', (e) => {
|
||||||
canvas = currentCanvas;
|
canvas = currentCanvas;
|
||||||
@@ -1101,19 +1163,15 @@ function initCanvasEvents() {
|
|||||||
currentCanvas.on('object:selected', (e) => {
|
currentCanvas.on('object:selected', (e) => {
|
||||||
canvas = currentCanvas;
|
canvas = currentCanvas;
|
||||||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||||||
|
|
||||||
// 阻止背景图(索引0)被选中(如果已锁定)
|
// 如果不是通过对象列表选中的,且对象被锁定,则取消选中
|
||||||
let selectedObj = e.target;
|
// 注意:只有真正被锁定的对象才会被取消选中,未锁定的对象应该正常选中
|
||||||
let idx = getIndex(selectedObj, currentCanvas);
|
if (!window._selectingFromList && e.target && isObjectLocked(e.target)) {
|
||||||
if (idx === 0) {
|
currentCanvas.discardActiveObject();
|
||||||
let bgObj = currentCanvas.getObjects()[0];
|
currentCanvas.renderAll();
|
||||||
if (bgObj && (bgObj.get('lockMovementX') === true || bgObj.get('selectable') === false)) {
|
return;
|
||||||
currentCanvas.discardActiveObject();
|
|
||||||
currentCanvas.renderAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleObjectSelected(e);
|
handleObjectSelected(e);
|
||||||
// 更新对象列表以同步锁状态
|
// 更新对象列表以同步锁状态
|
||||||
if (typeof window.updateList === 'function') {
|
if (typeof window.updateList === 'function') {
|
||||||
@@ -1157,7 +1215,6 @@ function initCanvasEvents() {
|
|||||||
let objData = objs[idx - 1];
|
let objData = objs[idx - 1];
|
||||||
// 安全检查:确保 objData 存在且有 type 属性
|
// 安全检查:确保 objData 存在且有 type 属性
|
||||||
if (!objData || typeof objData.type === 'undefined') {
|
if (!objData || typeof objData.type === 'undefined') {
|
||||||
console.warn('objData is undefined or missing type at index', idx - 1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let target = event.target;
|
let target = event.target;
|
||||||
@@ -1228,10 +1285,10 @@ window.updateList = function updateList() {
|
|||||||
let canvasObj = canvas.getObjects()[i + 1];
|
let canvasObj = canvas.getObjects()[i + 1];
|
||||||
isLocked = canvasObj.get('lockMovementX') === true;
|
isLocked = canvasObj.get('lockMovementX') === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 锁定状态图标
|
// 锁定状态图标
|
||||||
const lockIcon = isLocked ?
|
const lockIcon = isLocked ?
|
||||||
'<img src="public/images/lock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.7;" title="已锁定">' :
|
'<img src="public/images/lock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.7;" title="已锁定">' :
|
||||||
'<img src="public/images/unlock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.5;" title="未锁定">';
|
'<img src="public/images/unlock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.5;" title="未锁定">';
|
||||||
|
|
||||||
// 组装 HTML
|
// 组装 HTML
|
||||||
@@ -1257,6 +1314,9 @@ window.updateList = function updateList() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 标记是否通过对象列表选中(用于区分鼠标点击和列表点击)
|
||||||
|
window._selectingFromList = false;
|
||||||
|
|
||||||
// 将 selectObj 附加到 window 对象,确保全局可访问
|
// 将 selectObj 附加到 window 对象,确保全局可访问
|
||||||
window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
|
window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
|
||||||
let indicesArray = (Array.isArray(objIndices)) ? objIndices : ((typeof objIndices === 'number' && objIndices >= 0) ? [objIndices] : []);
|
let indicesArray = (Array.isArray(objIndices)) ? objIndices : ((typeof objIndices === 'number' && objIndices >= 0) ? [objIndices] : []);
|
||||||
@@ -1285,8 +1345,39 @@ window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
|
|||||||
if (!isFromCanvas && indicesArray.length === 1) {
|
if (!isFromCanvas && indicesArray.length === 1) {
|
||||||
let target = canvas.getObjects()[indicesArray[0] + 1];
|
let target = canvas.getObjects()[indicesArray[0] + 1];
|
||||||
if (target) {
|
if (target) {
|
||||||
|
// 检查对象是否被锁定
|
||||||
|
let isLocked = isObjectLocked(target);
|
||||||
|
|
||||||
|
// 设置标志位,表示这是通过对象列表选中的(无论是否锁定)
|
||||||
|
window._selectingFromList = true;
|
||||||
|
|
||||||
|
// 如果被锁定,临时设置 selectable 和 evented 为 true,以便能够选中
|
||||||
|
if (isLocked) {
|
||||||
|
target.set({
|
||||||
|
selectable: true,
|
||||||
|
evented: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
canvas.setActiveObject(target);
|
canvas.setActiveObject(target);
|
||||||
canvas.requestRenderAll();
|
canvas.requestRenderAll();
|
||||||
|
|
||||||
|
// 如果对象被锁定,选中后立即恢复锁定状态(但保持选中状态)
|
||||||
|
if (isLocked) {
|
||||||
|
setTimeout(() => {
|
||||||
|
target.set({
|
||||||
|
selectable: false,
|
||||||
|
evented: false
|
||||||
|
});
|
||||||
|
canvas.requestRenderAll();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除标志位(延迟清除,确保事件处理完成)
|
||||||
|
setTimeout(() => {
|
||||||
|
window._selectingFromList = false;
|
||||||
|
}, 10);
|
||||||
|
|
||||||
handleObjectSelected();
|
handleObjectSelected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1306,7 +1397,8 @@ window.recordState = function recordState() {
|
|||||||
currentRecordJson.pop();
|
currentRecordJson.pop();
|
||||||
}
|
}
|
||||||
currentRecordObjs.push(JSON.stringify(currentObjs))
|
currentRecordObjs.push(JSON.stringify(currentObjs))
|
||||||
let j = currentCanvas.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
// 保存所有锁定相关的属性,确保锁定状态可以正确恢复
|
||||||
|
let j = currentCanvas.toJSON(TO_JSON_PROPERTIES);
|
||||||
j.objects[0].hoverCursor = "default";
|
j.objects[0].hoverCursor = "default";
|
||||||
currentRecordJson.push(j);
|
currentRecordJson.push(j);
|
||||||
};
|
};
|
||||||
@@ -1321,7 +1413,6 @@ window.getIndex = function getIndex(target, _canvas = null) {
|
|||||||
// 使用 window.canvas 作为默认值,确保在 eval() 执行时也能访问
|
// 使用 window.canvas 作为默认值,确保在 eval() 执行时也能访问
|
||||||
const currentCanvas = _canvas || window.canvas || canvas;
|
const currentCanvas = _canvas || window.canvas || canvas;
|
||||||
if (!currentCanvas) {
|
if (!currentCanvas) {
|
||||||
console.error('getIndex: canvas is undefined');
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
temp_objs = currentCanvas.getObjects();
|
temp_objs = currentCanvas.getObjects();
|
||||||
@@ -1487,7 +1578,7 @@ function addBackground() {
|
|||||||
canvas2.renderAll()
|
canvas2.renderAll()
|
||||||
|
|
||||||
recordObjs2.push(JSON.stringify(objs2))
|
recordObjs2.push(JSON.stringify(objs2))
|
||||||
recordJson2.push(canvas2.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline']))
|
recordJson2.push(canvas2.toJSON(TO_JSON_PROPERTIES))
|
||||||
|
|
||||||
let file = GetFile().get('file')
|
let file = GetFile().get('file')
|
||||||
if (file && file != 'empty') {
|
if (file && file != 'empty') {
|
||||||
@@ -1909,12 +2000,16 @@ var circle_text_size = slider.render({
|
|||||||
max: 120,
|
max: 120,
|
||||||
value: 50,
|
value: 50,
|
||||||
change: function (value) {
|
change: function (value) {
|
||||||
if (circle_text_size_updating) return; // 如果正在更新slider,跳过change事件
|
if (circle_text_size_updating) return;
|
||||||
if (canvas.getActiveObject()) {
|
if (canvas && canvas.getActiveObject && canvas.getActiveObject()) {
|
||||||
canvas.getActiveObject().set('fontSize', value);
|
canvas.getActiveObject().set('fontSize', value);
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
updateControls();
|
if (typeof updateControls === 'function') {
|
||||||
recordState();
|
updateControls();
|
||||||
|
}
|
||||||
|
if (typeof recordState === 'function') {
|
||||||
|
recordState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1925,11 +2020,15 @@ var circle_text_diameter = slider.render({
|
|||||||
max: 1100,
|
max: 1100,
|
||||||
value: 500,
|
value: 500,
|
||||||
change: function (value) {
|
change: function (value) {
|
||||||
if (canvas.getActiveObject()) {
|
if (canvas && canvas.getActiveObject && canvas.getActiveObject()) {
|
||||||
canvas.getActiveObject().set('diameter', value);
|
canvas.getActiveObject().set('diameter', value);
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
updateControls();
|
if (typeof updateControls === 'function') {
|
||||||
recordState();
|
updateControls();
|
||||||
|
}
|
||||||
|
if (typeof recordState === 'function') {
|
||||||
|
recordState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -2030,17 +2129,14 @@ window.savePdf = async function savePdf(buffer) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
console.log('用户取消了保存操作');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将Buffer写入PDF文件到用户选择的路径
|
// 将Buffer写入PDF文件到用户选择的路径
|
||||||
fs.writeFile(filePath, buffer, (err) => {
|
fs.writeFile(filePath, buffer, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('写入文件失败:', err);
|
|
||||||
} else {
|
} else {
|
||||||
layer.msg(language_str("saveSucc") + filePath);//'保存成功至'
|
layer.msg(language_str("saveSucc") + filePath);//'保存成功至'
|
||||||
console.log('PDF文件已保存至:', filePath);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
+25
-13
@@ -346,8 +346,6 @@ window.display_func = function display_func(img1, img2, img3) {
|
|||||||
// 只处理导出(保存PDF)
|
// 只处理导出(保存PDF)
|
||||||
if (typeof window.savePdf === 'function') {
|
if (typeof window.savePdf === 'function') {
|
||||||
window.savePdf(Buffer.from(pdfBuffer));
|
window.savePdf(Buffer.from(pdfBuffer));
|
||||||
} else {
|
|
||||||
console.error('savePdf 函数未定义!');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
btn2: function () {
|
btn2: function () {
|
||||||
@@ -1045,8 +1043,9 @@ function saveAs(op1, callback) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let j = canvas1.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
|
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented'];
|
||||||
let b = canvas2.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
|
let j = canvas1.toJSON(props)
|
||||||
|
let b = canvas2.toJSON(props)
|
||||||
|
|
||||||
// 恢复辅助线
|
// 恢复辅助线
|
||||||
guideLines1.forEach(obj => canvas1.add(obj))
|
guideLines1.forEach(obj => canvas1.add(obj))
|
||||||
@@ -1112,8 +1111,9 @@ function save(op1, callback) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let j = canvas1.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
|
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented'];
|
||||||
let b = canvas2.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
|
let j = canvas1.toJSON(props)
|
||||||
|
let b = canvas2.toJSON(props)
|
||||||
|
|
||||||
// 恢复辅助线
|
// 恢复辅助线
|
||||||
guideLines1.forEach(obj => canvas1.add(obj))
|
guideLines1.forEach(obj => canvas1.add(obj))
|
||||||
@@ -1248,15 +1248,31 @@ window.openFile = function open(file) {
|
|||||||
|
|
||||||
// 加载 JSON,并在回调中重新生成二维码和条形码
|
// 加载 JSON,并在回调中重新生成二维码和条形码
|
||||||
canvas1.loadFromJSON(j.f, function () {
|
canvas1.loadFromJSON(j.f, function () {
|
||||||
|
// 加载后解锁所有对象(背景除外)
|
||||||
|
if (typeof window.unlockAllObjects === 'function') {
|
||||||
|
window.unlockAllObjects(canvas1);
|
||||||
|
}
|
||||||
if (typeof window.regenerateQrCodesAndBarcodes === 'function') {
|
if (typeof window.regenerateQrCodesAndBarcodes === 'function') {
|
||||||
window.regenerateQrCodesAndBarcodes(canvas1, fo);
|
window.regenerateQrCodesAndBarcodes(canvas1, fo);
|
||||||
}
|
}
|
||||||
|
// 加载后更新列表和图标显示
|
||||||
|
if (typeof window.updateList === 'function') {
|
||||||
|
window.updateList();
|
||||||
|
}
|
||||||
canvas1.renderAll()
|
canvas1.renderAll()
|
||||||
})
|
})
|
||||||
canvas2.loadFromJSON(j.b, function () {
|
canvas2.loadFromJSON(j.b, function () {
|
||||||
|
// 加载后解锁所有对象(背景除外)
|
||||||
|
if (typeof window.unlockAllObjects === 'function') {
|
||||||
|
window.unlockAllObjects(canvas2);
|
||||||
|
}
|
||||||
if (typeof window.regenerateQrCodesAndBarcodes === 'function') {
|
if (typeof window.regenerateQrCodesAndBarcodes === 'function') {
|
||||||
window.regenerateQrCodesAndBarcodes(canvas2, bo);
|
window.regenerateQrCodesAndBarcodes(canvas2, bo);
|
||||||
}
|
}
|
||||||
|
// 加载后更新列表和图标显示
|
||||||
|
if (typeof window.updateList === 'function') {
|
||||||
|
window.updateList();
|
||||||
|
}
|
||||||
canvas2.renderAll()
|
canvas2.renderAll()
|
||||||
})
|
})
|
||||||
background_image1 = canvas1.getObjects()[0]
|
background_image1 = canvas1.getObjects()[0]
|
||||||
@@ -1296,19 +1312,18 @@ window.openFile = function open(file) {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (typeof window.updateList === 'function') {
|
if (typeof window.updateList === 'function') {
|
||||||
window.updateList();
|
window.updateList();
|
||||||
} else {
|
|
||||||
console.error('[open函数] ❌ updateList 函数未定义!');
|
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
recordObjs1.push(JSON.stringify(objs1))
|
recordObjs1.push(JSON.stringify(objs1))
|
||||||
let j1 = canvas1.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
|
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented'];
|
||||||
|
let j1 = canvas1.toJSON(props)
|
||||||
j1.objects[0].hoverCursor = 'default'
|
j1.objects[0].hoverCursor = 'default'
|
||||||
recordJson1.push(j1)
|
recordJson1.push(j1)
|
||||||
|
|
||||||
recordObjs2.push(JSON.stringify(objs2))
|
recordObjs2.push(JSON.stringify(objs2))
|
||||||
let j2 = canvas2.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
|
let j2 = canvas2.toJSON(props)
|
||||||
j2.objects[0].hoverCursor = 'default'
|
j2.objects[0].hoverCursor = 'default'
|
||||||
recordJson2.push(j2)
|
recordJson2.push(j2)
|
||||||
}, 0)
|
}, 0)
|
||||||
@@ -1359,12 +1374,9 @@ function clearAll() {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (typeof window.updateList === 'function') {
|
if (typeof window.updateList === 'function') {
|
||||||
window.updateList();
|
window.updateList();
|
||||||
} else {
|
|
||||||
console.error('[clearAll] ❌ updateList 函数未定义!');
|
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
console.log()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将 clearAll 附加到 window 对象,确保全局可访问
|
// 将 clearAll 附加到 window 对象,确保全局可访问
|
||||||
|
|||||||
+136
-768
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user