Parcourir la source

feat: 添加元素缩放拖拽

liaojiaxing il y a 11 mois
Parent
commit
71800b56b6
1 fichiers modifiés avec 109 ajouts et 21 suppressions
  1. 109 21
      src/views/designer/component/ComponentWrapper.vue

+ 109 - 21
src/views/designer/component/ComponentWrapper.vue

@@ -7,15 +7,16 @@
     <div class="component-content">
       <component :is="component" v-bind="componentData.props" />
     </div>
-    <div class="edit-box" :style="editWapperStyle" v-if="showEditBox">
-      <span class="edit-box-point top-left"></span>
-      <span class="edit-box-point top-center"></span>
-      <span class="edit-box-point top-right"></span>
-      <span class="edit-box-point left-center"></span>
-      <span class="edit-box-point right-center"></span>
-      <span class="edit-box-point bottom-left"></span>
-      <span class="edit-box-point bottom-center"></span>
-      <span class="edit-box-point bottom-right"></span>
+    <div v-if="showEditBox" class="edit-box" :style="editWapperStyle">
+      <UseDraggable
+        v-for="item in dragPointList"
+        :key="item"
+        @move="(_, e) => handleDragPoint(item, e)"
+        @start="handleDragStart"
+        @end="handleDragEnd"
+      >
+        <span class="edit-box-point" :class="item"></span>
+      </UseDraggable>
     </div>
   </div>
 </template>
@@ -28,6 +29,7 @@ import type { CustomElement } from "#/project";
 import { useStageStore } from "@/store/modules/stage";
 import { useProjectStore } from "@/store/modules/project";
 import { useDraggable } from "@vueuse/core";
+import { UseDraggable } from "@vueuse/components";
 
 const { componentData } = defineProps<{ componentData: CustomElement }>();
 // 动态引入组件
@@ -45,7 +47,7 @@ const editWapperStyle = computed(() => {
     width: `${width * stageStore.scale}px`,
     height: `${height * stageStore.scale}px`,
     border: "1px solid #1890ff",
-    left:  (width / 2) * (1 - stageStore.scale) + "px",
+    left: (width / 2) * (1 - stageStore.scale) + "px",
     top: (height / 2) * (1 - stageStore.scale) + "px",
   };
 });
@@ -55,23 +57,24 @@ const warpperStyle = computed(() => {
   return {
     width: `${width}px`,
     height: `${height}px`,
-    left:  position.x + "px",
+    left: position.x + "px",
     top: position.y + "px",
   };
 });
 // 是否显示编辑框
 const showEditBox = computed(() => {
-  return projectStore.mode === 'edit' && projectStore.selectedElementKeys.includes(componentData.key);
+  return (
+    projectStore.mode === "edit" &&
+    projectStore.selectedElementKeys.includes(componentData.key)
+  );
 });
 
-const handleDragPoint = (e: MouseEvent) => {
-  e.stopPropagation();
-  console.log(e)
-};
-
+let isPointDragFlag = false;
 // 拖拽移动组件
 useDraggable(componentWrapperRef, {
   onMove: (position) => {
+    if(isPointDragFlag) return;
+
     const originPosition = componentWrapperRef.value!.getBoundingClientRect();
     // 计算移动的距离
     const x = position.x - originPosition.left;
@@ -82,12 +85,97 @@ useDraggable(componentWrapperRef, {
         x: componentData.position.x + x,
         y: componentData.position.y + y,
       },
-    })
+    });
   },
-  capture: false,
-  preventDefault: false,
-  stopPropagation: false
 });
+
+const dragPointList = [
+  "top-left",
+  "top-center",
+  "top-right",
+  "left-center",
+  "right-center",
+  "bottom-left",
+  "bottom-center",
+  "bottom-right",
+];
+
+/* ===============================缩放组件==================================== */
+const startPoint = {
+  x: 0,
+  y: 0,
+};
+// 拖拽点移动
+const handleDragPoint = (type: string, e: PointerEvent) => {
+  const moveX = (e.x - startPoint.x) / stageStore.scale;
+  const moveY = (e.y - startPoint.y) / stageStore.scale;
+  
+  let width = componentData.props.width;
+  let height = componentData.props.height;
+  let x = componentData.position.x;
+  let y = componentData.position.y;
+
+  switch (type) {
+    case "top-left":
+      width -= moveX;
+      height -= moveY;
+      x += moveX;
+      y += moveY;
+      break;
+    case "top-center":
+      height -= moveY;
+      y += moveY;
+      break;
+    case "top-right":
+      width += moveX;
+      height -= moveY;
+      y += moveY;
+      break;
+    case "left-center":
+      width -= moveX;
+      x += moveX;
+      break;
+    case "right-center":
+      width += moveX;
+      break;
+    case "bottom-left":
+      width -= moveX;
+      height += moveY;
+      x += moveX;
+      break;
+    case "bottom-center":
+      height += moveY;
+      break;
+    case "bottom-right":
+      width += moveX;
+      height += moveY;
+      break;
+  }
+
+  startPoint.x = e.x;
+  startPoint.y = e.y;
+
+  if(width < 10 || height < 10) return;
+
+  projectStore.updateElement(componentData.key, {
+    position: { x, y },
+    props: { 
+      ...componentData.props,
+      width,
+      height,
+     },
+  });
+};
+// 拖拽点开始
+const handleDragStart = (_, e: PointerEvent) => {
+  startPoint.x = e.x;
+  startPoint.y = e.y;
+  isPointDragFlag = true;
+};
+// 拖拽点结束
+const handleDragEnd = () => {
+  isPointDragFlag = false;
+};
 </script>
 
 <style lang="less" scoped>