Ver Fonte

feat: 新增组件多选和右键成组按钮

奔跑的面条 há 3 anos atrás
pai
commit
8a10a9cf82

+ 13 - 1
src/enums/editPageEnum.ts

@@ -1,3 +1,9 @@
+// 鼠标点击左右键
+export enum MouseEventButton {
+  LEFT = 1,
+  RIGHT = 2
+}
+
 // 页面拖拽键名
 export enum DragKeyEnum {
   DROG_KEY = 'ChartData'
@@ -27,6 +33,9 @@ export enum WinKeyboard {
   CTRL = 'ctrl',
   SHIFT = 'shift',
   ALT = ' alt',
+  CTRL_SOURCE_KEY = "control",
+  SHIFT_SOURCE_KEY = "shift",
+  ALT_SOURCE_KEY = "alt"
 }
 
 // Mac 键盘枚举
@@ -35,4 +44,7 @@ export enum MacKeyboard {
   CTRL = '⌘',
   SHIFT = '⇧',
   ALT = '⌥',
-}
+  CTRL_SOURCE_KEY = "⌘",
+  SHIFT_SOURCE_KEY = "⇧",
+  ALT_SOURCE_KEY = "⌥"
+}

+ 8 - 2
src/plugins/icon.ts

@@ -80,7 +80,9 @@ import {
   Scale as ScaleIcon,
   FitToScreen as FitToScreenIcon,
   FitToHeight as FitToHeightIcon,
-  FitToWidth as FitToWidthIcon
+  FitToWidth as FitToWidthIcon,
+  Carbon3DCursor as Carbon3DCursorIcon,
+  Carbon3DSoftware as Carbon3DSoftwareIcon
 } from '@vicons/carbon'
 
 const ionicons5 = {
@@ -234,7 +236,11 @@ const carbon = {
   ScaleIcon,
   FitToScreenIcon,
   FitToHeightIcon,
-  FitToWidthIcon
+  FitToWidthIcon,
+  // 成组
+  Carbon3DCursorIcon,
+  // 解组
+  Carbon3DSoftwareIcon
 }
 
 // https://www.xicons.org/#/ 还有很多

+ 1 - 1
src/store/modules/chartEditStore/chartEditStore.ts

@@ -172,7 +172,7 @@ export const useChartEditStore = defineStore({
         this.targetChart.selectId = []
         return
       }
-      // 新增
+      // 多选
       if(push) {
         // 字符串
         if(isString(selectId)) {

+ 2 - 1
src/store/modules/chartHistoryStore/chartHistoryStore.d.ts

@@ -51,7 +51,8 @@ export enum HistoryStackItemEnum {
 
 // 历史记录项类型
 export interface HistoryItemType {
-  [HistoryStackItemEnum.ID]: string
+  // 会有同时操作多个组件场景
+  [HistoryStackItemEnum.ID]: string | string[]
   [HistoryStackItemEnum.TARGET_TYPE]: HistoryTargetTypeEnum
   [HistoryStackItemEnum.ACTION_TYPE]: HistoryActionTypeEnum
   [HistoryStackItemEnum.HISTORY_DATA]: CreateComponentType | EditCanvasType

+ 5 - 0
src/views/chart/ContentEdit/components/EditShortcutKey/ShortcutKeyModal.vue

@@ -99,6 +99,11 @@ const shortcutKeyOptions = [
     win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + Z `,
     mac: `${MacKeyboard.CTRL.toUpperCase()} + ${MacKeyboard.SHIFT.toUpperCase()} + Z `,
   },
+  {
+    label: '多选',
+    win: `${WinKeyboard.CTRL.toUpperCase()} + 🖱️ `,
+    mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + 🖱️ `,
+  },
 ]
 const closeHandle = () => {
   emit('update:modelShow', false)

+ 37 - 21
src/views/chart/ContentEdit/hooks/useDrag.hook.ts

@@ -1,10 +1,7 @@
-import { DragKeyEnum } from '@/enums/editPageEnum'
+import { DragKeyEnum, MouseEventButton, WinKeyboard, MacKeyboard } from '@/enums/editPageEnum'
 import { createComponent } from '@/packages'
 import { ConfigType } from '@/packages/index.d'
-import {
-  CreateComponentType,
-  PickCreateComponentType,
-} from '@/packages/index.d'
+import { CreateComponentType, PickCreateComponentType } from '@/packages/index.d'
 import { useContextMenu } from '@/views/chart/hooks/useContextMenu.hook'
 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
 import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
@@ -35,10 +32,7 @@ export const dragHandle = async (e: DragEvent) => {
     // 创建新图表组件
     let newComponent: CreateComponentType = await createComponent(dropData)
 
-    newComponent.setPosition(
-      e.offsetX - newComponent.attr.w / 2,
-      e.offsetY - newComponent.attr.h / 2
-    )
+    newComponent.setPosition(e.offsetX - newComponent.attr.w / 2, e.offsetY - newComponent.attr.h / 2)
     chartEditStore.addComponentList(newComponent, false, true)
     chartEditStore.setTargetSelectChart(newComponent.id)
     loadingFinish()
@@ -57,10 +51,7 @@ export const dragoverHandle = (e: DragEvent) => {
 }
 
 // * 不拦截默认行为点击
-export const mousedownHandleUnStop = (
-  e: MouseEvent,
-  item?: CreateComponentType
-) => {
+export const mousedownHandleUnStop = (e: MouseEvent, item?: CreateComponentType) => {
   if (item) {
     chartEditStore.setTargetSelectChart(item.id)
     return
@@ -70,13 +61,42 @@ export const mousedownHandleUnStop = (
 
 // * 移动图表
 export const useMouseHandle = () => {
-  // 点击事件(包含移动事件)
-  const mousedownHandle = (e: MouseEvent, item: CreateComponentType) => {
+  // *  Click 事件, 松开鼠标触发
+  const mouseClickHandle = (e: MouseEvent, item: CreateComponentType) => {
     e.preventDefault()
     e.stopPropagation()
+    // 若此时按下了 CTRL, 表示多选
+    if (
+      window.$KeyboardActive?.has(WinKeyboard.CTRL_SOURCE_KEY) ||
+      window.$KeyboardActive?.has(MacKeyboard.CTRL_SOURCE_KEY)
+    ) {
+      chartEditStore.setTargetSelectChart(item.id, true)
+    }
+  }
 
+  // * 按下事件(包含移动事件)
+  const mousedownHandle = (e: MouseEvent, item: CreateComponentType) => {
+    e.preventDefault()
+    e.stopPropagation()
     onClickOutSide()
+
+    // 按下左键 + CTRL
+    if (
+      e.buttons === MouseEventButton.LEFT &&
+      (window.$KeyboardActive?.has(WinKeyboard.CTRL_SOURCE_KEY) ||
+        window.$KeyboardActive?.has(MacKeyboard.CTRL_SOURCE_KEY))
+    )
+      return
+
+    // 按下右键 + 选中多个
+    if (e.buttons === MouseEventButton.RIGHT && chartEditStore.getTargetChart.selectId.length > 1) return
+
+    // 选中当前目标组件
     chartEditStore.setTargetSelectChart(item.id)
+
+    // 按下右键
+    if (e.buttons === MouseEventButton.RIGHT) return
+
     const scale = chartEditStore.getEditCanvas.scale
     const width = chartEditStore.getEditCanvasConfig.width
     const height = chartEditStore.getEditCanvasConfig.height
@@ -141,15 +161,11 @@ export const useMouseHandle = () => {
     chartEditStore.setTargetHoverChart(undefined)
   }
 
-  return { mousedownHandle, mouseenterHandle, mouseleaveHandle }
+  return { mouseClickHandle, mousedownHandle, mouseenterHandle, mouseleaveHandle }
 }
 
 // * 移动锚点
-export const useMousePointHandle = (
-  e: MouseEvent,
-  point: string,
-  attr: PickCreateComponentType<'attr'>
-) => {
+export const useMousePointHandle = (e: MouseEvent, point: string, attr: PickCreateComponentType<'attr'>) => {
   e.stopPropagation()
   e.preventDefault()
 

+ 2 - 1
src/views/chart/ContentEdit/index.vue

@@ -27,6 +27,7 @@
             :index="index"
             :style="useComponentStyle(item.attr, index)"
             :item="item"
+            @click="mouseClickHandle($event, item)"
             @mousedown="mousedownHandle($event, item)"
             @mouseenter="mouseenterHandle($event, item)"
             @mouseleave="mouseleaveHandle($event, item)"
@@ -87,7 +88,7 @@ const { handleContextMenu } = useContextMenu()
 useLayout()
 
 // 点击事件
-const { mouseenterHandle, mouseleaveHandle, mousedownHandle } = useMouseHandle()
+const { mouseenterHandle, mouseleaveHandle, mousedownHandle, mouseClickHandle } = useMouseHandle()
 
 // 主题色
 const themeSetting = computed(() => {

+ 36 - 31
src/views/chart/hooks/useContextMenu.hook.ts

@@ -6,82 +6,85 @@ import { icon } from '@/plugins'
 import { MenuOptionsItemType } from './useContextMenu.hook.d'
 import { MenuEnum } from '@/enums/editPageEnum'
 
-const {
-  CopyIcon,
-  CutIcon,
-  ClipboardOutlineIcon,
-  TrashIcon,
-  ChevronDownIcon,
-  ChevronUpIcon,
-} = icon.ionicons5
-const { UpToTopIcon, DownToBottomIcon, PaintBrushIcon } = icon.carbon
+const { CopyIcon, CutIcon, ClipboardOutlineIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } = icon.ionicons5
+const { UpToTopIcon, DownToBottomIcon, PaintBrushIcon, Carbon3DSoftwareIcon, Carbon3DCursorIcon } = icon.carbon
 
 const chartEditStore = useChartEditStore()
 
-// * 默认选项
+// * 默认单组件选项
 const defaultOptions: MenuOptionsItemType[] = [
   {
     label: '复制',
     key: MenuEnum.COPY,
     icon: renderIcon(CopyIcon),
-    fnHandle: chartEditStore.setCopy,
+    fnHandle: chartEditStore.setCopy
   },
   {
     label: '剪切',
     key: MenuEnum.CUT,
     icon: renderIcon(CutIcon),
-    fnHandle: chartEditStore.setCut,
+    fnHandle: chartEditStore.setCut
   },
   {
     label: '粘贴',
     key: MenuEnum.PARSE,
     icon: renderIcon(ClipboardOutlineIcon),
-    fnHandle: chartEditStore.setParse,
+    fnHandle: chartEditStore.setParse
   },
   {
     type: 'divider',
-    key: 'd1',
+    key: 'd1'
   },
   {
     label: '置顶',
     key: MenuEnum.TOP,
     icon: renderIcon(UpToTopIcon),
-    fnHandle: chartEditStore.setTop,
+    fnHandle: chartEditStore.setTop
   },
   {
     label: '置底',
     key: MenuEnum.BOTTOM,
     icon: renderIcon(DownToBottomIcon),
-    fnHandle: chartEditStore.setBottom,
+    fnHandle: chartEditStore.setBottom
   },
   {
     label: '上移一层',
     key: MenuEnum.UP,
     icon: renderIcon(ChevronUpIcon),
-    fnHandle: chartEditStore.setUp,
+    fnHandle: chartEditStore.setUp
   },
   {
     label: '下移一层',
     key: MenuEnum.DOWN,
     icon: renderIcon(ChevronDownIcon),
-    fnHandle: chartEditStore.setDown,
+    fnHandle: chartEditStore.setDown
   },
   {
     type: 'divider',
-    key: 'd2',
+    key: 'd2'
   },
   {
     label: '清空剪贴板',
     key: MenuEnum.CLEAR,
     icon: renderIcon(PaintBrushIcon),
-    fnHandle: chartEditStore.setRecordChart,
+    fnHandle: chartEditStore.setRecordChart
   },
   {
     label: '删除',
     key: MenuEnum.DELETE,
     icon: renderIcon(TrashIcon),
-    fnHandle: chartEditStore.removeComponentList,
-  },
+    fnHandle: chartEditStore.removeComponentList
+  }
+]
+
+// * 默认多选组件选项
+const defaultMultiSelectionOptions: MenuOptionsItemType[] = [
+  {
+    label: '成组',
+    key: MenuEnum.COPY,
+    icon: renderIcon(Carbon3DSoftwareIcon),
+    fnHandle: chartEditStore.setCopy
+  }
 ]
 
 // * 无数据传递拥有的选项
@@ -126,7 +129,7 @@ const handleContextMenu = (
   // 隐藏选项列表
   hideOptionsList?: MenuEnum[],
   // 挑选选项列表
-  pickOptionsList?: MenuEnum[],
+  pickOptionsList?: MenuEnum[]
 ) => {
   e.stopPropagation()
   e.preventDefault()
@@ -136,8 +139,13 @@ const handleContextMenu = (
   }
   chartEditStore.setRightMenuShow(false)
 
-  // * 设置默认选项
-  menuOptions.value = defaultOptions
+  // * 多选默认选项
+  if (chartEditStore.getTargetChart.selectId.length > 1) {
+    menuOptions.value = defaultMultiSelectionOptions
+  } else {
+    // * 单选默认选项
+    menuOptions.value = defaultOptions
+  }
 
   if (!item) {
     menuOptions.value = pickOption(menuOptions.value, defaultNoItemKeys)
@@ -163,7 +171,6 @@ const handleContextMenu = (
  * @returns
  */
 export const useContextMenu = () => {
-
   // 设置默认项
   menuOptions.value = defaultOptions
 
@@ -175,9 +182,7 @@ export const useContextMenu = () => {
   // * 事件处理
   const handleMenuSelect = (key: string) => {
     chartEditStore.setRightMenuShow(false)
-    const targetItem: MenuOptionsItemType[] = menuOptions.value.filter(
-      (e: MenuOptionsItemType) => e.key === key
-    )
+    const targetItem: MenuOptionsItemType[] = menuOptions.value.filter((e: MenuOptionsItemType) => e.key === key)
 
     menuOptions.value.forEach((e: MenuOptionsItemType) => {
       if (e.key === key) {
@@ -189,12 +194,12 @@ export const useContextMenu = () => {
       }
     })
   }
-  
+
   return {
     menuOptions,
     handleContextMenu,
     onClickOutSide,
     handleMenuSelect,
-    mousePosition: chartEditStore.getMousePosition,
+    mousePosition: chartEditStore.getMousePosition
   }
 }

+ 5 - 5
src/views/chart/hooks/useKeyboard.hook.ts

@@ -77,14 +77,14 @@ const macKeyList: Array<string> = [
 
 // 处理键盘记录
 const keyRecordHandle = () => {
-  document.onkeydown = throttle((e: KeyboardEvent) => {
+  document.onkeydown = (e: KeyboardEvent) => {
     if(window.$KeyboardActive) window.$KeyboardActive.add(e.key.toLocaleLowerCase())
-    else window.$KeyboardActive = new Set([e.key])
-  }, 200)
+    else window.$KeyboardActive = new Set([e.key.toLocaleLowerCase()])
+  }
 
-  document.onkeyup = throttle((e: KeyboardEvent) => {
+  document.onkeyup = (e: KeyboardEvent) => {
     if(window.$KeyboardActive) window.$KeyboardActive.delete(e.key.toLocaleLowerCase())
-  }, 200)
+  }
 }
 
 // 初始化监听事件