Browse Source

feat(mt-edit): 适配系统快捷键并支持文本对齐

- 根据平台显示并识别 Cmd/Ctrl 快捷键
- 更新画布选择、复制粘贴、撤销重做、层级调整等快捷键逻辑
- 为文本组件新增 textAlign 配置和渲染样式
- 新增流程示例图片资源
Zimo 4 ngày trước cách đây
mục cha
commit
dfd77c7507

BIN
src/assets/images/process-demo/关闭阀门.png


BIN
src/assets/images/process-demo/开启阀门.png


BIN
src/assets/images/process-demo/流量计1.png


BIN
src/assets/images/process-demo/温度计.png


BIN
src/assets/images/process-demo/纯度计.png


BIN
src/assets/images/process-demo/罐.png


BIN
src/assets/images/process-demo/罐1.png


BIN
src/assets/images/process-demo/过滤器1.png


BIN
src/assets/images/process-demo/阀门2.png


+ 6 - 1
src/components/custom-components/text-vue/index.vue

@@ -6,7 +6,8 @@
       fontFamily: props.fontFamily,
       fontSize: props.fontSize + 'px',
       color: props.fill,
-      fontWeight: props.bold ? 'bold' : 'normal'
+      fontWeight: props.bold ? 'bold' : 'normal',
+      textAlign: props.textAlign
     }">
     {{ props.text }}
   </p>
@@ -36,6 +37,10 @@ const props = defineProps({
   bold: {
     type: Boolean,
     default: false
+  },
+  textAlign: {
+    type: String,
+    default: 'left'
   }
 })
 </script>

+ 4 - 2
src/components/mt-edit/components/draw-line-render/index.vue

@@ -95,7 +95,7 @@
 <script setup lang="ts">
 import type { MouseTouchEvent } from '@/components/mt-dzr/utils/types'
 import type { IDoneJson, IGlobalStoreCanvasCfg, IGlobalStoreGridCfg } from '../../store/types'
