Forráskód Böngészése

feat: 新增拖拽功能

MTrun 3 éve
szülő
commit
ae78ced3dd

+ 1 - 0
src/packages/index.d.ts

@@ -16,6 +16,7 @@ export type ConfigType = {
 export interface CreateComponentType {
   id: string
   key: string
+  attr: { x: number; y: number; w: number; h: number }
   chartData: ConfigType
   config: object
   setPosition: Function

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

@@ -2,7 +2,7 @@
   <div
     class="go-edit-range"
     :style="useSizeStyle(size)"
-    @mousedown="mousedownHandle($event, undefined)"
+    @mousedown="mousedownHandleUnStop($event, undefined)"
   >
     <slot></slot>
   </div>
@@ -10,7 +10,7 @@
 
 <script setup lang="ts">
 import { useSizeStyle } from '../../hooks/useStyle.hook'
-import { mousedownHandle } from '../../hooks/useLayout.hook'
+import { mousedownHandleUnStop } from '../../hooks/useLayout.hook'
 
 const size = {
   w: 1920,

+ 4 - 1
src/views/chart/ContentEdit/components/ShapeBox/index.vue

@@ -37,11 +37,14 @@ const hover = computed(() => {
 const select = computed(() => {
   return props.item.id === chartEditStore.getTargetChart.selectIndex
 })
+
+
 </script>
 
 <style lang="scss" scoped>
 @include go(shape-box) {
   position: absolute;
+  cursor: move;
   .shape-modal {
     position: absolute;
     top: 0;
@@ -59,7 +62,7 @@ const select = computed(() => {
       width: 100%;
       height: 100%;
       border-radius: 10px;
-      border: 2px solid v-bind('themeColor');
+      border: 1px solid v-bind('themeColor');
     }
   }
 }

+ 68 - 15
src/views/chart/ContentEdit/hooks/useLayout.hook.ts

@@ -2,6 +2,7 @@ import { onUnmounted, onMounted } from 'vue'
 import { getChartEditStore } from './useStore.hook'
 import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
 import { CreateComponentType } from '@/packages/index.d'
+import throttle from 'lodash/throttle'
 
 const chartEditStore = getChartEditStore()
 
@@ -30,10 +31,11 @@ export const useLayout = () => {
   })
 }
 
-// 点击事件
-export const mousedownHandle = (e: MouseEvent, item?: CreateComponentType) => {
-  e.preventDefault()
-  e.stopPropagation()
+// 不拦截默认行为点击
+export const mousedownHandleUnStop = (
+  e: MouseEvent,
+  item?: CreateComponentType
+) => {
   if (item) {
     chartEditStore.setTargetSelectChart(item.id)
     return
@@ -41,16 +43,67 @@ export const mousedownHandle = (e: MouseEvent, item?: CreateComponentType) => {
   chartEditStore.setTargetSelectChart(item)
 }
 
-// 进入事件
-export const mouseenterHandle = (e: MouseEvent, item: CreateComponentType) => {
-  e.preventDefault()
-  e.stopPropagation()
-  chartEditStore.setTargetHoverChart(item.id)
-}
+export const useMouseHandle = () => {
+  // 点击事件(包含移动事件)
+  const mousedownHandle = (e: MouseEvent, item: CreateComponentType) => {
+    e.preventDefault()
+    e.stopPropagation()
+
+    chartEditStore.setTargetSelectChart(item.id)
+    const scale = chartEditStore.getEditCanvas.scale
+    const width = chartEditStore.getEditCanvas.width
+    const height = chartEditStore.getEditCanvas.height
+
+    // 获取编辑区域 Dom
+    const editcontentDom = chartEditStore.getEditCanvas.editContentDom
+
+    // 记录图表初始位置
+    const itemAttrX = item.attr.x
+    const itemAttrY = item.attr.y
+
+    // 记录点击初始位置
+    const startX = e.screenX
+    const startY = e.screenY
+
+    // 计算偏移量(处理 scale 比例问题)
+    const mousemove = throttle((moveEvent: MouseEvent) => {
+      let currX = itemAttrX + (moveEvent.screenX - startX) / scale
+      let currY = itemAttrY + (moveEvent.screenY - startY) / scale
+
+      // 位置检测
+      currX = currX < 0 ? 0 : currX
+      currY = currY < 0 ? 0 : currY
+
+      // 预留 20px 边距
+      currX = currX > width - 20 ? width - 20 : currX
+      currY = currY > height - 20 ? height - 20 : currY
+
+      item.attr.x = currX
+      item.attr.y = currY
+    }, 30)
+
+    const mouseup = () => {
+      editcontentDom!.removeEventListener('mousemove', mousemove)
+      editcontentDom!.removeEventListener('mouseup', mouseup)
+    }
+
+    editcontentDom!.addEventListener('mousemove', mousemove)
+    editcontentDom!.addEventListener('mouseup', mouseup)
+  }
+
+  // 进入事件
+  const mouseenterHandle = (e: MouseEvent, item: CreateComponentType) => {
+    e.preventDefault()
+    e.stopPropagation()
+    chartEditStore.setTargetHoverChart(item.id)
+  }
+
+  // 移出事件
+  const mouseleaveHandle = (e: MouseEvent, item: CreateComponentType) => {
+    e.preventDefault()
+    e.stopPropagation()
+    chartEditStore.setTargetHoverChart(undefined)
+  }
 
-// 移出事件
-export const mouseleaveHandle = (e: MouseEvent, item: CreateComponentType) => {
-  e.preventDefault()
-  e.stopPropagation()
-  chartEditStore.setTargetHoverChart(undefined)
+  return { mousedownHandle, mouseenterHandle, mouseleaveHandle }
 }

+ 10 - 8
src/views/chart/ContentEdit/index.vue

@@ -12,7 +12,7 @@
   >
     <div id="go-chart-edit-content">
       <!-- 展示 -->
-      <EditRange>
+      <EditRange ref="editRangeRef">
         <!-- 右键 -->
         <n-dropdown
           placement="bottom-start"
@@ -55,24 +55,22 @@
 </template>
 
 <script lang="ts" setup>
-import { onUnmounted, onMounted, toRefs } from 'vue'
+import { ref, onMounted } from 'vue'
 import { ContentBox } from '../ContentBox/index'
 import { EditRange } from './components/EditRange'
 import { EditBottom } from './components/EditBottom'
 import { ShapeBox } from './components/ShapeBox/index'
 
-import {
-  useLayout,
-  mousedownHandle,
-  mouseenterHandle,
-  mouseleaveHandle
-} from './hooks/useLayout.hook'
+import { useLayout, useMouseHandle } from './hooks/useLayout.hook'
 import { handleDrop, handleDragOver } from './hooks/useDrop.hook'
 import { useContextMenu } from './hooks/useContextMenu.hook'
 import { getChartEditStore } from './hooks/useStore.hook'
 import { useComponentStyle, useSizeStyle } from './hooks/useStyle.hook'
+import { CreateComponentType } from '@/packages/index.d'
 
 const chartEditStore = getChartEditStore()
+
+// 右键
 const {
   showDropdownRef,
   menuOptions,
@@ -84,6 +82,10 @@ const {
 
 // 布局处理
 useLayout()
+
+// 点击事件
+const editRangeRef = ref<HTMLElement | null>(null)
+const { mouseenterHandle, mouseleaveHandle, mousedownHandle } = useMouseHandle()
 </script>
 
 <style lang="scss" scoped>