mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
perf: 抽离选中元素对齐的方法
This commit is contained in:
parent
70c93aaddc
commit
7c7ec3d52d
131
src/hooks/useAlignActiveElement.ts
Normal file
131
src/hooks/useAlignActiveElement.ts
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
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 useHistorySnapshot from './useHistorySnapshot'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
|
const activeElementIdList = computed(() => store.state.activeElementIdList)
|
||||||
|
const activeElementList = computed<PPTElement[]>(() => store.getters.activeElementList)
|
||||||
|
const currentSlide = computed<Slide>(() => store.getters.currentSlide)
|
||||||
|
|
||||||
|
const { addHistorySnapshot } = useHistorySnapshot()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对齐选中的元素
|
||||||
|
* @param command 对齐方向
|
||||||
|
*/
|
||||||
|
const alignActiveElement = (command: ElementAlignCommand) => {
|
||||||
|
const { minX, maxX, minY, maxY } = getElementListRange(activeElementList.value)
|
||||||
|
const elementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))
|
||||||
|
|
||||||
|
// 如果所选择的元素为组合元素的成员,需要计算该组合的整体范围
|
||||||
|
const groupElementRangeMap = {}
|
||||||
|
for (const activeElement of activeElementList.value) {
|
||||||
|
if (activeElement.groupId && !groupElementRangeMap[activeElement.groupId]) {
|
||||||
|
const groupElements = activeElementList.value.filter(item => item.groupId === activeElement.groupId)
|
||||||
|
groupElementRangeMap[activeElement.groupId] = getElementListRange(groupElements)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据不同的命令,计算对齐的位置
|
||||||
|
if (command === ElementAlignCommands.LEFT) {
|
||||||
|
elementList.forEach(element => {
|
||||||
|
if (activeElementIdList.value.includes(element.id)) {
|
||||||
|
if (!element.groupId) element.left = minX
|
||||||
|
else {
|
||||||
|
const range = groupElementRangeMap[element.groupId]
|
||||||
|
const offset = range.minX - minX
|
||||||
|
element.left = element.left - offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (command === ElementAlignCommands.RIGHT) {
|
||||||
|
elementList.forEach(element => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const range = groupElementRangeMap[element.groupId]
|
||||||
|
const offset = range.maxX - maxX
|
||||||
|
element.left = element.left - offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (command === ElementAlignCommands.TOP) {
|
||||||
|
elementList.forEach(element => {
|
||||||
|
if (activeElementIdList.value.includes(element.id)) {
|
||||||
|
if (!element.groupId) element.top = minY
|
||||||
|
else {
|
||||||
|
const range = groupElementRangeMap[element.groupId]
|
||||||
|
const offset = range.minY - minY
|
||||||
|
element.top = element.top - offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (command === ElementAlignCommands.BOTTOM) {
|
||||||
|
elementList.forEach(element => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const range = groupElementRangeMap[element.groupId]
|
||||||
|
const offset = range.maxY - maxY
|
||||||
|
element.top = element.top - offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (command === ElementAlignCommands.HORIZONTAL) {
|
||||||
|
const horizontalCenter = (minX + maxX) / 2
|
||||||
|
elementList.forEach(element => {
|
||||||
|
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 = horizontalCenter - elWidth / 2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const range = groupElementRangeMap[element.groupId]
|
||||||
|
const center = (range.maxX + range.minX) / 2
|
||||||
|
const offset = center - horizontalCenter
|
||||||
|
element.left = element.left - offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (command === ElementAlignCommands.VERTICAL) {
|
||||||
|
const verticalCenter = (minY + maxY) / 2
|
||||||
|
elementList.forEach(element => {
|
||||||
|
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 = verticalCenter - elHeight / 2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const range = groupElementRangeMap[element.groupId]
|
||||||
|
const center = (range.maxY + range.minY) / 2
|
||||||
|
const offset = center - verticalCenter
|
||||||
|
element.top = element.top - offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
store.commit(MutationTypes.UPDATE_SLIDE, { elements: elementList })
|
||||||
|
addHistorySnapshot()
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
alignActiveElement,
|
||||||
|
}
|
||||||
|
}
|
@ -34,23 +34,19 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent } from 'vue'
|
import { computed, defineComponent } from 'vue'
|
||||||
import { MutationTypes, useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { PPTElement, Slide } from '@/types/slides'
|
import { PPTElement } from '@/types/slides'
|
||||||
import { ElementAlignCommand, ElementAlignCommands } from '@/types/edit'
|
|
||||||
import { getElementListRange } from '@/utils/element'
|
|
||||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
|
||||||
import useCombineElement from '@/hooks/useCombineElement'
|
import useCombineElement from '@/hooks/useCombineElement'
|
||||||
|
import useAlignActiveElement from '@/hooks/useAlignActiveElement'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'multi-position-panel',
|
name: 'multi-position-panel',
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const activeElementIdList = computed(() => store.state.activeElementIdList)
|
|
||||||
const activeElementList = computed<PPTElement[]>(() => store.getters.activeElementList)
|
const activeElementList = computed<PPTElement[]>(() => store.getters.activeElementList)
|
||||||
const currentSlide = computed<Slide>(() => store.getters.currentSlide)
|
|
||||||
|
|
||||||
const { addHistorySnapshot } = useHistorySnapshot()
|
|
||||||
const { combineElements, uncombineElements } = useCombineElement()
|
const { combineElements, uncombineElements } = useCombineElement()
|
||||||
|
const { alignActiveElement } = useAlignActiveElement()
|
||||||
|
|
||||||
// 判断当前多选的几个元素是否可以组合
|
// 判断当前多选的几个元素是否可以组合
|
||||||
const canCombine = computed(() => {
|
const canCombine = computed(() => {
|
||||||
@ -61,114 +57,6 @@ export default defineComponent({
|
|||||||
return !inSameGroup
|
return !inSameGroup
|
||||||
})
|
})
|
||||||
|
|
||||||
// 对齐选中的元素
|
|
||||||
const alignActiveElement = (command: ElementAlignCommand) => {
|
|
||||||
const { minX, maxX, minY, maxY } = getElementListRange(activeElementList.value)
|
|
||||||
const elementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))
|
|
||||||
|
|
||||||
// 如果所选择的元素为组合元素的成员,需要计算该组合的整体范围
|
|
||||||
const groupElementRangeMap = {}
|
|
||||||
for (const activeElement of activeElementList.value) {
|
|
||||||
if (activeElement.groupId && !groupElementRangeMap[activeElement.groupId]) {
|
|
||||||
const groupElements = activeElementList.value.filter(item => item.groupId === activeElement.groupId)
|
|
||||||
groupElementRangeMap[activeElement.groupId] = getElementListRange(groupElements)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据不同的命令,计算对齐的位置
|
|
||||||
if (command === ElementAlignCommands.LEFT) {
|
|
||||||
elementList.forEach(element => {
|
|
||||||
if (activeElementIdList.value.includes(element.id)) {
|
|
||||||
if (!element.groupId) element.left = minX
|
|
||||||
else {
|
|
||||||
const range = groupElementRangeMap[element.groupId]
|
|
||||||
const offset = range.minX - minX
|
|
||||||
element.left = element.left - offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (command === ElementAlignCommands.RIGHT) {
|
|
||||||
elementList.forEach(element => {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const range = groupElementRangeMap[element.groupId]
|
|
||||||
const offset = range.maxX - maxX
|
|
||||||
element.left = element.left - offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (command === ElementAlignCommands.TOP) {
|
|
||||||
elementList.forEach(element => {
|
|
||||||
if (activeElementIdList.value.includes(element.id)) {
|
|
||||||
if (!element.groupId) element.top = minY
|
|
||||||
else {
|
|
||||||
const range = groupElementRangeMap[element.groupId]
|
|
||||||
const offset = range.minY - minY
|
|
||||||
element.top = element.top - offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (command === ElementAlignCommands.BOTTOM) {
|
|
||||||
elementList.forEach(element => {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const range = groupElementRangeMap[element.groupId]
|
|
||||||
const offset = range.maxY - maxY
|
|
||||||
element.top = element.top - offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (command === ElementAlignCommands.HORIZONTAL) {
|
|
||||||
const horizontalCenter = (minX + maxX) / 2
|
|
||||||
elementList.forEach(element => {
|
|
||||||
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 = horizontalCenter - elWidth / 2
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const range = groupElementRangeMap[element.groupId]
|
|
||||||
const center = (range.maxX + range.minX) / 2
|
|
||||||
const offset = center - horizontalCenter
|
|
||||||
element.left = element.left - offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (command === ElementAlignCommands.VERTICAL) {
|
|
||||||
const verticalCenter = (minY + maxY) / 2
|
|
||||||
elementList.forEach(element => {
|
|
||||||
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 = verticalCenter - elHeight / 2
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const range = groupElementRangeMap[element.groupId]
|
|
||||||
const center = (range.maxY + range.minY) / 2
|
|
||||||
const offset = center - verticalCenter
|
|
||||||
element.top = element.top - offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: elementList })
|
|
||||||
addHistorySnapshot()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canCombine,
|
canCombine,
|
||||||
combineElements,
|
combineElements,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user