-import { alignToGrid, positionArrarToPath } from '@/components/mt-edit/utils'
+import { alignToGrid, isSystemShortcutKey, positionArrarToPath } from '@/components/mt-edit/utils'
 import { computed } from 'vue'
 import { configStore } from '../../store/config'
 type LineRenderProps = {
@@ -132,7 +132,9 @@ const onMouseDown = (de: MouseTouchEvent, point_index: number, item: { x: number
     const m_x = e instanceof MouseEvent ? e.clientX : e.touches[0].pageX
     const m_y = e instanceof MouseEvent ? e.clientY : e.touches[0].pageY
     // 移动的距离
-    const move_x = de.ctrlKey ? 0 : alignToGrid((m_x - d_x) / lineRenderProps.canvasCfg.scale, 1) //感觉对齐网格有点体验不好 所以固定为一了
+    const move_x = isSystemShortcutKey(de)
+      ? 0
+      : alignToGrid((m_x - d_x) / lineRenderProps.canvasCfg.scale, 1) //感觉对齐网格有点体验不好 所以固定为一了
     const move_y = de.shiftKey ? 0 : alignToGrid((m_y - d_y) / lineRenderProps.canvasCfg.scale, 1)
     new_x = realityX + move_x
     new_y = realityY + move_y

+ 4 - 2
src/components/mt-edit/components/layout/header-panel/index.vue

@@ -30,7 +30,7 @@
             size="small"
             :disabled="!headerPanelProps.undoEnabled"
             @click="emits('onUndoClick')">
-            <el-icon title="撤销 Ctrl+Z" :size="20">
+            <el-icon :title="`撤销 ${systemShortcutKey}+Z`" :size="20">
               <svg-analysis name="undo" />
             </el-icon>
           </el-button>
@@ -40,7 +40,7 @@
             size="small"
             :disabled="!headerPanelProps.redoEnabled"
             @click="emits('onRedoClick')">
-            <el-icon title="重做 Ctrl+Y" :size="20">
+            <el-icon :title="`重做 ${systemShortcutKey}+Y`" :size="20">
               <svg-analysis name="redo" />
             </el-icon>
           </el-button>
@@ -257,6 +257,7 @@ import {
 import SvgAnalysis from '@/components/mt-edit/components/svg-analysis/index.vue'
 import type { IRealTimeData } from '@/components/mt-edit/store/types'
 import deepOilLogo from '@/assets/imgs/logo.png'
+import { getSystemShortcutKeyName } from '@/components/mt-edit/utils'
 import { ref } from 'vue'
 type HeaderPanelProps = {
   leftAside: boolean
@@ -305,6 +306,7 @@ const { isFullscreen, toggle } = useFullscreen()
 const toggleDark = useToggle(isDark)
 const drawline_selected = ref(false)
 const is_npm_env = ref(import.meta.env.MODE === 'npm')
+const systemShortcutKey = getSystemShortcutKeyName()
 const onGroupClick = () => {
   emits('onGroupClick')
 }

+ 18 - 15
src/components/mt-edit/components/layout/main-panel/index.vue

@@ -88,7 +88,8 @@ import {
   rotatePoint,
   getRectCoordinate,
   getRectCenterCoordinate,
-  handleAlign
+  handleAlign,
+  isSystemShortcutKey
 } from '@/components/mt-edit/utils'
 import type {
   AdsorbPointType,
@@ -300,14 +301,15 @@ const onRenderCoreMouseDown = (item: IDoneJson, e: MouseEvent) => {
       })
     cacheStore.setBoundingBox(allBoundingInfo)
   }
-  if (!e.ctrlKey) {
+  const system_shortcut_pressed = isSystemShortcutKey(e)
+  if (!system_shortcut_pressed) {
     // 如果当前id已经是选中状态了 则不需要取消其它组件的激活状态 也不需要重复设置选中状态
     if (globalStore.selected_items_id.includes(item.id)) {
       return
     }
     //将除了选中id的图形全部设置为非选中
     globalStore.setSingleSelect(item.id)
-  } else if (e.ctrlKey && !item.lock) {
+  } else if (system_shortcut_pressed && !item.lock) {
     const find_item = globalStore.done_json.find((f) => f.id == item.id)!
     find_item.active = !find_item.active
     globalStore.refreshSelectedItemsId()
@@ -1033,18 +1035,19 @@ const onContextMenuClick = (key: ContextMenuInfoType, e: MouseEvent) => {
   globalStore.setIntention('none')
 }
 const onKeydown = (e: KeyboardEvent) => {
+  const system_shortcut_pressed = isSystemShortcutKey(e)
   // 全选
-  if (e.ctrlKey && e.key.toLocaleLowerCase() === 'a') {
+  if (system_shortcut_pressed && e.key.toLocaleLowerCase() === 'a') {
     e.preventDefault()
     onContextMenuSelectAll()
   }
   //复制
-  else if (e.ctrlKey && e.key.toLocaleLowerCase() === 'c') {
+  else if (system_shortcut_pressed && e.key.toLocaleLowerCase() === 'c') {
     e.preventDefault()
     onContextMenuCopy()
   }
   //粘贴
-  else if (e.ctrlKey && e.key.toLocaleLowerCase() === 'v') {
+  else if (system_shortcut_pressed && e.key.toLocaleLowerCase() === 'v') {
     e.preventDefault()
     onContextMenuPaste(10, 10)
   }
@@ -1054,42 +1057,42 @@ const onKeydown = (e: KeyboardEvent) => {
     onContextMenuDelete()
   }
   //组合
-  else if (e.ctrlKey && e.key.toLocaleLowerCase() === 'g') {
+  else if (system_shortcut_pressed && e.key.toLocaleLowerCase() === 'g') {
     e.preventDefault()
     onContextMenuGroup()
   }
   //取消组合
-  else if (e.ctrlKey && e.key.toLocaleLowerCase() === 'u') {
+  else if (system_shortcut_pressed && e.key.toLocaleLowerCase() === 'u') {
     e.preventDefault()
     onContextMenuUnGroup()
   }
   // 置顶
-  else if (e.ctrlKey && e.key === 'ArrowRight') {
+  else if (system_shortcut_pressed && e.key === 'ArrowRight') {
     e.preventDefault()
     onContextMoveTop()
   }
   // 置底
-  else if (e.ctrlKey && e.key === 'ArrowLeft') {
+  else if (system_shortcut_pressed && e.key === 'ArrowLeft') {
     e.preventDefault()
     onContextMoveBottom()
   }
   // 上移一层
-  else if (e.ctrlKey && e.key === 'ArrowUp') {
+  else if (system_shortcut_pressed && e.key === 'ArrowUp') {
     e.preventDefault()
     onContextMoveUp()
   }
   // 下移一层
-  else if (e.ctrlKey && e.key === 'ArrowDown') {
+  else if (system_shortcut_pressed && e.key === 'ArrowDown') {
     e.preventDefault()
     onContextMoveDown()
   }
   // 撤销
-  else if (e.ctrlKey && e.key.toLocaleLowerCase() === 'z') {
+  else if (system_shortcut_pressed && e.key.toLocaleLowerCase() === 'z') {
     e.preventDefault()
     onUndo()
   }
   // 重做
-  else if (e.ctrlKey && e.key.toLocaleLowerCase() === 'y') {
+  else if (system_shortcut_pressed && e.key.toLocaleLowerCase() === 'y') {
     e.preventDefault()
     onRedo()
   }
@@ -1150,7 +1153,7 @@ const onKeydown = (e: KeyboardEvent) => {
   }
 }
 const onMouseWheel = (e: any) => {
-  if (e.ctrlKey) {
+  if (isSystemShortcutKey(e)) {
     e.preventDefault()
     e.stopPropagation()
     if (e.deltaY > 0) {

+ 9 - 2
src/components/mt-edit/components/line-render/index.vue

@@ -232,7 +232,12 @@
 <script setup lang="ts">
 import type { MouseTouchEvent } from '@/components/mt-dzr/utils/types'
 import type { IDoneJson, IGlobalStoreCanvasCfg, IGlobalStoreGridCfg } from '../../store/types'
-import { alignToGrid, getCenterXY, positionArrarToPath } from '@/components/mt-edit/utils'
+import {
+  alignToGrid,
+  getCenterXY,
+  isSystemShortcutKey,
+  positionArrarToPath
+} from '@/components/mt-edit/utils'
 import { computed, ref, watch } from 'vue'
 import { configStore } from '../../store/config'
 type LineRenderProps = {
@@ -311,7 +316,9 @@ const onMouseDown = (
     const m_x = e instanceof MouseEvent ? e.clientX : e.touches[0].pageX
     const m_y = e instanceof MouseEvent ? e.clientY : e.touches[0].pageY
     // 移动的距离
-    const move_x = de.ctrlKey ? 0 : alignToGrid((m_x - d_x) / lineRenderProps.canvasCfg.scale, 1) //感觉对齐网格有点体验不好 所以固定为一了
+    const move_x = isSystemShortcutKey(de)
+      ? 0
+      : alignToGrid((m_x - d_x) / lineRenderProps.canvasCfg.scale, 1) //感觉对齐网格有点体验不好 所以固定为一了
     const move_y = de.shiftKey ? 0 : alignToGrid((m_y - d_y) / lineRenderProps.canvasCfg.scale, 1)
     new_x = realityX + move_x
     new_y = realityY + move_y

+ 19 - 0
src/components/mt-edit/store/config.ts

@@ -248,6 +248,25 @@ const sysComponentItems: ILeftAsideConfigItem[] = [
         type: 'switch',
         val: false
       },
+      textAlign: {
+        title: '文字对齐',
+        type: 'select',
+        val: 'left',
+        options: [
+          {
+            value: 'left',
+            label: '左对齐'
+          },
+          {
+            value: 'center',
+            label: '居中'
+          },
+          {
+            value: 'right',
+            label: '右对齐'
+          }
+        ]
+      },
       vertical: {
         title: '竖排展示',
         type: 'switch',

+ 12 - 9
src/components/mt-edit/store/context-menu.ts

@@ -1,5 +1,8 @@
 import { reactive } from 'vue'
 import type { ContextMenuInfoType, IContextMenu } from './types'
+import { getSystemShortcutKeyName } from '../utils'
+
+const systemShortcutKey = getSystemShortcutKeyName()
 
 export const contextMenuStore: IContextMenu = reactive({
   menuInfo: {
@@ -9,17 +12,17 @@ export const contextMenuStore: IContextMenu = reactive({
     info: {
       selectAll: {
         title: '全选',
-        hot_key: 'Ctrl + A',
+        hot_key: `${systemShortcutKey} + A`,
         enable: false
       },
       copy: {
         title: '复制',
-        hot_key: 'Ctrl + C',
+        hot_key: `${systemShortcutKey} + C`,
         enable: false
       },
       paste: {
         title: '粘贴',
-        hot_key: 'Ctrl + V',
+        hot_key: `${systemShortcutKey} + V`,
         enable: false
       },
       delete: {
@@ -29,32 +32,32 @@ export const contextMenuStore: IContextMenu = reactive({
       },
       group: {
         title: '组合',
-        hot_key: 'Ctrl + G',
+        hot_key: `${systemShortcutKey} + G`,
         enable: false
       },
       ungroup: {
         title: '取消组合',
-        hot_key: 'Ctrl + U',
+        hot_key: `${systemShortcutKey} + U`,
         enable: false
       },
       moveTop: {
         title: '置顶',
-        hot_key: 'Ctrl + Right',
+        hot_key: `${systemShortcutKey} + Right`,
         enable: false
       },
       moveUp: {
         title: '上移',
-        hot_key: 'Ctrl + Up',
+        hot_key: `${systemShortcutKey} + Up`,
         enable: false
       },
       moveDown: {
         title: '下移',
-        hot_key: 'Ctrl + Down',
+        hot_key: `${systemShortcutKey} + Down`,
         enable: false
       },
       moveBottom: {
         title: '置底',
-        hot_key: 'Ctrl + Left',
+        hot_key: `${systemShortcutKey} + Left`,
         enable: false
       }
     }

+ 13 - 0
src/components/mt-edit/utils/index.ts

@@ -6,6 +6,19 @@ import type {
   ILeftAsideConfigItemPublicProps
 } from '../store/types'
 import { useUpdateSysLine } from '@/components/mt-edit/composables/sys-line'
+
+export const isMacPlatform = () => {
+  if (typeof navigator === 'undefined') {
+    return false
+  }
+  return /mac|iphone|ipad|ipod/i.test(navigator.platform)
+}
+
+export const getSystemShortcutKeyName = () => (isMacPlatform() ? 'Cmd' : 'Ctrl')
+
+export const isSystemShortcutKey = (event: MouseEvent | KeyboardEvent | WheelEvent) =>
+  isMacPlatform() ? event.metaKey : event.ctrlKey
+
 export const createGroupInfo = (
   selected_items: IDoneJson[],
   canvas_dom: HTMLElement,