diff --git a/src/component/Canvas/CanvasEditor/commands/LayerCommands.js b/src/component/Canvas/CanvasEditor/commands/LayerCommands.js index 66880184..0380638e 100644 --- a/src/component/Canvas/CanvasEditor/commands/LayerCommands.js +++ b/src/component/Canvas/CanvasEditor/commands/LayerCommands.js @@ -2595,7 +2595,7 @@ export class CreateImageLayerCommand extends Command { // 生成图层名称 const fileName = - this.layerName || `图片 ${new Date().toLocaleTimeString()}`; + this.layerName || `${new Date().toLocaleString()}`; this.fabricImage.set({ id: this.imageId, diff --git a/src/component/Canvas/CanvasEditor/components/SelectMenuPanel.vue b/src/component/Canvas/CanvasEditor/components/SelectMenuPanel.vue index e5396c59..d02015c8 100644 --- a/src/component/Canvas/CanvasEditor/components/SelectMenuPanel.vue +++ b/src/component/Canvas/CanvasEditor/components/SelectMenuPanel.vue @@ -22,7 +22,7 @@ v-for="v in activeObjects" :key="v.id" > -
图层1
+
{{ v.layer?.name }}
W @@ -53,16 +53,20 @@
-

水平翻转

+

+ {{ t("Canvas.flipHorizontal") }} +

-

垂直翻转

+

+ {{ t("Canvas.flipVertical") }} +

@@ -158,6 +162,9 @@ const getActiveObject = (e) => { console.log("==========切换激活对象", e); activeObjects.value = e.selected.map((v) => v); + activeObjects.value.forEach((v) => { + v.layer = props.layerManager.getLayerById(v.layerId); + }); if (activeObjects.value.length === 0) { close(); } else { @@ -166,46 +173,11 @@ }; const lastSelectLayerId = inject("lastSelectLayerId"); const layers = inject("layers"); - const changeAngle = (activeObj) => { - // console.log("=====================", e.target.value); - // const finalState = TransformCommand.captureTransformState(activeObj); - // const { xPrime, yPrime } = compute( - // activeObj.left, - // activeObj.top, - // activeObj.width, - // activeObj.height, - // activeObj.angle - // ); - // finalState.left = xPrime; - // finalState.top = yPrime; - // const transformCmd = new TransformCommand({ - // canvas: props.canvas, - // objectId: activeObj.id, - // initialState: null, - // finalState, - // objectType: activeObj.type, - // name: `变换 ${activeObj.type || "对象"}`, - // layerManager: props.layerManager, - // layers: layers, - // lastSelectLayerId: lastSelectLayerId, - // }); - // props.layerManager.commandManager.execute(transformCmd, { - // name: "对象修改", - // }); - }; - - const flipObject = (activeObj, type) => { - const initialState = TransformCommand.captureTransformState(activeObj); - const finalState = { ...initialState }; - if (type === "h") { - finalState.flipX = !finalState.flipX; - } else if (type === "v") { - finalState.flipY = !finalState.flipY; - } + const transformObject = (activeObj, initialState, finalState) => { const transformCmd = new TransformCommand({ canvas: props.canvas, objectId: activeObj.id, - initialState: initialState, + initialState, finalState, objectType: activeObj.type, name: `变换 ${activeObj.type || "对象"}`, @@ -217,20 +189,90 @@ name: "对象修改", }); }; - const clickflipHorizontal = (obj) => { - console.log("水平翻转"); - flipObject(obj, "h"); + + /** + * 根据左上角坐标计算旋转后的新坐标 + * @param {number} W - 宽度 + * @param {number} H - 高度 + * @param {number} currentX - 当前左上角x坐标 + * @param {number} currentY - 当前左上角y坐标 + * @param {number} currentAngleDeg - 当前角度(度) + * @param {number} newAngleDeg - 新角度(度) + * @returns {Object} 旋转后的左上角坐标 {x, y} + */ + function calculateRotatedTopLeftDeg( + W, + H, + currentX, + currentY, + currentAngleDeg, + newAngleDeg + ) { + const currentAngle = (currentAngleDeg * Math.PI) / 180; + const newAngle = (newAngleDeg * Math.PI) / 180; + // 1. 用当前角度计算中心点位置 + const cosCurrent = Math.cos(currentAngle); + const sinCurrent = Math.sin(currentAngle); + const Cx = currentX + (W / 2) * cosCurrent - (H / 2) * sinCurrent; + const Cy = currentY + (W / 2) * sinCurrent + (H / 2) * cosCurrent; + + // 2. 用新角度计算旋转后的左上角位置 + const cosNew = Math.cos(newAngle); + const sinNew = Math.sin(newAngle); + const newX = Cx + (-W / 2) * cosNew - (-H / 2) * sinNew; + const newY = Cy + (-W / 2) * sinNew + (-H / 2) * cosNew; + + return { x: newX, y: newY }; + } + // 改变角度 + const changeAngle = (e, obj) => { + const initialState = TransformCommand.captureTransformState(obj); + const finalState = { ...initialState }; + const angle = e.target.value; + if (obj.originX === "left" && obj.originY === "top") { + const width = obj.width * obj.scaleX; + const height = obj.height * obj.scaleY; + const left = obj.left; + const top = obj.top; + const { x, y } = calculateRotatedTopLeftDeg( + width, + height, + left, + top, + obj.angle, + angle + ); + finalState.left = x; + finalState.top = y; + } + finalState.angle = angle; + transformObject(obj, initialState, finalState); }; + // 水平翻转 + const clickflipHorizontal = (obj) => { + const initialState = TransformCommand.captureTransformState(obj); + const finalState = { ...initialState }; + finalState.flipX = !finalState.flipX; + transformObject(obj, initialState, finalState); + }; + // 垂直翻转 const clickflipVertical = (obj) => { - console.log("垂直翻转"); - flipObject(obj, "v"); + const initialState = TransformCommand.captureTransformState(obj); + const finalState = { ...initialState }; + finalState.flipY = !finalState.flipY; + transformObject(obj, initialState, finalState); }; const updateActiveObjects = (arrs, keys) => { arrs.forEach((v) => { activeObjects.value.forEach((item) => { if (item.id === v.id) { - keys.forEach((key) => (item[key] = v[key])); + keys.forEach((k) => { + item[k] = + typeof v[k] === "number" + ? Number(v[k].toFixed(3)) + : v[k]; + }); } }); activeObjects.value = [...activeObjects.value]; diff --git a/src/component/Canvas/CanvasEditor/managers/LayerManager.js b/src/component/Canvas/CanvasEditor/managers/LayerManager.js index c2fe3941..e70a6b70 100644 --- a/src/component/Canvas/CanvasEditor/managers/LayerManager.js +++ b/src/component/Canvas/CanvasEditor/managers/LayerManager.js @@ -1219,6 +1219,10 @@ export class LayerManager { } // 切换到选择模式 this?.toolManager?.setTool(OperationType.SELECT); + if(objects.length === 1) { + this.canvas.setActiveObject(objects[0]); + return objects[0]; + } // 创建一个新的活动选择组 const activeSelection = new fabric.ActiveSelection(objects, { canvas: this.canvas, diff --git a/src/component/Canvas/ExistsImageList/index.vue b/src/component/Canvas/ExistsImageList/index.vue index d1aaab6c..2f18de34 100644 --- a/src/component/Canvas/ExistsImageList/index.vue +++ b/src/component/Canvas/ExistsImageList/index.vue @@ -44,16 +44,17 @@ :key="index" class="image-item" @click="handleImageClick(item)" + @dblclick="handleImageDoubleClick(item)" >
- {{ item.name || "未命名" }} + {{ item.name }}
-

加载中...

@@ -279,6 +279,14 @@ const handleImageClick = item => { } } +// 处理图片双击 +const handleImageDoubleClick = item => { + selectList.value = [item.url] + confirm() +} + + + // 处理分类切换 const handleChangeCategory = category => { // console.log('handleChangeCategory',category) @@ -307,6 +315,7 @@ const confirm = () => { emitData = selectList.value } emits('select', emitData) + selectList.value = [] showPanel.value = false } diff --git a/src/lang/cn.ts b/src/lang/cn.ts index 8cc1cddc..71224767 100644 --- a/src/lang/cn.ts +++ b/src/lang/cn.ts @@ -1217,6 +1217,8 @@ export default { Rough: '粗糙', Smooth: '平滑', basic: '基础', + flipHorizontal: '水平翻转', + flipVertical: '垂直翻转', //长毛笔 FurSettings: '长毛笔设置', FurLength: '毛发长度', diff --git a/src/lang/en.ts b/src/lang/en.ts index 013326c6..054b3b13 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -1252,6 +1252,8 @@ export default { Rough: 'Rough', Smooth: 'Smooth', basic: 'Basic', + flipHorizontal: 'Horizontal Flip', + flipVertical: 'Vertical Flip', //长毛笔 FurSettings: 'FurSettings', FurLength: 'Fur Length', diff --git a/src/views/HomeView/history.vue b/src/views/HomeView/history.vue index 4b30f338..38a4b3f5 100644 --- a/src/views/HomeView/history.vue +++ b/src/views/HomeView/history.vue @@ -771,7 +771,7 @@ export default defineComponent({ padding: 0 1rem; .operate_item { - font-size: 1.4rem; + // font-size: 1.4rem; font-family: Roboto; font-weight: 400; color: #007ee5;