调整优化

This commit is contained in:
24kycj
2025-12-15 02:55:54 +08:00
parent 50ff0d347a
commit 3c4080f3f1
8 changed files with 3048 additions and 3407 deletions
+6 -13
View File
@@ -17,21 +17,21 @@ 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 文件加载)
@@ -119,7 +119,6 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
// 使用 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;
@@ -497,7 +496,6 @@ layui.use(['layer', 'slider', 'form', 'colorpicker'], function () {
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(); } })();
@@ -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,9 +536,7 @@ 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 {
+122 -32
View File
@@ -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) {
@@ -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();
@@ -1378,6 +1398,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) {
// --- 选中了普通对象 --- // --- 选中了普通对象 ---
--i; // 转换为 objs 数组下标 --i; // 转换为 objs 数组下标
@@ -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,17 +1600,13 @@ 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) {
let bgObj = currentCanvas.getObjects()[0];
if (bgObj && (bgObj.get('lockMovementX') === true || bgObj.get('selectable') === false)) {
currentCanvas.discardActiveObject(); currentCanvas.discardActiveObject();
currentCanvas.renderAll(); currentCanvas.renderAll();
return; 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
View File
@@ -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 对象,确保全局可访问
+132 -53
View File
@@ -1,18 +1,21 @@
var _keyctrl = false, _keyc = false, _textEdit = false, _inputEdit = false; // 移至上层和移至下层的事件处理在下方(第 2179 行),避免重复绑定
$("input").focus(function () {
console.log(1) var _keyctrl = false,
_inputEdit = true _keyc = false,
}) _textEdit = false,
$("input").blur(function () { _inputEdit = false;
_inputEdit = false $('input').focus(function () {
}) _inputEdit = true;
$("textarea").focus(function () { });
console.log(1) $('input').blur(function () {
_inputEdit = true _inputEdit = false;
}) });
$("textarea").blur(function () { $('textarea').focus(function () {
_inputEdit = false _inputEdit = true;
}) });
$('textarea').blur(function () {
_inputEdit = false;
});
$("body").keyup(function (event) { $("body").keyup(function (event) {
// 兼容三端?modifier key 检测(Windows/Linux: Ctrl, Mac: Cmd/Meta? // 兼容三端?modifier key 检测(Windows/Linux: Ctrl, Mac: Cmd/Meta?
if (event.keyCode == 17 || event.keyCode == 91 || event.keyCode == 93) { // Ctrl 键或 Meta 键(Mac Cmd)释? if (event.keyCode == 17 || event.keyCode == 91 || event.keyCode == 93) { // Ctrl 键或 Meta 键(Mac Cmd)释?
@@ -117,59 +120,94 @@ $("body").keydown(function (event) {
if (_keyctrl || event.ctrlKey || event.metaKey) { if (_keyctrl || event.ctrlKey || event.metaKey) {
v = -5; v = -5;
} }
let x = canvas.getActiveObject().get("left"); const currentCanvas = window.canvas || canvas;
if (currentCanvas && currentCanvas.getActiveObject()) {
let x = currentCanvas.getActiveObject().get('left');
x += v; x += v;
canvas.getActiveObject().set("left", x); currentCanvas.getActiveObject().set('left', x);
canvas.renderAll(); currentCanvas.renderAll();
if (typeof window.recordState === 'function') {
window.recordState(); window.recordState();
} else if (typeof recordState === 'function') {
recordState();
}
if (typeof updateControls === 'function') {
updateControls(); updateControls();
} }
}
}
if (event.keyCode == 38) { if (event.keyCode == 38) {
//up //up
let v = -1; let v = -1;
if (_keyctrl || event.ctrlKey || event.metaKey) { if (_keyctrl || event.ctrlKey || event.metaKey) {
v = -5; v = -5;
} }
let y = canvas.getActiveObject().get("top"); const currentCanvas = window.canvas || canvas;
if (currentCanvas && currentCanvas.getActiveObject()) {
let y = currentCanvas.getActiveObject().get('top');
y += v; y += v;
canvas.getActiveObject().set("top", y); currentCanvas.getActiveObject().set('top', y);
canvas.renderAll(); currentCanvas.renderAll();
if (typeof window.recordState === 'function') {
window.recordState(); window.recordState();
} else if (typeof recordState === 'function') {
recordState();
}
if (typeof updateControls === 'function') {
updateControls(); updateControls();
} }
}
}
if (event.keyCode == 39) { if (event.keyCode == 39) {
//right //right
let v = 1; let v = 1;
if (_keyctrl || event.ctrlKey || event.metaKey) { if (_keyctrl || event.ctrlKey || event.metaKey) {
v = 5; v = 5;
} }
let x = canvas.getActiveObject().get("left"); const currentCanvas = window.canvas || canvas;
if (currentCanvas && currentCanvas.getActiveObject()) {
let x = currentCanvas.getActiveObject().get('left');
x += v; x += v;
canvas.getActiveObject().set("left", x); currentCanvas.getActiveObject().set('left', x);
canvas.renderAll(); currentCanvas.renderAll();
if (typeof window.recordState === 'function') {
window.recordState(); window.recordState();
} else if (typeof recordState === 'function') {
recordState();
}
if (typeof updateControls === 'function') {
updateControls(); updateControls();
} }
}
}
if (event.keyCode == 40) { if (event.keyCode == 40) {
//down //down
let v = +1; let v = 1;
if (_keyctrl || event.ctrlKey || event.metaKey) { if (_keyctrl || event.ctrlKey || event.metaKey) {
v = 5; v = 5;
} }
let y = canvas.getActiveObject().get("top"); const currentCanvas = window.canvas || canvas;
if (currentCanvas && currentCanvas.getActiveObject()) {
let y = currentCanvas.getActiveObject().get('top');
y += v; y += v;
canvas.getActiveObject().set("top", y); currentCanvas.getActiveObject().set('top', y);
canvas.renderAll(); currentCanvas.renderAll();
if (typeof window.recordState === 'function') {
window.recordState(); window.recordState();
} else if (typeof recordState === 'function') {
recordState();
}
if (typeof updateControls === 'function') {
updateControls(); updateControls();
} }
}
}
// 普通删除键(DEL键,没有按CTRL/CMD? // 普通删除键(DEL键,没有按CTRL/CMD?
if (event.keyCode == 46 && !isModifierKey && !_inputEdit && !_textEdit) { if (event.keyCode == 46 && !isModifierKey && !_inputEdit && !_textEdit) {
// 使用 window.canvas 作为后备,确保在 eval() 加载 .jsc 时也能访问 // 使用 window.canvas 作为后备,确保在 eval() 加载 .jsc 时也能访问
const currentCanvas = window.canvas || canvas; const currentCanvas = window.canvas || canvas;
const currentObjs = window.objs || objs; const currentObjs = window.objs || objs;
if (!currentCanvas) { if (!currentCanvas) {
console.error('canvas is undefined in delete handler');
return; return;
} }
let actObjs = currentCanvas.getActiveObjects(); let actObjs = currentCanvas.getActiveObjects();
@@ -189,9 +227,15 @@ $("body").keydown(function (event) {
} }
currentCanvas.discardActiveObject(); currentCanvas.discardActiveObject();
if (flag == 1) { if (flag == 1) {
if (typeof window.recordState === 'function') {
window.recordState(); window.recordState();
canvas.renderAll(); } else if (typeof recordState === 'function') {
handleObjectSelected() recordState();
}
currentCanvas.renderAll();
if (typeof window.handleObjectSelected === 'function') {
window.handleObjectSelected();
}
} }
} }
}); });
@@ -230,7 +274,6 @@ $("#addPic").click(function () {
//canvas.add(image); //canvas.add(image);
}); });
}).catch(err => { }).catch(err => {
console.log(err)
}) })
} }
}); });
@@ -411,9 +454,6 @@ $("#front_side").click(function () {
$("#back_side").removeClass("ui-button-active"); $("#back_side").removeClass("ui-button-active");
$(".canvas-container:eq(0)").show(); $(".canvas-container:eq(0)").show();
$(".canvas-container:eq(1)").hide(); $(".canvas-container:eq(1)").hide();
console.log("------");
console.log(recordObjs1);
console.log("------");
canvas = canvas1; canvas = canvas1;
objs = objs1; objs = objs1;
background_image = background_image1; background_image = background_image1;
@@ -839,7 +879,6 @@ $("#down_obj").click(function () {//下移,放到后?数组中在前面
}); });
$("#set_bg").click(function () {//设置为背? $("#set_bg").click(function () {//设置为背?
let obj = canvas.getActiveObject(); let obj = canvas.getActiveObject();
console.log(obj, obj.get("selectable"))
let idx = getIndex(obj); let idx = getIndex(obj);
const scaleX = 2787 / obj.width const scaleX = 2787 / obj.width
const scaleY = 2787 / obj.height const scaleY = 2787 / obj.height
@@ -890,6 +929,10 @@ $("#previous").click(function () {
// 2. 恢复画布 (使用回调函数) // 2. 恢复画布 (使用回调函数)
canvas.loadFromJSON(recordJson1[step.val], function () { canvas.loadFromJSON(recordJson1[step.val], function () {
// 加载后解锁所有对象(背景除外)
if (typeof window.unlockAllObjects === 'function') {
window.unlockAllObjects(canvas);
}
if (typeof window.onStateRestored === 'function') { if (typeof window.onStateRestored === 'function') {
window.onStateRestored(); // 图片加载完才执行这一行 window.onStateRestored(); // 图片加载完才执行这一行
} }
@@ -920,6 +963,10 @@ $("#next").click(function () {
objs = objs1; objs = objs1;
canvas.loadFromJSON(recordJson1[step.val], function () { canvas.loadFromJSON(recordJson1[step.val], function () {
// 加载后解锁所有对象(背景除外)
if (typeof window.unlockAllObjects === 'function') {
window.unlockAllObjects(canvas);
}
if (typeof window.onStateRestored === 'function') { if (typeof window.onStateRestored === 'function') {
window.onStateRestored(); // 图片加载完才执行这一行 window.onStateRestored(); // 图片加载完才执行这一行
} }
@@ -1162,7 +1209,7 @@ $("#lock").off('click').on('click', function (e) {
let isLocked = obj.get("lockMovementX") === true; let isLocked = obj.get("lockMovementX") === true;
let shouldLock = !isLocked; let shouldLock = !isLocked;
// 锁定/解锁所有编辑操作,锁定后不可选中 // 锁定/解锁所有编辑操作,但保持选中状态(不取消选中
obj.set({ obj.set({
lockMovementX: shouldLock, lockMovementX: shouldLock,
lockMovementY: shouldLock, lockMovementY: shouldLock,
@@ -1171,14 +1218,12 @@ $("#lock").off('click').on('click', function (e) {
lockScalingY: shouldLock, lockScalingY: shouldLock,
lockSkewingX: shouldLock, lockSkewingX: shouldLock,
lockSkewingY: shouldLock, lockSkewingY: shouldLock,
// 锁定时不可选中,解锁时可选中 // 锁定时不可选中,解锁时可选中(但保持当前选中状态)
selectable: !shouldLock, selectable: !shouldLock,
evented: !shouldLock evented: !shouldLock
}); });
if (shouldLock) { if (shouldLock) {
$("#lock_img").attr("src", "public/images/lock20.png")//已锁定//已经上锁,需要解? $("#lock_img").attr("src", "public/images/lock20.png")//已锁定
// 锁定后取消选中
canvas.discardActiveObject();
} else { } else {
$("#lock_img").attr("src", "public/images/unlock20.png")//已解锁 $("#lock_img").attr("src", "public/images/unlock20.png")//已解锁
} }
@@ -1189,7 +1234,6 @@ $("#lock").off('click').on('click', function (e) {
window.updateList(); window.updateList();
} }
canvas.renderAll(); canvas.renderAll();
window.recordState();
}); });
$("#text_back_transparent").click(function () { $("#text_back_transparent").click(function () {
canvas.getActiveObject().set("textBackgroundColor", ""); canvas.getActiveObject().set("textBackgroundColor", "");
@@ -1269,7 +1313,6 @@ function saveAs(op1, callback) {
callback(); callback();
} }
}).catch(err => { }).catch(err => {
console.log()
}) })
} }
// save 函数已在 output.js 中定义 // save 函数已在 output.js 中定义
@@ -1338,11 +1381,8 @@ $("#open").click(function () {
// 调用 output.js 中的 openFile 函数 // 调用 output.js 中的 openFile 函数
if (typeof window.openFile === 'function') { if (typeof window.openFile === 'function') {
window.openFile(filePath); window.openFile(filePath);
} else {
console.error('openFile 函数未定义!');
} }
}).catch(err => { }).catch(err => {
console.log(err)
}) })
} }
}); });
@@ -1379,7 +1419,7 @@ $("#open").click(function () {
canvas2.renderAll(); canvas2.renderAll();
if (typeof window.updateList === 'function') { if (typeof window.updateList === 'function') {
window.updateList(); window.updateList();
} }
$("#new").click(function () { $("#new").click(function () {
if (step.val == 0) { if (step.val == 0) {
ipcRenderer.send('open-first-page'); ipcRenderer.send('open-first-page');
@@ -2127,7 +2167,9 @@ $("#delete").click(function () {
canvas.renderAll(); canvas.renderAll();
} }
}); });
$("#up_obj").click(function () {//上移,放到前面 数组中在后面 // 移至上层和移至下层:先取消所有绑定(包括第一处的绑定),然后重新绑定(确保只绑定一次)
// 注意:第一处的事件绑定(第 842 行和第 861 行)会被这里的 off('click') 取消
$("#up_obj").off('click').on('click', function () {//上移,放到前面 数组中在后面
let idx = getIndex(canvas.getActiveObject()); let idx = getIndex(canvas.getActiveObject());
if (idx + 1 != canvas.getObjects().length) { if (idx + 1 != canvas.getObjects().length) {
canvas.bringForward(canvas.getActiveObject()); canvas.bringForward(canvas.getActiveObject());
@@ -2135,7 +2177,6 @@ $("#up_obj").click(function () {//上移,放到前面 数组中在后面
let temp = objs[idx - 1]; let temp = objs[idx - 1];
objs[idx - 1] = objs[idx]; objs[idx - 1] = objs[idx];
objs[idx] = temp; objs[idx] = temp;
//console.log(objs);
window.recordState(); window.recordState();
if (typeof window.updateList === 'function') { if (typeof window.updateList === 'function') {
@@ -2146,12 +2187,11 @@ $("#up_obj").click(function () {//上移,放到前面 数组中在后面
} }
} }
}); });
$("#down_obj").click(function () {//下移,放到后面 数组中在前面 $("#down_obj").off('click').on('click', function () {//下移,放到后面 数组中在前面
let idx = getIndex(canvas.getActiveObject()); let idx = getIndex(canvas.getActiveObject());
if (idx != 1) { if (idx != 1) {
canvas.sendBackwards(canvas.getActiveObject()); canvas.sendBackwards(canvas.getActiveObject());
canvas.renderAll(); canvas.renderAll();
//[objs[idx-2],objs[idx-1]] = [objs[idx-1],objs[idx-2]];
let temp = objs[idx - 1]; let temp = objs[idx - 1];
objs[idx - 1] = objs[idx - 2]; objs[idx - 1] = objs[idx - 2];
@@ -2167,7 +2207,6 @@ $("#down_obj").click(function () {//下移,放到后面 数组中在前面
}); });
$("#set_bg").click(function () {//设置为背景 $("#set_bg").click(function () {//设置为背景
let obj = canvas.getActiveObject(); let obj = canvas.getActiveObject();
console.log(obj, obj.get("selectable"))
let idx = getIndex(obj); let idx = getIndex(obj);
const scaleX = 2787 / obj.width const scaleX = 2787 / obj.width
const scaleY = 2787 / obj.height const scaleY = 2787 / obj.height
@@ -2284,7 +2323,6 @@ $("#about").click(async function () {
version = "v" + v; // 拼接一个 v,变成 v2.3.017 version = "v" + v; // 拼接一个 v,变成 v2.3.017
} }
} catch (e) { } catch (e) {
console.error("获取版本号失败", e);
} }
// 2. 获取成功后再弹出窗口 // 2. 获取成功后再弹出窗口
@@ -2336,3 +2374,44 @@ $("#output").click(function () {
window.output(null, saveAs); // 调用output函数,使用saveAs进行另存为 window.output(null, saveAs); // 调用output函数,使用saveAs进行另存为
} }
}); });
// 确保移至上层和移至下层的事件绑定正确(在文件末尾再次确认)
// 取消所有绑定,然后重新绑定第二处的实现(第 2171 行和第 2189 行)
$(document).ready(function() {
setTimeout(function() {
$("#up_obj").off('click').on('click', function () {
let idx = getIndex(canvas.getActiveObject());
if (idx + 1 != canvas.getObjects().length) {
canvas.bringForward(canvas.getActiveObject());
canvas.renderAll();
let temp = objs[idx - 1];
objs[idx - 1] = objs[idx];
objs[idx] = temp;
window.recordState();
if (typeof window.updateList === 'function') {
window.updateList();
}
if (typeof window.selectObj === 'function') {
window.selectObj(idx);
}
}
});
$("#down_obj").off('click').on('click', function () {
let idx = getIndex(canvas.getActiveObject());
if (idx != 1) {
canvas.sendBackwards(canvas.getActiveObject());
canvas.renderAll();
let temp = objs[idx - 1];
objs[idx - 1] = objs[idx - 2];
objs[idx - 2] = temp;
window.recordState();
if (typeof window.updateList === 'function') {
window.updateList();
}
if (typeof window.selectObj === 'function') {
window.selectObj(idx - 2);
}
}
});
}, 100);
});
-8
View File
@@ -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 {
+149 -53
View File
@@ -560,16 +560,12 @@ function selectPic(target, index) {
$("#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) {
// 如果是背景图且已锁定,不应该显示图片控件
if (activeObj.get('lockMovementX') === true || activeObj.get('selectable') === false) {
canvas.discardActiveObject(); canvas.discardActiveObject();
canvas.renderAll(); canvas.renderAll();
return; 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));
@@ -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();
$("#circle_text_control").show(); if (!activeObj) return;
$("#circle_text_color").val(canvas.getActiveObject().get("fill"));
$("#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_updating = true; // 设置标志位
circle_text_size.setValue(canvas.getActiveObject().get("fontSize"));
circle_text_size_updating = false; // 清除标志位
} else {
$("#circle_text_size").next().children(".layui-slider-bar").css("width", ((canvas.getActiveObject().get("fontSize") - 10) / (120 - 10)) * 100 + "%");
$("#circle_text_size").next().children(".layui-slider-handle").css("left", ((canvas.getActiveObject().get("fontSize") - 10) / (120 - 10)) * 100 + "%");
}
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter.setValue) {
circle_text_diameter.setValue(canvas.getActiveObject().get("diameter"));
} else {
$("#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_text").val(canvas.getActiveObject().get("text"));
$("#circle_text_font_family").val(canvas.getActiveObject().get("fontFamily"));
if (canvas.getActiveObject().get("underline") == true) { let idx = getIndex(activeObj);
$("#circle_text_control").show();
$("#circle_text_color").val(activeObj.get("fill"));
$("#circle_text_back_color").val(activeObj.get("textBackgroundColor") == "" ? '#ffffff' : activeObj.get("textBackgroundColor"));
if (typeof circle_text_size !== 'undefined' && circle_text_size && typeof circle_text_size.setValue === 'function') {
if (typeof circle_text_size_updating !== 'undefined') {
circle_text_size_updating = true;
}
circle_text_size.setValue(activeObj.get("fontSize") - 10);
if (typeof circle_text_size_updating !== 'undefined') {
circle_text_size_updating = false;
}
}
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter && typeof circle_text_diameter.setValue === 'function') {
circle_text_diameter.setValue(activeObj.get("diameter") - 50);
}
$("#circle_text_center").prop("checked", objs[idx - 1].circleCenter ? 'checked' : '');
$("#circle_text_text").val(activeObj.get("text"));
$("#circle_text_font_family").val(activeObj.get("fontFamily"));
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")
@@ -932,10 +932,8 @@ 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.discardActiveObject();
canvas.renderAll(); 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(); $("#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();
@@ -943,7 +941,6 @@ function handleObjectSelected(e) {
selectObj(-1, true); selectObj(-1, true);
return; 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;
@@ -1102,17 +1164,13 @@ 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, currentCanvas); if (!window._selectingFromList && e.target && isObjectLocked(e.target)) {
if (idx === 0) {
let bgObj = currentCanvas.getObjects()[0];
if (bgObj && (bgObj.get('lockMovementX') === true || bgObj.get('selectable') === false)) {
currentCanvas.discardActiveObject(); currentCanvas.discardActiveObject();
currentCanvas.renderAll(); currentCanvas.renderAll();
return; return;
} }
}
handleObjectSelected(e); handleObjectSelected(e);
// 更新对象列表以同步锁状态 // 更新对象列表以同步锁状态
@@ -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;
@@ -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,14 +2000,18 @@ 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();
if (typeof updateControls === 'function') {
updateControls(); updateControls();
}
if (typeof recordState === 'function') {
recordState(); recordState();
} }
} }
}
}); });
var circle_text_diameter = slider.render({ var circle_text_diameter = slider.render({
@@ -1925,13 +2020,17 @@ 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();
if (typeof updateControls === 'function') {
updateControls(); updateControls();
}
if (typeof recordState === 'function') {
recordState(); recordState();
} }
} }
}
}); });
var out_pic_op = slider.render({ var out_pic_op = slider.render({
@@ -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
View File
@@ -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 对象,确保全局可访问
+111 -743
View File
File diff suppressed because it is too large Load Diff