瀏覽代碼

复核:图片容器拖动

Michael Wang 4 年之前
父節點
當前提交
4978333038
共有 1 個文件被更改,包括 65 次插入2 次删除
  1. 65 2
      src/components/inspect/MarkBody.vue

+ 65 - 2
src/components/inspect/MarkBody.vue

@@ -1,5 +1,12 @@
 <template>
-  <div class="mark-body-container tw-flex-auto">
+  <div
+    class="mark-body-container tw-flex-auto"
+    :class="isGrabbing && 'grabbing'"
+    ref="container"
+    @mousedown="mouseDownHandler"
+    @mouseup="mouseUpHandler"
+    @mousemove="mouseMoveHandler"
+  >
     <div v-if="!store.currentTask" class="tw-text-center">暂无待复核任务</div>
     <div v-else :style="{ width: answerPaperScale }">
       <div
@@ -19,7 +26,14 @@
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, reactive, watchEffect } from "vue";
+import {
+  computed,
+  defineComponent,
+  onUnmounted,
+  reactive,
+  ref,
+  watchEffect,
+} from "vue";
 import { store } from "./store";
 import filters from "@/filters";
 import MarkDrawTrack from "./MarkDrawTrack.vue";
@@ -125,10 +139,53 @@ export default defineComponent({
       return scale * 100 + "%";
     });
 
+    // grab moving
+    let pos = { top: 0, left: 0, x: 0, y: 0 };
+    const container = ref((null as unknown) as HTMLDivElement);
+    const isGrabbing = ref(false);
+
+    const mouseDownHandler = function (e: MouseEvent) {
+      pos = {
+        // The current scroll
+        left: container.value.scrollLeft,
+        top: container.value.scrollTop,
+        // Get the current mouse position
+        x: e.clientX,
+        y: e.clientY,
+      };
+      isGrabbing.value = true;
+
+      document.addEventListener("mousemove", mouseMoveHandler);
+      document.addEventListener("mouseup", mouseUpHandler);
+    };
+
+    const mouseMoveHandler = function (e: MouseEvent) {
+      if (!isGrabbing.value) return;
+      // How far the mouse has been moved
+      const dx = e.clientX - pos.x;
+      const dy = e.clientY - pos.y;
+
+      // Scroll the element
+      container.value.scrollTop = pos.top - dy;
+      container.value.scrollLeft = pos.left - dx;
+    };
+    const mouseUpHandler = function () {
+      isGrabbing.value = false;
+    };
+    onUnmounted(() => {
+      document.removeEventListener("mousemove", mouseMoveHandler);
+      document.removeEventListener("mouseup", mouseUpHandler);
+    });
+
     return {
       store,
       sliceImagesWithTrackList,
       answerPaperScale,
+      container,
+      isGrabbing,
+      mouseDownHandler,
+      mouseMoveHandler,
+      mouseUpHandler,
     };
   },
 });
@@ -141,6 +198,12 @@ export default defineComponent({
   background-size: 8px 8px;
   background-image: linear-gradient(to right, #e7e7e7 4px, transparent 4px),
     linear-gradient(to bottom, transparent 4px, #e7e7e7 4px);
+
+  cursor: grab;
+  user-select: none;
+}
+.grabbing {
+  cursor: grabbing;
 }
 .mark-body-container img {
   width: 100%;