Quellcode durchsuchen

feat: 添加对齐功能

liaojiaxing vor 10 Monaten
Ursprung
Commit
9769c97866

+ 62 - 4
src/store/modules/action.ts

@@ -1,25 +1,83 @@
 import { defineStore } from "pinia";
+import { AlignEnum } from "@/enum/alignEnum";
+import { useProjectStore } from "@/store/modules/project";
 
 export const useAcionStore = defineStore({
   id: 'action',
   state() {
     return {
       // 操作记录
-      records: []
+      records: [],
     }
   },
+  getters: {
+    projectStore: () => useProjectStore(),
+  },
   actions: {
     addRecord(record) {
 
     },
-    undo() {
+    actionUndo() {
 
     },
-    redo() {
+    actionRedo() {
 
     },
-    clear() {
+    actionClear() {
 
+    },
+    // 对齐
+    actionAlign(type: AlignEnum) {
+      const activeElements = this.projectStore.currentSelectedElements;
+      switch (type) {
+        case AlignEnum.Bottom: {
+          const maxY = Math.max(...activeElements.map((item) => item.container.props.y + item.container.props.height));
+          activeElements.forEach((item) => {
+            this.projectStore.updateElement(item.key, 'container.props.y', maxY - item.container.props.height);
+          });
+          break;
+        }
+        case AlignEnum.HorizontalCenter: {
+          const maxX = Math.max(...activeElements.map((item) => item.container.props.x + item.container.props.width));
+          const minX = Math.min(...activeElements.map((item) => item.container.props.x));
+          const centerX = minX + (maxX - minX) / 2;
+          activeElements.forEach((item) => {
+            this.projectStore.updateElement(item.key, 'container.props.x', centerX - item.container.props.width / 2);
+          });
+          break;
+        }
+        case AlignEnum.VerticalCenter: {
+          const maxY = Math.max(...activeElements.map((item) => item.container.props.y + item.container.props.height));
+          const minY = Math.min(...activeElements.map((item) => item.container.props.y));
+          const centerY = minY + (maxY - minY) / 2;
+          activeElements.forEach((item) => {
+            this.projectStore.updateElement(item.key, 'container.props.y', centerY - item.container.props.height / 2);
+          });
+          break;
+        }
+        case AlignEnum.Left: {
+          const minX = Math.min(...activeElements.map((item) => item.container.props.x));
+          activeElements.forEach((item) => {
+            this.projectStore.updateElement(item.key, 'container.props.x', minX);
+          });
+          break;
+        }
+        case AlignEnum.Right: {
+          const maxX = Math.max(...activeElements.map((item) => item.container.props.x + item.container.props.width));
+          activeElements.forEach((item) => {
+            this.projectStore.updateElement(item.key, 'container.props.x', maxX - item.container.props.width);
+          });
+          break
+        }
+        case AlignEnum.Top: {
+          const minY = Math.min(...activeElements.map((item) => item.container.props.y));
+          activeElements.forEach((item) => {
+            this.projectStore.updateElement(item.key, 'container.props.y', minY);
+          });
+          break;
+        }
+        default: 
+      }
     }
   }
 })

+ 13 - 4
src/views/designer/component/MenuBar.vue

@@ -56,7 +56,7 @@
 
     <Dropdown trigger="click">
       <template #overlay>
-        <Menu>
+        <Menu @click="handleAlignClick" :disabled="projectStore.selectedElementKeys.length < 2">
           <MenuItem :key="AlignEnum.Left">
             <VerticalRightOutlined />
             左对齐
@@ -74,11 +74,11 @@
             <VerticalAlignTopOutlined />
             顶部对齐
           </MenuItem>
-          <MenuItem key="5">
+          <MenuItem :key="AlignEnum.Bottom">
             <VerticalAlignBottomOutlined />
             底部对齐
           </MenuItem>
-          <MenuItem key="6">
+          <MenuItem :key="AlignEnum.VerticalCenter">
             <LineOutlined />
             垂直居中
           </MenuItem>
@@ -88,7 +88,7 @@
         <template #title>
           <div>对齐</div>
         </template>
-        <Button type="text" size="small">
+        <Button :disabled="projectStore.selectedElementKeys.length < 2" type="text" size="small">
           <VerticalAlignMiddleOutlined />
           <CaretDownOutlined
             style="font-size: 10px; vertical-align: baseline"
@@ -153,6 +153,15 @@ import {
 } from "@ant-design/icons-vue";
 
 import { AlignEnum } from "@/enum/alignEnum";
+import { useAcionStore } from "@/store/modules/action";
+import { useProjectStore } from "@/store/modules/project";
+
+const actionStore = useAcionStore();
+const projectStore = useProjectStore();
+
+const handleAlignClick = ({ key }: any) => {
+  actionStore.actionAlign(key);
+};
 
 </script>
 

+ 1 - 1
src/views/designer/index.vue

@@ -37,7 +37,7 @@
         <!-- 图层管理 -->
         <LayerManagement v-show="stageStore.showLayer" />
       </div>
-      <div class="component-wrapper">
+      <div class="component-wrapper" >
         <!-- 组件库 -->
         <ComponentLibary />
       </div>