diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 961920f..204153c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: 5.3 +lockfileVersion: 5.4 specifiers: '@commitlint/cli': ^17.0.3 @@ -29,20 +29,20 @@ specifiers: dependencies: element-plus: 2.2.9_vue@3.2.37 - pinia: 2.0.17_typescript@4.7.4+vue@3.2.37 + pinia: 2.0.17_j6bzmzd4ujpabbp5objtwxyjp4 vue: 3.2.37 vue-router: 4.1.1_vue@3.2.37 devDependencies: '@commitlint/cli': 17.0.3 '@commitlint/config-conventional': 17.0.3 - '@typescript-eslint/eslint-plugin': 5.30.5_f646e16e2de31e818e163bded4698d6b - '@typescript-eslint/parser': 5.30.5_eslint@8.19.0+typescript@4.7.4 + '@typescript-eslint/eslint-plugin': 5.30.5_6zdoc3rn4mpiddqwhppni2mnnm + '@typescript-eslint/parser': 5.30.5_4x5o4skxv6sl53vpwefgt23khm '@vitejs/plugin-vue': 2.3.3_vite@2.9.13+vue@3.2.37 eslint: 8.19.0 eslint-config-prettier: 8.5.0_eslint@8.19.0 eslint-define-config: 1.5.1 - eslint-plugin-prettier: 4.2.1_fd2e32b7574349919aac0818c3f895ea + eslint-plugin-prettier: 4.2.1_7uxdfn2xinezdgvmbammh6ev5i eslint-plugin-vue: 9.2.0_eslint@8.19.0 husky: 8.0.1 less: 4.1.3 @@ -69,11 +69,19 @@ packages: '@babel/highlight': 7.18.6 dev: true + /@babel/helper-string-parser/7.19.4: + resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} + engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier/7.18.6: resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-identifier/7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + /@babel/highlight/7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} @@ -87,6 +95,16 @@ packages: resolution: {integrity: sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw==} engines: {node: '>=6.0.0'} hasBin: true + dependencies: + '@babel/types': 7.19.4 + + /@babel/types/7.19.4: + resolution: {integrity: sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 /@commitlint/cli/17.0.3: resolution: {integrity: sha512-oAo2vi5d8QZnAbtU5+0cR2j+A7PO8zuccux65R/EycwvsZrDVyW518FFrnJK2UQxbRtHFFIG+NjQ6vOiJV0Q8A==} @@ -173,7 +191,7 @@ packages: '@types/node': 18.0.3 chalk: 4.1.2 cosmiconfig: 7.0.1 - cosmiconfig-typescript-loader: 2.0.2_2dd5d46eecda2aef953638919121af58 + cosmiconfig-typescript-loader: 2.0.2_fxk5i3xm3ivo7fjwhcizcinpla lodash: 4.17.21 resolve-from: 5.0.0 typescript: 4.7.4 @@ -431,7 +449,7 @@ packages: resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==} dev: false - /@typescript-eslint/eslint-plugin/5.30.5_f646e16e2de31e818e163bded4698d6b: + /@typescript-eslint/eslint-plugin/5.30.5_6zdoc3rn4mpiddqwhppni2mnnm: resolution: {integrity: sha512-lftkqRoBvc28VFXEoRgyZuztyVUQ04JvUnATSPtIRFAccbXTWL6DEtXGYMcbg998kXw1NLUJm7rTQ9eUt+q6Ig==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -442,10 +460,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.30.5_eslint@8.19.0+typescript@4.7.4 + '@typescript-eslint/parser': 5.30.5_4x5o4skxv6sl53vpwefgt23khm '@typescript-eslint/scope-manager': 5.30.5 - '@typescript-eslint/type-utils': 5.30.5_eslint@8.19.0+typescript@4.7.4 - '@typescript-eslint/utils': 5.30.5_eslint@8.19.0+typescript@4.7.4 + '@typescript-eslint/type-utils': 5.30.5_4x5o4skxv6sl53vpwefgt23khm + '@typescript-eslint/utils': 5.30.5_4x5o4skxv6sl53vpwefgt23khm debug: 4.3.4 eslint: 8.19.0 functional-red-black-tree: 1.0.1 @@ -458,7 +476,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.30.5_eslint@8.19.0+typescript@4.7.4: + /@typescript-eslint/parser/5.30.5_4x5o4skxv6sl53vpwefgt23khm: resolution: {integrity: sha512-zj251pcPXI8GO9NDKWWmygP6+UjwWmrdf9qMW/L/uQJBM/0XbU2inxe5io/234y/RCvwpKEYjZ6c1YrXERkK4Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -486,7 +504,7 @@ packages: '@typescript-eslint/visitor-keys': 5.30.5 dev: true - /@typescript-eslint/type-utils/5.30.5_eslint@8.19.0+typescript@4.7.4: + /@typescript-eslint/type-utils/5.30.5_4x5o4skxv6sl53vpwefgt23khm: resolution: {integrity: sha512-k9+ejlv1GgwN1nN7XjVtyCgE0BTzhzT1YsQF0rv4Vfj2U9xnslBgMYYvcEYAFVdvhuEscELJsB7lDkN7WusErw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -496,7 +514,7 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.30.5_eslint@8.19.0+typescript@4.7.4 + '@typescript-eslint/utils': 5.30.5_4x5o4skxv6sl53vpwefgt23khm debug: 4.3.4 eslint: 8.19.0 tsutils: 3.21.0_typescript@4.7.4 @@ -531,7 +549,7 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.30.5_eslint@8.19.0+typescript@4.7.4: + /@typescript-eslint/utils/5.30.5_4x5o4skxv6sl53vpwefgt23khm: resolution: {integrity: sha512-o4SSUH9IkuA7AYIfAvatldovurqTAHrfzPApOZvdUq01hHojZojCFXx06D/aFpKCgWbMPRdJBWAC3sWp3itwTA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -659,7 +677,6 @@ packages: dependencies: '@vue/reactivity': 3.2.37 '@vue/shared': 3.2.37 - dev: false /@vue/runtime-dom/3.2.37: resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} @@ -667,7 +684,6 @@ packages: '@vue/runtime-core': 3.2.37 '@vue/shared': 3.2.37 csstype: 2.6.20 - dev: false /@vue/server-renderer/3.2.37_vue@3.2.37: resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} @@ -677,7 +693,6 @@ packages: '@vue/compiler-ssr': 3.2.37 '@vue/shared': 3.2.37 vue: 3.2.37 - dev: false /@vue/shared/3.2.37: resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} @@ -924,6 +939,8 @@ packages: snapdragon-node: 2.1.1 split-string: 3.1.0 to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color dev: true /braces/3.0.2: @@ -1089,8 +1106,8 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - is-text-path: 1.0.1 JSONStream: 1.3.5 + is-text-path: 1.0.1 lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 @@ -1116,7 +1133,7 @@ packages: vary: 1.1.2 dev: true - /cosmiconfig-typescript-loader/2.0.2_2dd5d46eecda2aef953638919121af58: + /cosmiconfig-typescript-loader/2.0.2_fxk5i3xm3ivo7fjwhcizcinpla: resolution: {integrity: sha512-KmE+bMjWMXJbkWCeY4FJX/npHuZPNr9XF9q9CIQ/bpFwi1qHfCmSiKarrCcRa0LO4fWjk93pVoeRtJAkTGcYNw==} engines: {node: '>=12', npm: '>=6'} peerDependencies: @@ -1125,7 +1142,7 @@ packages: dependencies: '@types/node': 18.0.3 cosmiconfig: 7.0.1 - ts-node: 10.8.2_2dd5d46eecda2aef953638919121af58 + ts-node: 10.8.2_fxk5i3xm3ivo7fjwhcizcinpla typescript: 4.7.4 transitivePeerDependencies: - '@swc/core' @@ -1194,7 +1211,6 @@ packages: /csstype/2.6.20: resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==} - dev: false /dargs/7.0.0: resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} @@ -1207,12 +1223,22 @@ packages: /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true dependencies: ms: 2.0.0 dev: true /debug/3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true dependencies: ms: 2.1.2 dev: true @@ -1368,7 +1394,7 @@ packages: escape-html: 1.0.3 lodash: 4.17.21 lodash-es: 4.17.21 - lodash-unified: 1.0.2_da03a4540fbd16bbaafbb96724306afd + lodash-unified: 1.0.2_3ib2ivapxullxkx3xftsimdk7u memoize-one: 6.0.0 normalize-wheel-es: 1.1.2 vue: 3.2.37 @@ -1649,7 +1675,7 @@ packages: engines: {node: '>= 14.6.0', npm: '>= 6.0.0', pnpm: '>= 7.0.0'} dev: true - /eslint-plugin-prettier/4.2.1_fd2e32b7574349919aac0818c3f895ea: + /eslint-plugin-prettier/4.2.1_7uxdfn2xinezdgvmbammh6ev5i: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1836,6 +1862,8 @@ packages: regex-not: 1.0.2 snapdragon: 0.8.2 to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color dev: true /extend-shallow/2.0.1: @@ -1865,6 +1893,8 @@ packages: regex-not: 1.0.2 snapdragon: 0.8.2 to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color dev: true /fast-deep-equal/3.1.3: @@ -2490,6 +2520,8 @@ packages: mime: 1.6.0 needle: 3.1.0 source-map: 0.6.1 + transitivePeerDependencies: + - supports-color dev: true /levn/0.4.1: @@ -2531,7 +2563,7 @@ packages: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} dev: false - /lodash-unified/1.0.2_da03a4540fbd16bbaafbb96724306afd: + /lodash-unified/1.0.2_3ib2ivapxullxkx3xftsimdk7u: resolution: {integrity: sha512-OGbEy+1P+UT26CYi4opY4gebD8cWRDxAT6MAObIVQMiqYdxZr1g3QHWCToVsm31x2NkLS4K3+MC2qInaRMa39g==} peerDependencies: '@types/lodash-es': '*' @@ -2663,6 +2695,8 @@ packages: regex-not: 1.0.2 snapdragon: 0.8.2 to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color dev: true /micromatch/4.0.5: @@ -2746,6 +2780,8 @@ packages: regex-not: 1.0.2 snapdragon: 0.8.2 to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color dev: true /natural-compare/1.4.0: @@ -2761,6 +2797,8 @@ packages: debug: 3.2.7 iconv-lite: 0.6.3 sax: 1.2.4 + transitivePeerDependencies: + - supports-color dev: true optional: true @@ -2955,7 +2993,7 @@ packages: dev: true optional: true - /pinia/2.0.17_typescript@4.7.4+vue@3.2.37: + /pinia/2.0.17_j6bzmzd4ujpabbp5objtwxyjp4: resolution: {integrity: sha512-AtwLwEWQgIjofjgeFT+nxbnK5lT2QwQjaHNEDqpsi2AiCwf/NY78uWTeHUyEhiiJy8+sBmw0ujgQMoQbWiZDfA==} peerDependencies: '@vue/composition-api': ^1.4.0 @@ -3320,6 +3358,8 @@ packages: source-map: 0.5.7 source-map-resolve: 0.5.3 use: 3.1.1 + transitivePeerDependencies: + - supports-color dev: true /source-map-js/1.0.2: @@ -3500,6 +3540,8 @@ packages: posthtml-svg-mode: 1.0.3 query-string: 4.3.4 traverse: 0.6.6 + transitivePeerDependencies: + - supports-color dev: true /svgo/2.8.0: @@ -3535,6 +3577,10 @@ packages: readable-stream: 3.6.0 dev: true + /to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + /to-object-path/0.3.0: resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} engines: {node: '>=0.10.0'} @@ -3576,7 +3622,7 @@ packages: engines: {node: '>=8'} dev: true - /ts-node/10.8.2_2dd5d46eecda2aef953638919121af58: + /ts-node/10.8.2_fxk5i3xm3ivo7fjwhcizcinpla: resolution: {integrity: sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==} hasBin: true peerDependencies: @@ -3656,7 +3702,6 @@ packages: resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} engines: {node: '>=4.2.0'} hasBin: true - dev: true /union-value/1.0.1: resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} @@ -3851,7 +3896,6 @@ packages: '@vue/runtime-dom': 3.2.37 '@vue/server-renderer': 3.2.37_vue@3.2.37 '@vue/shared': 3.2.37 - dev: false /which/2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} diff --git a/prettier.config.js b/prettier.config.js index 1aefcce..3bde828 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -15,6 +15,6 @@ module.exports = { requirePragma: false, // 需要编译指示 proseWrap: 'never', // 如果散文超过打印宽度,则换行 htmlWhitespaceSensitivity: 'strict', // 所有标签周围的空格(或缺少空格)被认为是重要的。 - endOfLine: 'lf', // 确保在文本文件中仅使用 ( \n)换行,常见于 Linux 和 macOS 以及 git repos 内部。 + endOfLine: 'auto', // 确保在文本文件中仅使用 ( \n)换行,常见于 Linux 和 macOS 以及 git repos 内部。 rangeStart: 0 // 格式化文件时,回到包含所选语句的第一行的开头。 }; diff --git a/src/components/webtopo-svgedit/components/center-panel/index.vue b/src/components/webtopo-svgedit/components/center-panel/index.vue index 81ddba0..66904e5 100644 --- a/src/components/webtopo-svgedit/components/center-panel/index.vue +++ b/src/components/webtopo-svgedit/components/center-panel/index.vue @@ -26,29 +26,59 @@ v-for="(item, index) in globalStore.done_json" :key="item.id" :transform="`translate(${item.x},${item.y})rotate(0)scale(1)`" - :class="`${globalStore.intention == EGlobalStoreIntention.None ? 'svg-item-none' : ''} - ${ - globalStore.intention == EGlobalStoreIntention.Move && - globalStore.handle_svg_info?.info.id == item.id - ? 'svg-item-move' - : '' - } ${ - globalStore.intention == EGlobalStoreIntention.Select && - globalStore.handle_svg_info?.info.id == item.id - ? 'svg-item-select' - : '' - }`" - @mousedown="onSvgMouseDown(item, index, $event)" > - + - - + @@ -60,11 +90,13 @@ import { EGlobalStoreIntention, EMouseInfoState, + EScaleInfoType, IDoneJson } from '../../../../store/global/types'; import { useSvgEditLayoutStore } from '../../../../store/svgedit-layout'; import { randomString } from '../../../../utils'; - + import HandlePanel from '../handle-panel/index.vue'; + // import HandlePanel from '../handle-panel/index.vue'; const globalStore = useGlobalStore(); const configStore = useConfigStore(); const svgEditLayoutStore = useSvgEditLayoutStore(); @@ -76,14 +108,23 @@ console.error('要创建的数据获取失败'); return; } - const done_item_json = { - id: randomString(), + const done_item_json: IDoneJson = { + id: globalStore.create_svg_info.name + randomString(), x: e.offsetX - svgEditLayoutStore.center_offset.x, y: e.offsetY - svgEditLayoutStore.center_offset.y, + scale_x: 1, + scale_y: 1, + actual_bound: { + x: 0, + y: 0, + width: 0, + height: 0 + }, ...globalStore.create_svg_info }; globalStore.setHandleSvgInfo(done_item_json, globalStore.done_json.length); globalStore.setDoneJson(done_item_json); + globalStore.intention = EGlobalStoreIntention.None; } }; const dragEnterEvent = (e: DragEvent) => { @@ -133,10 +174,63 @@ //移动画布 svgEditLayoutStore.center_offset.x = globalStore.mouse_info.new_position_x; svgEditLayoutStore.center_offset.y = globalStore.mouse_info.new_position_y; + } else if (globalStore.intention == EGlobalStoreIntention.Zoom) { + //缩放 + const move_length_x = + globalStore.scale_info.type === EScaleInfoType.TopLeft || + globalStore.scale_info.type === EScaleInfoType.Left || + globalStore.scale_info.type === EScaleInfoType.BottomLeft + ? globalStore.mouse_info.new_position_x - globalStore.mouse_info.now_position_x + : globalStore.scale_info.type === EScaleInfoType.TopRight || + globalStore.scale_info.type === EScaleInfoType.Right || + globalStore.scale_info.type === EScaleInfoType.BottomRight + ? globalStore.mouse_info.now_position_x - globalStore.mouse_info.new_position_x + : 0; + const move_length_y = + globalStore.scale_info.type === EScaleInfoType.TopLeft || + globalStore.scale_info.type === EScaleInfoType.TopCenter || + globalStore.scale_info.type === EScaleInfoType.TopRight + ? globalStore.mouse_info.new_position_y - globalStore.mouse_info.now_position_y + : globalStore.scale_info.type === EScaleInfoType.BottomLeft || + globalStore.scale_info.type === EScaleInfoType.BottomCenter || + globalStore.scale_info.type === EScaleInfoType.BottomRight + ? globalStore.mouse_info.now_position_y - globalStore.mouse_info.new_position_y + : 0; + //算出缩放倍数 + if (globalStore.handle_svg_info) { + const scale_x = + (globalStore.handle_svg_info.info.actual_bound.width * + globalStore.scale_info.scale_times.x - + move_length_x) / + globalStore.handle_svg_info.info.actual_bound.width; + const scale_y = + (globalStore.handle_svg_info.info.actual_bound.height * + globalStore.scale_info.scale_times.y - + move_length_y) / + globalStore.handle_svg_info.info.actual_bound.height; + if (scale_x > 0) { + globalStore.handle_svg_info.info.scale_x = scale_x; + globalStore.handle_svg_info.info.x = + globalStore.scale_info.type === EScaleInfoType.TopLeft || + globalStore.scale_info.type === EScaleInfoType.Left || + globalStore.scale_info.type === EScaleInfoType.BottomLeft + ? globalStore.scale_info.scale_item_info.x + move_length_x / 2 + : globalStore.scale_info.scale_item_info.x - move_length_x / 2; + } + if (scale_y > 0) { + globalStore.handle_svg_info.info.scale_y = scale_y; + globalStore.handle_svg_info.info.y = + globalStore.scale_info.type === EScaleInfoType.TopLeft || + globalStore.scale_info.type === EScaleInfoType.TopCenter || + globalStore.scale_info.type === EScaleInfoType.TopRight + ? globalStore.scale_info.scale_item_info.y + move_length_y / 2 + : globalStore.scale_info.scale_item_info.y - move_length_y / 2; + } + } } }; const onCanvasMouseUp = () => { - //如果鼠标不是按下状态或者没有选择组件 + //如果鼠标不是按下状态 if (globalStore.mouse_info.state != EMouseInfoState.Down) { return; } diff --git a/src/components/webtopo-svgedit/components/handle-panel/index.vue b/src/components/webtopo-svgedit/components/handle-panel/index.vue new file mode 100644 index 0000000..995611f --- /dev/null +++ b/src/components/webtopo-svgedit/components/handle-panel/index.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/src/store/global/index.ts b/src/store/global/index.ts index 2c9be77..efff90a 100644 --- a/src/store/global/index.ts +++ b/src/store/global/index.ts @@ -1,13 +1,16 @@ import { defineStore } from 'pinia'; +import { nextTick } from 'vue'; import { configCenter } from '../../config-center'; import { IConfigItem } from '../../config-center/types'; import { isOfType } from '../../utils'; import { EGlobalStoreIntention, EMouseInfoState, + EScaleInfoType, IDoneJson, IGlobalStore, - IMouseInfo + IMouseInfo, + IScaleInfo } from './types'; /** * 全局共享状态 @@ -28,7 +31,18 @@ export const useGlobalStore = defineStore('global-store', { new_position_x: 0, new_position_y: 0 }, - handle_svg_info: undefined + handle_svg_info: undefined, + scale_info: { + type: EScaleInfoType.None, + scale_times: { + x: 1, + y: 1 + }, + scale_item_info: { + x: 0, + y: 0 + } + } }; }, getters: {}, @@ -38,11 +52,25 @@ export const useGlobalStore = defineStore('global-store', { this.create_svg_info = create_svg_info; }, setDoneJson(done_json: IDoneJson[] | IDoneJson) { - // console.log('这里要记录操作历史记录'); + console.log('这里要记录操作历史记录'); if (isOfType(done_json, 'id')) { this.done_json.push(done_json); + nextTick(() => { + const queryBbox = document.querySelector(`#${done_json.id}`); + const rectBBox = document.querySelector(`#rect${done_json.id}`); + // console.log(queryBbox, 190); + if (queryBbox && rectBBox) { + const BBox = (queryBbox as SVGGraphicsElement).getBBox(); + const { x, y, width, height } = BBox; + rectBBox.setAttribute('x', x.toString()); + rectBBox.setAttribute('y', y.toString()); + rectBBox.setAttribute('width', width.toString()); + rectBBox.setAttribute('height', height.toString()); + done_json.actual_bound = { x, y, width, height }; + } + }); } else { - this.done_json = done_json; + this.done_json = JSON.parse(JSON.stringify(done_json)); } }, setMouseInfo(mouse_info: IMouseInfo) { @@ -57,6 +85,9 @@ export const useGlobalStore = defineStore('global-store', { } else { this.handle_svg_info = info; } + }, + setScaleInfo(info: IScaleInfo) { + this.scale_info = info; } } }); diff --git a/src/store/global/types.ts b/src/store/global/types.ts index 9c3e7c1..c3299d2 100644 --- a/src/store/global/types.ts +++ b/src/store/global/types.ts @@ -7,26 +7,36 @@ export interface IGlobalStore { done_json: IDoneJson[]; mouse_info: IMouseInfo; handle_svg_info: IHandleSvgInfo | undefined; + scale_info: IScaleInfo; } export interface IDoneJson extends IConfigItem { id: string; x: number; y: number; + scale_x: number; + scale_y: number; + actual_bound: { + x: number; + y: number; + width: number; + height: number; + }; } export enum EGlobalStoreIntention { None = 'None', Create = 'Create', Move = 'Move', MoveCanvas = 'MoveCanvas', - Select = 'Select' + Select = 'Select', + Zoom = 'Zoom' } export interface IMouseInfo { state: EMouseInfoState; - position_x: number; + position_x: number; //鼠标指针坐标 position_y: number; - now_position_x: number; + now_position_x: number; //当前目标的坐标 now_position_y: number; - new_position_x: number; + new_position_x: number; //移动之后目标的坐标 new_position_y: number; } export enum EMouseInfoState { @@ -37,3 +47,29 @@ export interface IHandleSvgInfo { info: IDoneJson; index: number; } +/** + * 缩放信息 + */ +export interface IScaleInfo { + type: EScaleInfoType; + scale_times: { + //点击缩放时当前组件的缩放倍数 + x: number; + y: number; + }; + scale_item_info: { + x: number; + y: number; + }; +} +export enum EScaleInfoType { + None = '', + TopLeft = 'TopLeft', + TopCenter = 'TopCenter', + TopRight = 'TopRight', + Left = 'Left', + Right = 'Right', + BottomLeft = 'BottomLeft', + BottomCenter = 'BottomCenter', + BottomRight = 'BottomRight' +} diff --git a/src/utils/index.ts b/src/utils/index.ts index fbf612e..608e188 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -17,3 +17,12 @@ export const randomString = (len?: number) => { export const isOfType = (target: unknown, prop: keyof T): target is T => { return (target as T)[prop] !== undefined; }; +/** + * 获取坐标偏移量 + * @param length 真实宽/高 + * @param scale 缩放倍数 + * @returns 坐标偏移量 + */ +export const getCoordinateOffset = (length: number, scale: number) => { + return (length / 2) * (scale - 1); +}; diff --git a/tsconfig.node.json b/tsconfig.node.json index e993792..a336f89 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -2,7 +2,8 @@ "compilerOptions": { "composite": true, "module": "esnext", - "moduleResolution": "node" + "moduleResolution": "node", + "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] }