Browse Source

!704 1. 增加流程图 小手功能 2. 增加重置功能 移动流程位置后恢复原位置 3. 流程挪动的时候禁用文本选择,确保拖动时不会选择文本
Merge pull request !704 from Lemon/feature/bpm-流程图小手

芋道源码 6 months ago
parent
commit
3906204bb9
1 changed files with 95 additions and 17 deletions
  1. 95 17
      src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue

+ 95 - 17
src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="simple-process-model-container position-relative">
-    <div class="position-absolute top-0px right-0px bg-#fff">
+    <div class="position-absolute top-0px right-0px bg-#fff z-index-button-group">
       <el-row type="flex" justify="end">
         <el-button-group key="scale-control" size="default">
           <el-button v-if="!readonly" size="default" @click="exportJson">
@@ -23,10 +23,19 @@
           <el-button size="default" :plain="true" :icon="ZoomOut" @click="zoomOut()" />
           <el-button size="default" class="w-80px"> {{ scaleValue }}% </el-button>
           <el-button size="default" :plain="true" :icon="ZoomIn" @click="zoomIn()" />
+          <el-button size="default" @click="resetPosition">重置</el-button>
         </el-button-group>
       </el-row>
     </div>
-    <div class="simple-process-model" :style="`transform: scale(${scaleValue / 100});`">
+    <div
+      class="simple-process-model"
+      :style="`transform: translate(${currentX}px, ${currentY}px) scale(${scaleValue / 100});`"
+      @mousedown="startDrag"
+      @mousemove="onDrag"
+      @mouseup="stopDrag"
+      @mouseleave="stopDrag"
+      @mouseenter="setGrabCursor"
+    >
       <ProcessNodeTree v-if="processNodeTree" v-model:flow-node="processNodeTree" />
     </div>
   </div>
@@ -80,24 +89,43 @@ let scaleValue = ref(100)
 const MAX_SCALE_VALUE = 200
 const MIN_SCALE_VALUE = 50
 
-// 放大
-const zoomIn = () => {
-  if (scaleValue.value == MAX_SCALE_VALUE) {
-    return
-  }
-  scaleValue.value += 10
+const isDragging = ref(false)
+const startX = ref(0)
+const startY = ref(0)
+const currentX = ref(0)
+const currentY = ref(0)
+const initialX = ref(0)
+const initialY = ref(0)
+
+const setGrabCursor = () => {
+  document.body.style.cursor = 'grab';
 }
 
-// 缩小
-const zoomOut = () => {
-  if (scaleValue.value == MIN_SCALE_VALUE) {
-    return
-  }
-  scaleValue.value -= 10
+const resetCursor = () => {
+  document.body.style.cursor = 'default';
 }
 
-const processReZoom = () => {
-  scaleValue.value = 100
+const startDrag = (e: MouseEvent) => {
+  isDragging.value = true;
+  startX.value = e.clientX - currentX.value;
+  startY.value = e.clientY - currentY.value;
+  setGrabCursor(); // 设置小手光标
+}
+
+const onDrag = (e: MouseEvent) => {
+  if (!isDragging.value) return;
+  e.preventDefault(); // 禁用文本选择
+  
+  // 使用 requestAnimationFrame 优化性能
+  requestAnimationFrame(() => {
+    currentX.value = e.clientX - startX.value;
+    currentY.value = e.clientY - startY.value;
+  });
+}
+
+const stopDrag = () => {
+  isDragging.value = false;
+  resetCursor(); // 重置光标
 }
 
 const errorDialogVisible = ref(false)
@@ -193,6 +221,56 @@ const importLocalFile = () => {
     }
   }
 }
+
+// 放大
+const zoomIn = () => {
+  if (scaleValue.value == MAX_SCALE_VALUE) {
+    return
+  }
+  scaleValue.value += 10
+}
+
+// 缩小
+const zoomOut = () => {
+  if (scaleValue.value == MIN_SCALE_VALUE) {
+    return
+  }
+  scaleValue.value -= 10
+}
+
+const processReZoom = () => {
+  scaleValue.value = 100
+}
+
+// 在组件初始化时记录初始位置
+onMounted(() => {
+  initialX.value = currentX.value
+  initialY.value = currentY.value
+})
+
+// 重置位置的函数
+const resetPosition = () => {
+  currentX.value = initialX.value
+  currentY.value = initialY.value
+}
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.simple-process-model-container {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  overflow: hidden;
+  user-select: none; // 禁用文本选择
+}
+
+.simple-process-model {
+  position: relative; // 确保相对定位
+  min-width: 100%; // 确保宽度为100%
+  min-height: 100%; // 确保高度为100%
+}
+
+.z-index-button-group {
+  z-index: 10;
+}
+</style>