diff --git a/src/hooks/useAlignActiveElement.ts b/src/hooks/useAlignActiveElement.ts index 6cde29a2..cfab7b5e 100644 --- a/src/hooks/useAlignActiveElement.ts +++ b/src/hooks/useAlignActiveElement.ts @@ -2,7 +2,7 @@ import { computed } from 'vue' import { MutationTypes, useStore } from '@/store' import { PPTElement, Slide } from '@/types/slides' import { ElementAlignCommand, ElementAlignCommands } from '@/types/edit' -import { getElementListRange } from '@/utils/element' +import { getElementListRange, getRectRotatedOffset } from '@/utils/element' import useHistorySnapshot from './useHistorySnapshot' export default () => { @@ -35,7 +35,19 @@ export default () => { if (command === ElementAlignCommands.LEFT) { elementList.forEach(element => { if (activeElementIdList.value.includes(element.id)) { - if (!element.groupId) element.left = minX + if (!element.groupId) { + if ('rotate' in element && element.rotate) { + const { offsetX } = getRectRotatedOffset({ + left: element.left, + top: element.top, + width: element.width, + height: element.height, + rotate: element.rotate, + }) + element.left = minX - offsetX + } + else element.left = minX + } else { const range = groupElementRangeMap[element.groupId] const offset = range.minX - minX @@ -49,7 +61,17 @@ export default () => { if (activeElementIdList.value.includes(element.id)) { if (!element.groupId) { const elWidth = element.type === 'line' ? Math.max(element.start[0], element.end[0]) : element.width - element.left = maxX - elWidth + if ('rotate' in element && element.rotate) { + const { offsetX } = getRectRotatedOffset({ + left: element.left, + top: element.top, + width: element.width, + height: element.height, + rotate: element.rotate, + }) + element.left = maxX - elWidth + offsetX + } + else element.left = maxX - elWidth } else { const range = groupElementRangeMap[element.groupId] @@ -62,7 +84,19 @@ export default () => { else if (command === ElementAlignCommands.TOP) { elementList.forEach(element => { if (activeElementIdList.value.includes(element.id)) { - if (!element.groupId) element.top = minY + if (!element.groupId) { + if ('rotate' in element && element.rotate) { + const { offsetY } = getRectRotatedOffset({ + left: element.left, + top: element.top, + width: element.width, + height: element.height, + rotate: element.rotate, + }) + element.top = minY - offsetY + } + else element.top = minY + } else { const range = groupElementRangeMap[element.groupId] const offset = range.minY - minY @@ -76,7 +110,17 @@ export default () => { if (activeElementIdList.value.includes(element.id)) { if (!element.groupId) { const elHeight = element.type === 'line' ? Math.max(element.start[1], element.end[1]) : element.height - element.top = maxY - elHeight + if ('rotate' in element && element.rotate) { + const { offsetY } = getRectRotatedOffset({ + left: element.left, + top: element.top, + width: element.width, + height: element.height, + rotate: element.rotate, + }) + element.top = maxY - elHeight + offsetY + } + else element.top = maxY - elHeight } else { const range = groupElementRangeMap[element.groupId] diff --git a/src/hooks/useUniformDisplayElement.ts b/src/hooks/useUniformDisplayElement.ts index 6f20b0e0..9afda211 100644 --- a/src/hooks/useUniformDisplayElement.ts +++ b/src/hooks/useUniformDisplayElement.ts @@ -1,7 +1,7 @@ import { computed } from 'vue' import { MutationTypes, useStore } from '@/store' import { PPTElement, Slide } from '@/types/slides' -import { getElementRange, getElementListRange, getRectRotatedRange } from '@/utils/element' +import { getElementRange, getElementListRange, getRectRotatedOffset } from '@/utils/element' import useHistorySnapshot from './useHistorySnapshot' interface SortedElementData { @@ -58,21 +58,13 @@ export default () => { for (const sortedItem of sortedElementData) { if (sortedItem.el.id === element.id) { if ('rotate' in element && element.rotate) { - const { xRange: originXRange } = getRectRotatedRange({ - left: element.left, - top: element.top, - width: element.width, - height: element.height, - rotate: 0, - }) - const { xRange: rotatedXRange } = getRectRotatedRange({ + const { offsetX } = getRectRotatedOffset({ left: element.left, top: element.top, width: element.width, height: element.height, rotate: element.rotate, }) - const offsetX = rotatedXRange[0] - originXRange[0] element.left = sortedItem.pos - offsetX } else element.left = sortedItem.pos @@ -125,21 +117,13 @@ export default () => { for (const sortedItem of sortedElementData) { if (sortedItem.el.id === element.id) { if ('rotate' in element && element.rotate) { - const { yRange: originYRange } = getRectRotatedRange({ - left: element.left, - top: element.top, - width: element.width, - height: element.height, - rotate: 0, - }) - const { yRange: rotatedYRange } = getRectRotatedRange({ + const { offsetY } = getRectRotatedOffset({ left: element.left, top: element.top, width: element.width, height: element.height, rotate: element.rotate, }) - const offsetY = rotatedYRange[0] - originYRange[0] element.top = sortedItem.pos - offsetY } else element.top = sortedItem.pos diff --git a/src/utils/element.ts b/src/utils/element.ts index 231d5ba1..1b058635 100644 --- a/src/utils/element.ts +++ b/src/utils/element.ts @@ -43,6 +43,31 @@ export const getRectRotatedRange = (element: RotatedElementData) => { } } +/** + * 计算元素在画布中的矩形范围旋转后的新位置与旋转之前位置的偏离距离 + * @param element 元素的位置大小和旋转角度信息 + */ +export const getRectRotatedOffset = (element: RotatedElementData) => { + const { xRange: originXRange, yRange: originYRange } = getRectRotatedRange({ + left: element.left, + top: element.top, + width: element.width, + height: element.height, + rotate: 0, + }) + const { xRange: rotatedXRange, yRange: rotatedYRange } = getRectRotatedRange({ + left: element.left, + top: element.top, + width: element.width, + height: element.height, + rotate: element.rotate, + }) + return { + offsetX: rotatedXRange[0] - originXRange[0], + offsetY: rotatedYRange[0] - originYRange[0], + } +} + /** * 计算元素在画布中的位置范围 * @param element 元素信息