调整优化
This commit is contained in:
@@ -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
@@ -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
@@ -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 对象,确保全局可访问
|
||||||
|
|||||||
+131
-52
@@ -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)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -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);
|
||||||
|
});
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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 对象,确保全局可访问
|
||||||
|
|||||||
+104
-736
@@ -79,14 +79,14 @@ $('body').keydown(function (event) {
|
|||||||
window.pasteFromClipboard();
|
window.pasteFromClipboard();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// CTRL/CMD+SHIFT+DEL - 清空
|
// CTRL/CMD+SHIFT+DEL (Windows) 或 CMD+SHIFT+Backspace (Mac) - 清空
|
||||||
if (isModifierKey && event.shiftKey && event.keyCode == 46) {
|
if (isModifierKey && event.shiftKey && (event.keyCode == 46 || event.keyCode == 8)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#clean').click();
|
$('#clean').click();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// CTRL/CMD+DEL - 删除
|
// CTRL/CMD+DEL (Windows) 或 CMD+Backspace (Mac) - 删除
|
||||||
if (isModifierKey && !event.shiftKey && event.keyCode == 46) {
|
if (isModifierKey && !event.shiftKey && (event.keyCode == 46 || event.keyCode == 8)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#delete').click();
|
$('#delete').click();
|
||||||
return;
|
return;
|
||||||
@@ -156,17 +156,24 @@ $('body').keydown(function (event) {
|
|||||||
}
|
}
|
||||||
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;
|
||||||
|
}
|
||||||
|
const currentCanvas = window.canvas || canvas;
|
||||||
|
if (currentCanvas && currentCanvas.getActiveObject()) {
|
||||||
|
let y = currentCanvas.getActiveObject().get('top');
|
||||||
|
y += v;
|
||||||
|
currentCanvas.getActiveObject().set('top', y);
|
||||||
|
currentCanvas.renderAll();
|
||||||
|
if (typeof window.recordState === 'function') {
|
||||||
|
window.recordState();
|
||||||
|
} else if (typeof recordState === 'function') {
|
||||||
|
recordState();
|
||||||
|
}
|
||||||
|
if (typeof updateControls === 'function') {
|
||||||
|
updateControls();
|
||||||
}
|
}
|
||||||
if (canvas.getActiveObject()) {
|
|
||||||
let y = canvas.getActiveObject().get('top')
|
|
||||||
y += v
|
|
||||||
canvas.getActiveObject().set('top', y)
|
|
||||||
canvas.renderAll()
|
|
||||||
recordState()
|
|
||||||
updateControls()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 普通删除键(DEL键,没有按CTRL/CMD)
|
// 普通删除键(DEL键,没有按CTRL/CMD)
|
||||||
@@ -175,7 +182,6 @@ $('body').keydown(function (event) {
|
|||||||
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()
|
||||||
@@ -194,10 +200,14 @@ $('body').keydown(function (event) {
|
|||||||
}
|
}
|
||||||
currentCanvas.discardActiveObject()
|
currentCanvas.discardActiveObject()
|
||||||
if (flag == 1) {
|
if (flag == 1) {
|
||||||
recordState()
|
if (typeof window.recordState === 'function') {
|
||||||
canvas.renderAll()
|
window.recordState();
|
||||||
|
} else if (typeof recordState === 'function') {
|
||||||
|
recordState();
|
||||||
|
}
|
||||||
|
currentCanvas.renderAll();
|
||||||
if (typeof window.handleObjectSelected === 'function') {
|
if (typeof window.handleObjectSelected === 'function') {
|
||||||
window.handleObjectSelected()
|
window.handleObjectSelected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -893,7 +903,17 @@ $('#previous').click(function () {
|
|||||||
if ($('#front_side').hasClass('ui-button-active')) {
|
if ($('#front_side').hasClass('ui-button-active')) {
|
||||||
// 使用 recordJson1 和 recordObjs1
|
// 使用 recordJson1 和 recordObjs1
|
||||||
if (recordJson1 && recordJson1[step.val]) {
|
if (recordJson1 && recordJson1[step.val]) {
|
||||||
canvas.loadFromJSON(recordJson1[step.val])
|
canvas.loadFromJSON(recordJson1[step.val], function() {
|
||||||
|
// 加载后解锁所有对象(背景除外)
|
||||||
|
if (typeof window.unlockAllObjects === 'function') {
|
||||||
|
window.unlockAllObjects(canvas);
|
||||||
|
}
|
||||||
|
// 加载后更新列表和图标显示
|
||||||
|
if (typeof window.updateList === 'function') {
|
||||||
|
window.updateList();
|
||||||
|
}
|
||||||
|
canvas.renderAll();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (recordObjs1 && recordObjs1[step.val]) {
|
if (recordObjs1 && recordObjs1[step.val]) {
|
||||||
objs1 = JSON.parse(recordObjs1[step.val])
|
objs1 = JSON.parse(recordObjs1[step.val])
|
||||||
@@ -902,7 +922,17 @@ $('#previous').click(function () {
|
|||||||
} else if ($('#back_side').hasClass('ui-button-active')) {
|
} else if ($('#back_side').hasClass('ui-button-active')) {
|
||||||
// 使用 recordJson2 和 recordObjs2
|
// 使用 recordJson2 和 recordObjs2
|
||||||
if (recordJson2 && recordJson2[step.val]) {
|
if (recordJson2 && recordJson2[step.val]) {
|
||||||
canvas.loadFromJSON(recordJson2[step.val])
|
canvas.loadFromJSON(recordJson2[step.val], function() {
|
||||||
|
// 加载后解锁所有对象(背景除外)
|
||||||
|
if (typeof window.unlockAllObjects === 'function') {
|
||||||
|
window.unlockAllObjects(canvas);
|
||||||
|
}
|
||||||
|
// 加载后更新列表和图标显示
|
||||||
|
if (typeof window.updateList === 'function') {
|
||||||
|
window.updateList();
|
||||||
|
}
|
||||||
|
canvas.renderAll();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (recordObjs2 && recordObjs2[step.val]) {
|
if (recordObjs2 && recordObjs2[step.val]) {
|
||||||
objs2 = JSON.parse(recordObjs2[step.val])
|
objs2 = JSON.parse(recordObjs2[step.val])
|
||||||
@@ -950,7 +980,17 @@ $('#next').click(function () {
|
|||||||
if ($('#front_side').hasClass('ui-button-active')) {
|
if ($('#front_side').hasClass('ui-button-active')) {
|
||||||
// 使用 recordJson1 和 recordObjs1
|
// 使用 recordJson1 和 recordObjs1
|
||||||
if (recordJson1 && recordJson1[step.val]) {
|
if (recordJson1 && recordJson1[step.val]) {
|
||||||
canvas.loadFromJSON(recordJson1[step.val])
|
canvas.loadFromJSON(recordJson1[step.val], function() {
|
||||||
|
// 加载后解锁所有对象(背景除外)
|
||||||
|
if (typeof window.unlockAllObjects === 'function') {
|
||||||
|
window.unlockAllObjects(canvas);
|
||||||
|
}
|
||||||
|
// 加载后更新列表和图标显示
|
||||||
|
if (typeof window.updateList === 'function') {
|
||||||
|
window.updateList();
|
||||||
|
}
|
||||||
|
canvas.renderAll();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (recordObjs1 && recordObjs1[step.val]) {
|
if (recordObjs1 && recordObjs1[step.val]) {
|
||||||
objs1 = JSON.parse(recordObjs1[step.val])
|
objs1 = JSON.parse(recordObjs1[step.val])
|
||||||
@@ -959,7 +999,17 @@ $('#next').click(function () {
|
|||||||
} else if ($('#back_side').hasClass('ui-button-active')) {
|
} else if ($('#back_side').hasClass('ui-button-active')) {
|
||||||
// 使用 recordJson2 和 recordObjs2
|
// 使用 recordJson2 和 recordObjs2
|
||||||
if (recordJson2 && recordJson2[step.val]) {
|
if (recordJson2 && recordJson2[step.val]) {
|
||||||
canvas.loadFromJSON(recordJson2[step.val])
|
canvas.loadFromJSON(recordJson2[step.val], function() {
|
||||||
|
// 加载后解锁所有对象(背景除外)
|
||||||
|
if (typeof window.unlockAllObjects === 'function') {
|
||||||
|
window.unlockAllObjects(canvas);
|
||||||
|
}
|
||||||
|
// 加载后更新列表和图标显示
|
||||||
|
if (typeof window.updateList === 'function') {
|
||||||
|
window.updateList();
|
||||||
|
}
|
||||||
|
canvas.renderAll();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (recordObjs2 && recordObjs2[step.val]) {
|
if (recordObjs2 && recordObjs2[step.val]) {
|
||||||
objs2 = JSON.parse(recordObjs2[step.val])
|
objs2 = JSON.parse(recordObjs2[step.val])
|
||||||
@@ -1200,7 +1250,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,
|
||||||
@@ -1209,29 +1259,23 @@ $('#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();
|
|
||||||
canvas.renderAll();
|
|
||||||
// 锁定后不需要调用 updateControls,因为已经没有选中对象了
|
|
||||||
} else {
|
} else {
|
||||||
$('#lock_img').attr('src', 'public/images/unlock20.png') //已解锁
|
$('#lock_img').attr('src', 'public/images/unlock20.png') //已解锁
|
||||||
// 解锁后更新控件
|
|
||||||
updateControls();
|
|
||||||
}
|
}
|
||||||
|
// 更新控件(保持选中状态,所以可以更新)
|
||||||
|
updateControls();
|
||||||
recordState()
|
recordState()
|
||||||
// 更新对象列表以同步锁状态
|
// 更新对象列表以同步锁状态
|
||||||
if (typeof window.updateList === 'function') {
|
if (typeof window.updateList === 'function') {
|
||||||
window.updateList();
|
window.updateList();
|
||||||
}
|
}
|
||||||
if (!shouldLock) {
|
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
}
|
|
||||||
})
|
})
|
||||||
$('#text_back_transparent').click(function () {
|
$('#text_back_transparent').click(function () {
|
||||||
canvas.getActiveObject().set('textBackgroundColor', '')
|
canvas.getActiveObject().set('textBackgroundColor', '')
|
||||||
@@ -1376,12 +1420,9 @@ $('#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);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1423,7 +1464,8 @@ function addBackground() {
|
|||||||
//pre_objs1.push(JSON.stringify(objs1));
|
//pre_objs1.push(JSON.stringify(objs1));
|
||||||
|
|
||||||
recordObjs1.push(JSON.stringify(objs1))
|
recordObjs1.push(JSON.stringify(objs1))
|
||||||
recordJson1.push(canvas1.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline']))
|
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented'];
|
||||||
|
recordJson1.push(canvas1.toJSON(props))
|
||||||
})
|
})
|
||||||
// 类型改变
|
// 类型改变
|
||||||
fabric.Image.fromURL('./public/images/bg_back_2.png', function (image) {
|
fabric.Image.fromURL('./public/images/bg_back_2.png', function (image) {
|
||||||
@@ -1441,14 +1483,13 @@ function addBackground() {
|
|||||||
//pre_objs2.push(JSON.stringify(objs2));
|
//pre_objs2.push(JSON.stringify(objs2));
|
||||||
|
|
||||||
recordObjs2.push(JSON.stringify(objs2))
|
recordObjs2.push(JSON.stringify(objs2))
|
||||||
recordJson2.push(canvas2.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline']))
|
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented'];
|
||||||
|
recordJson2.push(canvas2.toJSON(props))
|
||||||
|
|
||||||
let file = GetFile().get('file')
|
let file = GetFile().get('file')
|
||||||
if (file && file != 'empty') {
|
if (file && file != 'empty') {
|
||||||
if (typeof window.openFile === 'function') {
|
if (typeof window.openFile === 'function') {
|
||||||
window.openFile(file);
|
window.openFile(file);
|
||||||
} else {
|
|
||||||
console.error('openFile 函数未定义!');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1521,16 +1562,12 @@ function selectPic(target, index) {
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//透明度
|
//透明度
|
||||||
$('#pic_control').show()
|
$('#pic_control').show()
|
||||||
@@ -2128,7 +2165,8 @@ function recordState() {
|
|||||||
}
|
}
|
||||||
//recordObjs.splice(step.val, 1, JSON.stringify(objs))
|
//recordObjs.splice(step.val, 1, JSON.stringify(objs))
|
||||||
recordObjs.push(JSON.stringify(objs))
|
recordObjs.push(JSON.stringify(objs))
|
||||||
j = canvas.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'];
|
||||||
|
j = canvas.toJSON(props)
|
||||||
j.objects[0].hoverCursor = 'default'
|
j.objects[0].hoverCursor = 'default'
|
||||||
recordJson.push(j)
|
recordJson.push(j)
|
||||||
}
|
}
|
||||||
@@ -2698,7 +2736,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. 获取成功后再弹出窗口
|
||||||
@@ -2750,139 +2787,13 @@ $("#output").click(function () {
|
|||||||
window.output(null, saveAs); // 调用output函数,使用saveAs进行另存为
|
window.output(null, saveAs); // 调用output函数,使用saveAs进行另存为
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
function handleObjectSelected() {
|
|
||||||
let select_obj = canvas.getActiveObject()
|
|
||||||
if (!select_obj) {
|
|
||||||
$('#base_control').hide()
|
|
||||||
$('#line_control').hide()
|
|
||||||
$('#pic_control').hide()
|
|
||||||
$('#out_pic_control').hide()
|
|
||||||
$('#text_control').hide()
|
|
||||||
$("#circle_text_control").hide();
|
|
||||||
$('#out_text_control').hide()
|
|
||||||
$('#rect_control').hide()
|
|
||||||
$('#circle_control').hide()
|
|
||||||
$('#counter_control').hide()
|
|
||||||
$('#qrcode_Controll').hide()
|
|
||||||
$('#barcode_controll').hide()
|
|
||||||
$('#component_type').text(language_str('bg')) //comfirm
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果是辅助线,直接返回,不处理
|
|
||||||
if (select_obj.isGuideLine) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = getIndex(select_obj)
|
|
||||||
if (i != 0) {
|
|
||||||
//不是背景
|
|
||||||
--i
|
|
||||||
|
|
||||||
// 安全检查:确保 objs[i] 存在且有 type 属性
|
|
||||||
if (!objs[i] || typeof objs[i].type === 'undefined') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (objs[i].type) {
|
|
||||||
case 1:
|
|
||||||
//console.log("图片");
|
|
||||||
$('#component_type').text(language_str('img')) //"图片"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectPic(select_obj, i)
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
//console.log("预留图片");
|
|
||||||
|
|
||||||
$('#component_type').text(language_str('simg')) //"合成图片"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectOutPic(select_obj, i)
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
$('#component_type').text(language_str('text')) //"文字"
|
|
||||||
//console.log("文字");
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectText(select_obj, i)
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
//console.log("标签");
|
|
||||||
|
|
||||||
$('#component_type').text(language_str('stext')) //"合成文字"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectOutText(select_obj, i)
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
//console.log("矩形");
|
|
||||||
|
|
||||||
$('#component_type').text(language_str('rect')) //"矩形"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectRect(select_obj, i)
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
//console.log("圆形");
|
|
||||||
|
|
||||||
$('#component_type').text(language_str('circ')) //"圆形"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectCircle(select_obj, i)
|
|
||||||
break
|
|
||||||
case 7:
|
|
||||||
//console.log("直线");
|
|
||||||
|
|
||||||
$('#component_type').text(language_str('line')) //"直线"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectLine(select_obj, i)
|
|
||||||
break
|
|
||||||
case 8:
|
|
||||||
//console.log("二维码");
|
|
||||||
|
|
||||||
$('#component_type').text(language_str('qrc')) //"二维码"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectQrCode(select_obj, i)
|
|
||||||
break
|
|
||||||
case 9:
|
|
||||||
//console.log("条形码");
|
|
||||||
|
|
||||||
$('#component_type').text(language_str('barc')) //"条形码"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectBarCode(select_obj, i)
|
|
||||||
break
|
|
||||||
case 10:
|
|
||||||
//console.log("计数器");
|
|
||||||
|
|
||||||
$('#component_type').text(language_str('counter')) //"计数器"
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectCounter(select_obj, i)
|
|
||||||
break
|
|
||||||
case 11:
|
|
||||||
|
|
||||||
$("#component_type").text(language_str("ctext"));//"圆形文字"
|
|
||||||
//console.log("圆形文字");
|
|
||||||
selectObject(select_obj, i);
|
|
||||||
selectCircleText(select_obj, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//背景,收起对象属性
|
|
||||||
$('#base_control').hide()
|
|
||||||
$('#line_control').hide()
|
|
||||||
$('#pic_control').hide()
|
|
||||||
$('#out_pic_control').hide()
|
|
||||||
$('#text_control').hide()
|
|
||||||
$("#circle_text_control").hide();
|
|
||||||
$('#out_text_control').hide()
|
|
||||||
$('#rect_control').hide()
|
|
||||||
$('#circle_control').hide()
|
|
||||||
$('#counter_control').hide()
|
|
||||||
$('#qrcode_Controll').hide()
|
|
||||||
$('#barcode_controll').hide()
|
|
||||||
$('#component_type').text(language_str('bg'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 防止重复初始化事件监听器
|
// 防止重复初始化事件监听器
|
||||||
if (typeof window._design2CanvasEventsInitialized === 'undefined') {
|
if (typeof window._design2CanvasEventsInitialized === 'undefined') {
|
||||||
window._design2CanvasEventsInitialized = true;
|
window._design2CanvasEventsInitialized = true;
|
||||||
|
|
||||||
|
// 所有 canvas 事件已在 core.js 的 initCanvasEvents() 中统一处理,这里不再重复监听
|
||||||
|
// 如果需要 canvas1 特定的 mouse:move 处理,可以在这里添加
|
||||||
canvas1.on('mouse:move', (e) => {
|
canvas1.on('mouse:move', (e) => {
|
||||||
if (!e.pointer || typeof background_image === 'undefined' || !background_image) return;
|
if (!e.pointer || typeof background_image === 'undefined' || !background_image) return;
|
||||||
let width = canvas.getWidth()
|
let width = canvas.getWidth()
|
||||||
@@ -2891,580 +2802,37 @@ if (typeof window._design2CanvasEventsInitialized === 'undefined') {
|
|||||||
'X: ' + (e.pointer.x - (width / 2 - (width / 2 - background_image.left) * zoom)).toFixed(0) + ' Y: ' + (e.pointer.y - (height / 2 - (height / 2 - background_image.top) * zoom)).toFixed(0)
|
'X: ' + (e.pointer.x - (width / 2 - (width / 2 - background_image.left) * zoom)).toFixed(0) + ' Y: ' + (e.pointer.y - (height / 2 - (height / 2 - background_image.top) * zoom)).toFixed(0)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
canvas1.on("object:moving", function (e) {
|
// 注意:以下事件已在 core.js 的 initCanvasEvents() 中统一处理,移除重复监听以避免冲突:
|
||||||
let obj = canvas1.getActiveObject()
|
// - mouse:down (通过 handleObjectSelected 处理)
|
||||||
let idx = getIndex(e.target, canvas1);
|
// - object:scaling, object:rotating, object:rotated
|
||||||
// 添加边界检查,避免访问 undefined
|
// - text:editing:entered, text:editing:exited
|
||||||
if (idx > 0 && idx <= objs1.length && objs1[idx - 1] && objs1[idx - 1].type && objs1[idx - 1].type === 11 && $("#circle_text_center").prop("checked")) {
|
// - object:modified (已在 core.js 中处理)
|
||||||
let pointer = {
|
// - mouse:up (已在 core.js 中处理)
|
||||||
x: obj.left,
|
// 如果需要 canvas1 特定的处理逻辑,请修改 core.js 中的相应函数
|
||||||
y: obj.top
|
|
||||||
}
|
|
||||||
let distance = getDisdance(pointer.x, pointer.y, canvas1.width / 2, canvas1.height / 2)
|
|
||||||
let angleDeg = getDeg(pointer)
|
|
||||||
let flipped = pointer.y > canvas1.height / 2 ? true : false
|
|
||||||
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter.setValue) {
|
|
||||||
circle_text_diameter.setValue(distance * 2 - 50);
|
|
||||||
}
|
|
||||||
obj.set("diameter", distance * 2);
|
|
||||||
obj.set("angle", angleDeg);
|
|
||||||
obj.set("flipped", flipped);
|
|
||||||
}
|
|
||||||
updateControls();
|
|
||||||
});
|
|
||||||
canvas1.on('object:scaling', function (event) {
|
|
||||||
updateControls();
|
|
||||||
})
|
|
||||||
canvas1.on('object:rotating', function (e) {
|
|
||||||
updateControls()
|
|
||||||
})
|
|
||||||
canvas1.on('object:rotated', function (e) {
|
|
||||||
recordState()
|
|
||||||
})
|
|
||||||
canvas1.on('object:added', function (e) {
|
|
||||||
//recordState();
|
|
||||||
})
|
|
||||||
canvas1.on('mouse:down', (e) => {
|
|
||||||
//单选
|
|
||||||
canvas = canvas1;
|
|
||||||
objs = objs1;
|
|
||||||
let select_obj = canvas.getActiveObject()
|
|
||||||
|
|
||||||
// 如果是辅助线,直接返回,不处理
|
// 保留 canvas1 特定的 after:render 处理
|
||||||
if (select_obj && select_obj.isGuideLine) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = getIndex(select_obj, canvas)
|
|
||||||
if (i != 0) {
|
|
||||||
//不是背景
|
|
||||||
--i
|
|
||||||
|
|
||||||
// 安全检查:确保 objs[i] 存在且有 type 属性
|
|
||||||
if (!objs[i] || typeof objs[i].type === 'undefined') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (objs[i].type) {
|
|
||||||
case 1:
|
|
||||||
$('#component_type').text(language_str('img'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectPic(select_obj, i)
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
$('#component_type').text(language_str('simg'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectOutPic(select_obj, i)
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
$('#component_type').text(language_str('text'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectText(select_obj, i)
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
$('#component_type').text(language_str('stext'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectOutText(select_obj, i)
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
$('#component_type').text(language_str('rect'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectRect(select_obj, i)
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
$('#component_type').text(language_str('circ'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectCircle(select_obj, i)
|
|
||||||
break
|
|
||||||
case 7:
|
|
||||||
$('#component_type').text(language_str('line'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectLine(select_obj, i)
|
|
||||||
break
|
|
||||||
case 8:
|
|
||||||
$('#component_type').text(language_str('qrc'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectQrCode(select_obj, i)
|
|
||||||
break
|
|
||||||
case 9:
|
|
||||||
$('#component_type').text(language_str('barc'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectBarCode(select_obj, i)
|
|
||||||
break
|
|
||||||
case 10:
|
|
||||||
$('#component_type').text(language_str('counter'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectCounter(select_obj, i)
|
|
||||||
break
|
|
||||||
case 11:
|
|
||||||
$("#component_type").text(language_str("ctext"));
|
|
||||||
selectObject(select_obj, i);
|
|
||||||
selectCircleText(select_obj, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
selectObj(i, true)
|
|
||||||
} else {
|
|
||||||
//背景,收起对象属性
|
|
||||||
$('#base_control').hide()
|
|
||||||
$('#line_control').hide()
|
|
||||||
$('#pic_control').hide()
|
|
||||||
$('#out_pic_control').hide()
|
|
||||||
$('#text_control').hide()
|
|
||||||
$("#circle_text_control").hide();
|
|
||||||
$('#out_text_control').hide()
|
|
||||||
$('#rect_control').hide()
|
|
||||||
$('#circle_control').hide()
|
|
||||||
$('#qrcode_Controll').hide()
|
|
||||||
$('#barcode_controll').hide()
|
|
||||||
$('#counter_control').hide()
|
|
||||||
selectObj(-1)
|
|
||||||
$('#component_type').text(language_str('bg'))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
canvas1.on('text:editing:entered', function () {
|
|
||||||
_textEdit = true
|
|
||||||
})
|
|
||||||
canvas1.on('text:editing:exited', function () {
|
|
||||||
_textEdit = false
|
|
||||||
})
|
|
||||||
canvas1.on('object:modified', function (event) {
|
|
||||||
if (canvas1.getActiveObjects().length > 1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳过辅助线
|
|
||||||
if (event.target.isGuideLine) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let idx = getIndex(event.target, canvas1);
|
|
||||||
if (idx <= 0) return;
|
|
||||||
|
|
||||||
// 安全检查:确保 objs[idx - 1] 存在且有 type 属性
|
|
||||||
if (!objs[idx - 1] || typeof objs[idx - 1].type === 'undefined') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (objs[idx - 1].type == 3) {
|
|
||||||
event.target.fontSize *= event.target.scaleX
|
|
||||||
event.target.fontSize = event.target.fontSize.toFixed(0)
|
|
||||||
event.target.scaleX = 1
|
|
||||||
event.target.scaleY = 1
|
|
||||||
event.target._clearCache()
|
|
||||||
canvas1.renderAll()
|
|
||||||
updateControls()
|
|
||||||
} else if (objs[idx - 1].type == 4) {
|
|
||||||
event.target.fontSize *= event.target.scaleX
|
|
||||||
event.target.fontSize = event.target.fontSize.toFixed(0)
|
|
||||||
event.target.scaleX = 1
|
|
||||||
event.target.scaleY = 1
|
|
||||||
event.target._clearCache()
|
|
||||||
canvas1.renderAll()
|
|
||||||
} else if (objs[idx - 1].type == 10) {
|
|
||||||
event.target.fontSize *= event.target.scaleX
|
|
||||||
event.target.fontSize = event.target.fontSize.toFixed(0)
|
|
||||||
event.target.scaleX = 1
|
|
||||||
event.target.scaleY = 1
|
|
||||||
event.target._clearCache()
|
|
||||||
canvas1.renderAll()
|
|
||||||
} else if (objs[idx - 1].type == 5) {
|
|
||||||
canvas1.getActiveObject().set('width', canvas1.getActiveObject().get('width') * canvas1.getActiveObject().get('scaleX'))
|
|
||||||
canvas1.getActiveObject().set('height', canvas1.getActiveObject().get('height') * canvas1.getActiveObject().get('scaleY'))
|
|
||||||
canvas1.getActiveObject().set('scaleX', 1)
|
|
||||||
canvas1.getActiveObject().set('scaleY', 1)
|
|
||||||
updateControls()
|
|
||||||
}
|
|
||||||
recordState()
|
|
||||||
})
|
|
||||||
canvas1.on('mouse:up', (e) => {
|
|
||||||
canvas = canvas1;
|
|
||||||
objs = objs1;
|
|
||||||
switch (addState) {
|
|
||||||
case 1:
|
|
||||||
addPic(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addPic').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
addOutPic(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addOutPic').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
addText(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addText').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
addOutText(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addOutText').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
addRect(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addRect').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
addCircle(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addCircle').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 7:
|
|
||||||
addLine(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addLine').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 8:
|
|
||||||
addQrCode(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addQrCode').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 9:
|
|
||||||
addBarCode(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas1.renderAll()
|
|
||||||
$('#addBarCode').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 10:
|
|
||||||
addCounter(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
$('#addCounter').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 11:
|
|
||||||
addCircleText(e.pointer);
|
|
||||||
addState = 0;
|
|
||||||
background_image.hoverCursor = "default";
|
|
||||||
canvas1.renderAll();
|
|
||||||
$("#addCircleText").css("background-color", "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
canvas1.on('text:changed', (e) => {
|
|
||||||
$('#text_text').val(e.target.get('text'))
|
|
||||||
})
|
|
||||||
canvas1.on('after:render', function () {
|
canvas1.on('after:render', function () {
|
||||||
if (is_bgi_add) {
|
if (is_bgi_add) {
|
||||||
var image = document.getElementById('source_front')
|
var image = document.getElementById('source_front')
|
||||||
ctx1.drawImage(image, (canvas.width - $('#source_front').width()) / 2, (canvas.height - $('#source_front').height()) / 2, $('#source_front').width(), $('#source_front').height())
|
ctx1.drawImage(image, (canvas.width - $('#source_front').width()) / 2, (canvas.height - $('#source_front').height()) / 2, $('#source_front').width(), $('#source_front').height())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
canvas2.on('text:editing:entered', function () {
|
// 保留 canvas1 特定的 text:changed 处理
|
||||||
_textEdit = true
|
canvas1.on('text:changed', (e) => {
|
||||||
})
|
$('#text_text').val(e.target.get('text'))
|
||||||
canvas2.on('text:editing:exited', function () {
|
|
||||||
_textEdit = false
|
|
||||||
})
|
})
|
||||||
|
// 保留 canvas2 特定的 after:render 处理
|
||||||
canvas2.on('after:render', function () {
|
canvas2.on('after:render', function () {
|
||||||
if (is_bgi_add) {
|
if (is_bgi_add) {
|
||||||
var image = document.getElementById('source_back')
|
var image = document.getElementById('source_back')
|
||||||
ctx2.drawImage(image, (canvas.width - $('#source_back').width()) / 2, (canvas1.height - $('#source_back').height()) / 2, $('#source_back').width(), $('#source_back').height())
|
ctx2.drawImage(image, (canvas.width - $('#source_back').width()) / 2, (canvas1.height - $('#source_back').height()) / 2, $('#source_back').width(), $('#source_back').height())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
canvas2.on('mouse:move', (e) => {
|
// 注意:以下事件已在 core.js 的 initCanvasEvents() 中统一处理,移除重复监听以避免冲突:
|
||||||
if (!e.pointer || typeof background_image === 'undefined' || !background_image) return;
|
// - mouse:down (通过 handleObjectSelected 处理)
|
||||||
canvas = canvas2;
|
// - mouse:up (已在 core.js 中处理)
|
||||||
objs = objs2;
|
// - object:scaling, object:rotating, object:rotated, object:added
|
||||||
$('#posText').text('X: ' + (e.pointer.x - background_image.left).toFixed(0) + ' Y: ' + (e.pointer.y - background_image.top).toFixed(0))
|
// - text:editing:entered, text:editing:exited
|
||||||
})
|
// - object:modified (已在 core.js 中处理)
|
||||||
canvas2.on("object:moving", function (e) {
|
// 如果需要 canvas2 特定的处理逻辑,请修改 core.js 中的相应函数
|
||||||
canvas = canvas2;
|
|
||||||
objs = objs2;
|
|
||||||
let obj = canvas2.getActiveObject()
|
|
||||||
let idx = getIndex(e.target, canvas2);
|
|
||||||
// 添加边界检查,避免访问 undefined
|
|
||||||
if (idx > 0 && idx <= objs2.length && objs2[idx - 1] && objs2[idx - 1].type && objs2[idx - 1].type === 11 && $("#circle_text_center").prop("checked")) {
|
|
||||||
let pointer = {
|
|
||||||
x: obj.left,
|
|
||||||
y: obj.top
|
|
||||||
}
|
|
||||||
let distance = getDisdance(pointer.x, pointer.y, canvas2.width / 2, canvas2.height / 2)
|
|
||||||
// 计算角度时需要使用 canvas2
|
|
||||||
let centerX = canvas2.width / 2;
|
|
||||||
let centerY = canvas2.height / 2;
|
|
||||||
let mouseX = pointer.x;
|
|
||||||
let mouseY = pointer.y;
|
|
||||||
let dx = mouseX - centerX;
|
|
||||||
let dy = mouseY - centerY;
|
|
||||||
let angleRad = Math.atan2(dy, dx);
|
|
||||||
let angleDeg = angleRad * (180 / Math.PI);
|
|
||||||
if (angleDeg < 0) {
|
|
||||||
angleDeg += 360;
|
|
||||||
}
|
|
||||||
angleDeg += 90;
|
|
||||||
let flipped = pointer.y > canvas2.height / 2 ? true : false
|
|
||||||
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter.setValue) {
|
|
||||||
circle_text_diameter.setValue(distance * 2 - 50);
|
|
||||||
}
|
|
||||||
obj.set("diameter", distance * 2);
|
|
||||||
obj.set("angle", angleDeg);
|
|
||||||
obj.set("flipped", flipped);
|
|
||||||
}
|
|
||||||
updateControls();
|
|
||||||
});
|
|
||||||
canvas2.on('object:scaling', function (e) {
|
|
||||||
canvas = canvas2;
|
|
||||||
objs = objs2;
|
|
||||||
updateControls()
|
|
||||||
})
|
|
||||||
canvas2.on('object:rotating', function (e) {
|
|
||||||
canvas = canvas2;
|
|
||||||
objs = objs2;
|
|
||||||
updateControls()
|
|
||||||
})
|
|
||||||
canvas2.on('object:rotated', function (e) {
|
|
||||||
canvas = canvas2;
|
|
||||||
objs = objs2;
|
|
||||||
recordState()
|
|
||||||
})
|
|
||||||
canvas2.on('object:added', function (e) {
|
|
||||||
//recordState();
|
|
||||||
})
|
|
||||||
canvas2.on('mouse:down', (e) => {
|
|
||||||
//单选
|
|
||||||
canvas = canvas2;
|
|
||||||
objs = objs2;
|
|
||||||
let select_obj = canvas.getActiveObject()
|
|
||||||
|
|
||||||
// 如果是辅助线,直接返回,不处理
|
|
||||||
if (select_obj && select_obj.isGuideLine) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = getIndex(select_obj, canvas)
|
|
||||||
if (i != 0) {
|
|
||||||
//不是背景
|
|
||||||
--i
|
|
||||||
|
|
||||||
// 安全检查:确保 objs[i] 存在且有 type 属性
|
|
||||||
if (!objs[i] || typeof objs[i].type === 'undefined') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (objs[i].type) {
|
|
||||||
case 1:
|
|
||||||
$('#component_type').text(language_str('img'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectPic(select_obj, i)
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
$('#component_type').text(language_str('simg'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectOutPic(select_obj, i)
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
$('#component_type').text(language_str('text'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectText(select_obj, i)
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
$('#component_type').text(language_str('stext'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectOutText(select_obj, i)
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
$('#component_type').text(language_str('rect'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectRect(select_obj, i)
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
$('#component_type').text(language_str('circ'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectCircle(select_obj, i)
|
|
||||||
break
|
|
||||||
case 7:
|
|
||||||
$('#component_type').text(language_str('line'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectLine(select_obj, i)
|
|
||||||
break
|
|
||||||
case 8:
|
|
||||||
$('#component_type').text(language_str('qrc'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectQrCode(select_obj, i)
|
|
||||||
break
|
|
||||||
case 9:
|
|
||||||
$('#component_type').text(language_str('barc'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectBarCode(select_obj, i)
|
|
||||||
break
|
|
||||||
case 10:
|
|
||||||
$('#component_type').text(language_str('counter'))
|
|
||||||
selectObject(select_obj, i)
|
|
||||||
selectCounter(select_obj, i)
|
|
||||||
break
|
|
||||||
case 11:
|
|
||||||
$("#component_type").text(language_str("ctext"));
|
|
||||||
selectObject(select_obj, i);
|
|
||||||
selectCircleText(select_obj, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
selectObj(i, true)
|
|
||||||
} else {
|
|
||||||
//背景,收起对象属性
|
|
||||||
$('#base_control').hide()
|
|
||||||
$('#line_control').hide()
|
|
||||||
$('#pic_control').hide()
|
|
||||||
$('#out_pic_control').hide()
|
|
||||||
$('#text_control').hide()
|
|
||||||
$("#circle_text_control").hide();
|
|
||||||
$('#out_text_control').hide()
|
|
||||||
$('#rect_control').hide()
|
|
||||||
$('#circle_control').hide()
|
|
||||||
$('#qrcode_Controll').hide()
|
|
||||||
$('#barcode_controll').hide()
|
|
||||||
$('#counter_control').hide()
|
|
||||||
selectObj(-1)
|
|
||||||
$('#component_type').text(language_str('bg'))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
canvas2.on('object:modified', function (event) {
|
|
||||||
canvas = canvas2;
|
|
||||||
objs = objs2;
|
|
||||||
if (canvas.getActiveObjects().length > 1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳过辅助线
|
|
||||||
if (event.target.isGuideLine) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let idx = getIndex(event.target, canvas2);
|
|
||||||
if (idx <= 0) return;
|
|
||||||
|
|
||||||
// 安全检查:确保 objs[idx - 1] 存在且有 type 属性
|
|
||||||
if (!objs[idx - 1] || typeof objs[idx - 1].type === 'undefined') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (objs[idx - 1].type == 3) {
|
|
||||||
event.target.fontSize *= event.target.scaleX
|
|
||||||
event.target.fontSize = event.target.fontSize.toFixed(0)
|
|
||||||
event.target.scaleX = 1
|
|
||||||
event.target.scaleY = 1
|
|
||||||
event.target._clearCache()
|
|
||||||
canvas2.renderAll()
|
|
||||||
} else if (objs[idx - 1].type == 4) {
|
|
||||||
event.target.fontSize *= event.target.scaleX
|
|
||||||
event.target.fontSize = event.target.fontSize.toFixed(0)
|
|
||||||
event.target.scaleX = 1
|
|
||||||
event.target.scaleY = 1
|
|
||||||
event.target._clearCache()
|
|
||||||
canvas2.renderAll()
|
|
||||||
} else if (objs[idx - 1].type == 10) {
|
|
||||||
event.target.fontSize *= event.target.scaleX
|
|
||||||
event.target.fontSize = event.target.fontSize.toFixed(0)
|
|
||||||
event.target.scaleX = 1
|
|
||||||
event.target.scaleY = 1
|
|
||||||
event.target._clearCache()
|
|
||||||
canvas2.renderAll()
|
|
||||||
} else if (objs[idx - 1].type == 5) {
|
|
||||||
canvas2.getActiveObject().set('width', canvas2.getActiveObject().get('width') * canvas2.getActiveObject().get('scaleX'))
|
|
||||||
canvas2.getActiveObject().set('height', canvas2.getActiveObject().get('height') * canvas2.getActiveObject().get('scaleY'))
|
|
||||||
canvas2.getActiveObject().set('scaleX', 1)
|
|
||||||
canvas2.getActiveObject().set('scaleY', 1)
|
|
||||||
updateControls()
|
|
||||||
}
|
|
||||||
recordState()
|
|
||||||
})
|
|
||||||
canvas2.on('mouse:up', (e) => {
|
|
||||||
canvas = canvas2;
|
|
||||||
objs = objs2;
|
|
||||||
switch (addState) {
|
|
||||||
case 1:
|
|
||||||
addPic(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addPic').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
addOutPic(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addOutPic').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
addText(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addText').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
addOutText(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addOutText').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
addRect(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addRect').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
addCircle(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addCircle').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 7:
|
|
||||||
addLine(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addLine').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 8:
|
|
||||||
addQrCode(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addQrCode').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 9:
|
|
||||||
addBarCode(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
canvas2.renderAll()
|
|
||||||
$('#addBarCode').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 10:
|
|
||||||
addCounter(e.pointer)
|
|
||||||
addState = 0
|
|
||||||
background_image.hoverCursor = 'default'
|
|
||||||
$('#addCounter').css('background-color', '')
|
|
||||||
break
|
|
||||||
case 11:
|
|
||||||
addCircleText(e.pointer);
|
|
||||||
addState = 0;
|
|
||||||
background_image.hoverCursor = "default";
|
|
||||||
canvas2.renderAll();
|
|
||||||
$("#addCircleText").css("background-color", "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user