调整优化

This commit is contained in:
24kycj
2025-12-15 02:55:54 +08:00
parent 50ff0d347a
commit 3c4080f3f1
8 changed files with 3048 additions and 3407 deletions
+126 -36
View File
@@ -280,7 +280,6 @@ var zoomSlider = slider.render({
max: 500,
value: 100,
change(val) {
console.log(val, zoomSlider)
canvas.zoomToPoint(
new fabric.Point(0, 0),
val / 100
@@ -379,7 +378,7 @@ function addBackground() {
//pre_json1.push(canvas1.toJSON(["selectable","hoverable","hoverCursor"]));
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) {
@@ -399,7 +398,7 @@ function addBackground() {
//pre_json2.push(canvas2.toJSON(["selectable","hoverable","hoverCursor"]));
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')
if (file && file != 'empty') {
@@ -663,18 +662,25 @@ function addCircleText(pointer) {
window.recordState();
}
function selectCircleText(target, index) {
function selectCircleText() {
// 检查是否有选中对象
if (!canvas || !canvas.getActiveObject()) return;
let idx = getIndex(canvas.getActiveObject());
$("#circle_text_control").show();
$("#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 是否存在且有 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);
} 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-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);
} else {
$("#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 + "%");
}
let a = canvas.getActiveObject().getCoords();
console.log(getCoordsMinX(a));
$("#pic_control").hide();
$("#set_bg").hide();
$("#out_pic_control").hide();
@@ -1045,7 +1050,6 @@ function addCounter(pointer) {
canvas.renderAll();
updateList();
window.recordState();
console.log(canvas.getObjects())
}
function selectCounter(target, index) {
@@ -1126,7 +1130,7 @@ window.updateList = function updateList() {
const lockIcon = isLocked ?
'<img src="public/images/lock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.7;" title="已锁定">' :
'<img src="public/images/unlock20.png" style="width:14px; height:14px; margin-left:5px; opacity:0.5;" title="未锁定">';
// 组装 HTML
str = `<div style="${rowStyle}">
<div style="${leftStyle}">
@@ -1151,6 +1155,9 @@ window.updateList = function updateList() {
}
// 将 selectObj 附加到 window 对象,确保全局可访问
// 标记是否通过对象列表选中(用于区分鼠标点击和列表点击)
window._selectingFromList = false;
window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
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)) {
$(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) {
@@ -1188,15 +1185,39 @@ window.selectObj = function selectObj(objIndices, isFromCanvas = false) {
if (!isFromCanvas && indicesArray.length === 1) {
let target = canvas.getObjects()[indicesArray[0] + 1];
if (target) {
// 如果对象被锁定,临时允许选中以便解锁
if (target.get('lockMovementX') === true) {
// 检查对象是否被锁定
let isLocked = isObjectLocked(target);
// 设置标志位,表示这是通过对象列表选中的(无论是否锁定)
window._selectingFromList = true;
// 如果被锁定,临时设置 selectable 和 evented 为 true,以便能够选中
if (isLocked) {
target.set({
selectable: true,
evented: true
})
});
}
canvas.setActiveObject(target);
canvas.requestRenderAll();
// 如果对象被锁定,选中后立即恢复锁定状态(但保持选中状态)
if (isLocked) {
setTimeout(() => {
target.set({
selectable: false,
evented: false
});
canvas.requestRenderAll();
}, 0);
}
// 清除标志位(延迟清除,确保事件处理完成)
setTimeout(() => {
window._selectingFromList = false;
}, 10);
handleObjectSelected();
}
}
@@ -1217,7 +1238,7 @@ window.recordState = function recordState() {
//recordObjs.splice(step.val, 1, JSON.stringify(objs))
//recordJson.splice(step.val, 1, canvas.toJSON(["selectable","hoverable","hoverCursor","text","fontStyle","fontWeight","underline"]))
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";
recordJson.push(j);
}
@@ -1228,7 +1249,6 @@ window.getIndex = function getIndex(target, _canvas = null) {
// 使用 window.canvas 作为默认值,确保在 eval() 执行时也能访问
const currentCanvas = _canvas || window.canvas || canvas;
if (!currentCanvas) {
console.error('getIndex: canvas is undefined');
return 0;
}
temp_objs = currentCanvas.getObjects();
@@ -1377,6 +1397,16 @@ function handleObjectSelected(e) {
// 2. 获取索引
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) {
// --- 选中了普通对象 ---
@@ -1450,6 +1480,61 @@ function handleObjectMoving(e) {
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 对象,确保全局可访问
window.handleObjectSelected = handleObjectSelected;
@@ -1489,6 +1574,17 @@ function initCanvasEvents() {
objs = (currentCanvas === canvas1) ? objs1 : objs2;
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 事件以确保对象选中时正确显示属性面板
currentCanvas.on('selection:created', (e) => {
canvas = currentCanvas;
@@ -1504,16 +1600,12 @@ function initCanvasEvents() {
canvas = currentCanvas;
objs = (currentCanvas === canvas1) ? objs1 : objs2;
// 阻止背景图(索引0)被选中(如果已锁定)
let selectedObj = e.target;
let idx = getIndex(selectedObj);
if (idx === 0) {
let bgObj = currentCanvas.getObjects()[0];
if (bgObj && (bgObj.get('lockMovementX') === true || bgObj.get('selectable') === false)) {
currentCanvas.discardActiveObject();
currentCanvas.renderAll();
return;
}
// 如果不是通过对象列表选中的,且对象被锁定,则取消选中
// 注意:只有真正被锁定的对象才会被取消选中,未锁定的对象应该正常选中
if (!window._selectingFromList && e.target && isObjectLocked(e.target)) {
currentCanvas.discardActiveObject();
currentCanvas.renderAll();
return;
}
handleObjectSelected(e);
@@ -1582,7 +1674,6 @@ function initCanvasEvents() {
if (typeof window.updateList === 'function') {
window.updateList();
}
console.warn('objData is undefined or missing type at index', idx - 1);
return;
}
let target = event.target;
@@ -2081,7 +2172,6 @@ window.copySelection = function copySelection() {
});
clipboardData.offset = 10; // 重置偏移量
console.log(`已复制 ${activeObjects.length} 个对象`);
layer.msg("已复制");
}