Sfoglia il codice sorgente

feat: 新增页面框选效果

奔跑的面条 3 anni fa
parent
commit
c987dd8816

+ 1 - 1
src/enums/editPageEnum.ts

@@ -6,7 +6,7 @@ export enum MouseEventButton {
 
 // 页面拖拽键名
 export enum DragKeyEnum {
-  DROG_KEY = 'ChartData'
+  DRAG_KEY = 'ChartData'
 }
 
 // 操作枚举

+ 7 - 1
src/settings/designSetting.ts

@@ -59,4 +59,10 @@ export const requestInterval = 30
 export const requestIntervalUnit = RequestHttpIntervalEnum.SECOND
 
 // 工作区域历史记录存储最大数量
-export const editHistoryMax = 100
+export const editHistoryMax = 100
+
+// 拖拽时蒙层的 z-index,需比所有图表高
+export const canvasModelIndex = 9999
+
+// 框选时蒙层的 z-index,需比所有图表高
+export const selectBoxIndex = canvasModelIndex + 10

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

@@ -21,7 +21,8 @@ export enum EditCanvasTypeEnum {
   USER_SCALE = 'userScale',
   LOCK_SCALE = 'lockScale',
   IS_CREATE = 'isCreate',
-  IS_DRAG = 'isDrag'
+  IS_DRAG = 'isDrag',
+  IS_SELECT = 'isSelect'
 }
 
 // 编辑区域
@@ -41,6 +42,8 @@ export type EditCanvasType = {
   [EditCanvasTypeEnum.IS_CREATE]: boolean
   // 拖拽中
   [EditCanvasTypeEnum.IS_DRAG]: boolean
+  // 框选中
+  [EditCanvasTypeEnum.IS_SELECT]: boolean
 }
 
 // 滤镜/背景色/宽高主题等

+ 5 - 3
src/store/modules/chartEditStore/chartEditStore.ts

@@ -52,7 +52,9 @@ export const useChartEditStore = defineStore({
       // 初始化
       isCreate: false,
       // 拖拽中
-      isDrag: false
+      isDrag: false,
+      // 框选中
+      isSelect: false
     },
     // 右键菜单
     rightMenuShow: false,
@@ -216,10 +218,10 @@ export const useChartEditStore = defineStore({
     },
     // * 设置鼠标位置
     setMousePosition(x?: number, y?: number, startX?: number, startY?: number): void {
-      if (startX) this.mousePosition.startX = startX
-      if (startY) this.mousePosition.startY = startY
       if (x) this.mousePosition.x = x
       if (y) this.mousePosition.y = y
+      if (startX) this.mousePosition.startX = startX
+      if (startY) this.mousePosition.startY = startY
     },
     // * 找到目标 id 数据的下标位置,id可为父级或子集数组(无则返回-1)
     fetchTargetIndex(id?: string): number {

+ 1 - 1
src/views/chart/ContentCharts/components/ChartsItemBox/index.vue

@@ -45,7 +45,7 @@ const dragStartHandle = (e: DragEvent, item: ConfigType) => {
   componentInstall(item.chartKey, fetchChartComponent(item))
   componentInstall(item.conKey, fetchConfigComponent(item))
   // 将配置项绑定到拖拽属性上
-  e!.dataTransfer!.setData(DragKeyEnum.DROG_KEY, JSON.stringify(omit(item, ['image'])))
+  e!.dataTransfer!.setData(DragKeyEnum.DRAG_KEY, JSON.stringify(omit(item, ['image'])))
   // 修改状态
   chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CREATE, true)
 }

+ 13 - 5
src/views/chart/ContentEdit/components/EditRange/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="go-edit-range go-transition" :style="rangeStyle" @mousedown="mousedownHandleUnStop($event, undefined)">
+  <div class="go-edit-range go-transition" :style="rangeStyle" @mousedown="mousedownBoxSelect($event, undefined)">
     <slot></slot>
     <!-- 水印 -->
     <edit-watermark></edit-watermark>
@@ -7,19 +7,23 @@
     <edit-rule></edit-rule>
     <!-- 拖拽时的辅助线 -->
     <edit-align-line></edit-align-line>
+    <!-- 框选时的样式框 -->
+    <edit-select></edit-select>
     <!-- 拖拽时的遮罩 -->
-    <div class="go-edit-range-model" :style="rangeModelStyle"></div>
+    <div v-if="showModel" class="go-edit-range-model" :style="rangeModelStyle"></div>
   </div>
 </template>
 
 <script setup lang="ts">
 import { toRefs, computed } from 'vue'
 import { useSizeStyle } from '../../hooks/useStyle.hook'
-import { mousedownHandleUnStop } from '../../hooks/useDrag.hook'
+import { canvasModelIndex } from '@/settings/designSetting'
+import { mousedownBoxSelect } from '../../hooks/useDrag.hook'
 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
 import { EditAlignLine } from '../EditAlignLine'
 import { EditWatermark } from '../EditWatermark'
 import { EditRule } from '../EditRule'
+import { EditSelect } from '../EditSelect'
 
 const chartEditStore = useChartEditStore()
 
@@ -41,11 +45,15 @@ const rangeStyle = computed(() => {
   return { ...useSizeStyle(size.value), ...scale }
 })
 
+// 是否展示模态层
+const showModel = computed(() => {
+  return getEditCanvas.value.isCreate || getEditCanvas.value.isDrag
+})
+
 // 模态层
 const rangeModelStyle = computed(() => {
-  const dragStyle = getEditCanvas.value.isCreate && { 'z-index': 99999 }
   // @ts-ignore
-  return { ...useSizeStyle(size.value), ...dragStyle }
+  return { ...useSizeStyle(size.value), 'z-index': canvasModelIndex }
 })
 </script>
 

+ 3 - 0
src/views/chart/ContentEdit/components/EditSelect/index.ts

@@ -0,0 +1,3 @@
+import EditSelect from './index.vue'
+
+export { EditSelect }

+ 107 - 0
src/views/chart/ContentEdit/components/EditSelect/index.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="go-edit-select" v-if="isSelect" :style="positionStyle">
+    <div class="select-background"></div>
+    <div class="select-border"></div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, toRefs, watch } from 'vue'
+import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
+import { useDesignStore } from '@/store/modules/designStore/designStore'
+import { useSizeStyle, useComponentStyle } from '../../hooks/useStyle.hook'
+import { selectBoxIndex } from '@/settings/designSetting'
+
+// 全局颜色
+const designStore = useDesignStore()
+const themeColor = ref(designStore.getAppTheme)
+const chartEditStore = useChartEditStore()
+const { isSelect, scale } = toRefs(chartEditStore.getEditCanvas)
+
+// 位置
+const positionStyle = ref()
+
+watch(
+  () => chartEditStore.getMousePosition,
+  positionInfo => {
+    if (!isSelect.value) return
+
+    const { startX, startY, x, y } = positionInfo
+
+    const attr = {
+      zIndex: selectBoxIndex,
+      // left
+      x: 0,
+      // top
+      y: 0,
+      // 宽
+      w: 0,
+      // 高
+      h: 0
+    }
+
+    // 处理位置
+    if (x > startX && y > startY) {
+      // 右下
+      attr.x = startX
+      attr.y = startY
+      attr.w = Math.round((x - startX) / scale.value)
+      attr.h = Math.round((y - startY) / scale.value)
+    } else if (x > startX && y < startY) {
+      // 右上
+      attr.x = startX
+      attr.w = Math.round((x - startX) / scale.value)
+      attr.h = Math.round((startY - y) / scale.value)
+      attr.y = startY - attr.h
+    } else if (x < startX && y > startY) {
+      // 左下
+      attr.y = startY
+      attr.w = Math.round((startX - x) / scale.value)
+      attr.h = Math.round((y - startY) / scale.value)
+      attr.x = startX - attr.w
+    } else {
+      // 左上
+      attr.w = Math.round((startX - x) / scale.value)
+      attr.h = Math.round((startY - y) / scale.value)
+      attr.x = startX - attr.w
+      attr.y = startY - attr.h
+    }
+
+    positionStyle.value = {
+      ...useComponentStyle(attr, selectBoxIndex),
+      ...useSizeStyle(attr)
+    }
+  },
+  {
+    deep: true
+  }
+)
+</script>
+
+<style lang="scss" scoped>
+@include go('edit-select') {
+  position: absolute;
+  .select-border,
+  .select-background {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    border-radius: 10px;
+    overflow: hidden;
+  }
+  .select-border {
+    left: 0;
+    top: 0;
+    opacity: 1;
+    border-width: 2px;
+    border-style: solid;
+    border-color: v-bind('themeColor');
+  }
+  .select-background {
+    top: 2px;
+    left: 2px;
+    opacity: 0.1;
+    background-color: v-bind('themeColor');
+  }
+}
+</style>

+ 38 - 9
src/views/chart/ContentEdit/hooks/useDrag.hook.ts

@@ -20,7 +20,7 @@ export const dragHandle = async (e: DragEvent) => {
     loadingStart()
 
     // 获取拖拽数据
-    const drayDataString = e!.dataTransfer!.getData(DragKeyEnum.DROG_KEY)
+    const drayDataString = e!.dataTransfer!.getData(DragKeyEnum.DRAG_KEY)
     if (!drayDataString) {
       loadingFinish()
       return
@@ -60,6 +60,38 @@ export const mousedownHandleUnStop = (e: MouseEvent, item?: CreateComponentType
   chartEditStore.setTargetSelectChart(undefined)
 }
 
+// * 框选
+export const mousedownBoxSelect = (e: MouseEvent, item?: CreateComponentType | CreateComponentGroupType) => {
+  mousedownHandleUnStop(e)
+
+  // 记录点击初始位置
+  const startOffsetX = e.offsetX
+  const startOffsetY = e.offsetY
+  const startScreenX = e.screenX
+  const startScreenY = e.screenY
+
+  chartEditStore.setMousePosition(undefined, undefined, startOffsetX, startOffsetY)
+
+  // 移动框选
+  const mousemove = throttle((moveEvent: MouseEvent) => {
+    const currX = startOffsetX + moveEvent.screenX - startScreenX
+    const currY = startOffsetY + moveEvent.screenY - startScreenY
+
+    chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_SELECT, true)
+    chartEditStore.setMousePosition(currX, currY)
+  }, 50)
+
+  // 鼠标抬起
+  const mouseup = () => {
+    chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_SELECT, false)
+    chartEditStore.setMousePosition(0, 0, 0, 0)
+    document.removeEventListener('mousemove', mousemove)
+    document.removeEventListener('mouseup', mouseup)
+  }
+  document.addEventListener('mousemove', mousemove)
+  document.addEventListener('mouseup', mouseup)
+}
+
 // * 鼠标事件
 export const useMouseHandle = () => {
   // *  Click 事件, 松开鼠标触发
@@ -86,7 +118,6 @@ export const useMouseHandle = () => {
     e.preventDefault()
     e.stopPropagation()
     onClickOutSide()
-
     // 按下左键 + CTRL
     if (
       e.buttons === MouseEventButton.LEFT &&
@@ -124,11 +155,10 @@ export const useMouseHandle = () => {
     const startY = e.screenY
 
     // 记录初始位置
-    chartEditStore.setMousePosition(startX, startY)
+    chartEditStore.setMousePosition(undefined, undefined, startX, startY)
 
     // 移动-计算偏移量
     const mousemove = throttle((moveEvent: MouseEvent) => {
-      chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, true)
       chartEditStore.setMousePosition(moveEvent.screenX, moveEvent.screenY)
 
       // 当前偏移量,处理 scale 比例问题
@@ -136,8 +166,8 @@ export const useMouseHandle = () => {
       let offsetY = (moveEvent.screenY - startY) / scale
 
       chartEditStore.getTargetChart.selectId.forEach(id => {
-        if(!targetMap.has(id)) return
-        
+        if (!targetMap.has(id)) return
+
         const index = chartEditStore.fetchTargetIndex(id)
         // 拿到初始位置数据
         const { x, y, w, h } = targetMap.get(id)
@@ -166,8 +196,7 @@ export const useMouseHandle = () => {
     }, 30)
 
     const mouseup = () => {
-      chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, false)
-      chartEditStore.setMousePosition(0, 0)
+      chartEditStore.setMousePosition(0, 0, 0, 0)
       document.removeEventListener('mousemove', mousemove)
       document.removeEventListener('mouseup', mouseup)
     }
@@ -237,7 +266,7 @@ export const useMousePointHandle = (e: MouseEvent, point: string, attr: PickCrea
 
   const mouseup = () => {
     chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, false)
-    chartEditStore.setMousePosition(0, 0)
+    chartEditStore.setMousePosition(0, 0, 0, 0)
     document.removeEventListener('mousemove', mousemove)
     document.removeEventListener('mouseup', mouseup)
   }