mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
update
This commit is contained in:
parent
ab8d5aab63
commit
2e905e5bd8
@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div class="element-style-panel">
|
||||
<div v-if="!currentPanelComponent">
|
||||
请先选中要编辑的元素
|
||||
</div>
|
||||
<component :is="currentPanelComponent"></component>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,28 +1,49 @@
|
||||
<template>
|
||||
<div class="multi-position-panel">
|
||||
<ButtonGroup class="row">
|
||||
<Button style="flex: 1;">左</Button>
|
||||
<Button style="flex: 1;">中</Button>
|
||||
<Button style="flex: 1;">右</Button>
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="左对齐">
|
||||
<Button style="flex: 1;" @click="alignActiveElement('left')"><IconFont type="icon-align-left" /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="水平居中">
|
||||
<Button style="flex: 1;" @click="alignActiveElement('horizontal')"><IconFont type="icon-align-vertical-center" /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="右对齐">
|
||||
<Button style="flex: 1;" @click="alignActiveElement('right')"><IconFont type="icon-align-right" /></Button>
|
||||
</Tooltip>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup class="row">
|
||||
<Button style="flex: 1;">上</Button>
|
||||
<Button style="flex: 1;">中</Button>
|
||||
<Button style="flex: 1;">下</Button>
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="上对齐">
|
||||
<Button style="flex: 1;" @click="alignActiveElement('top')"><IconFont type="icon-align-top" /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="垂直居中">
|
||||
<Button style="flex: 1;" @click="alignActiveElement('vertical')"><IconFont type="icon-align-horizontal-center" /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="下对齐">
|
||||
<Button style="flex: 1;" @click="alignActiveElement('bottom')"><IconFont type="icon-align-bottom" /></Button>
|
||||
</Tooltip>
|
||||
</ButtonGroup>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ButtonGroup class="row">
|
||||
<Button style="flex: 1;">组合</Button>
|
||||
<Button style="flex: 1;">取消组合</Button>
|
||||
<Button :disabled="!canCombine" @click="combineElements()" style="flex: 1;">组合</Button>
|
||||
<Button :disabled="canCombine" @click="uncombineElements()" style="flex: 1;">取消组合</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { Button, Divider } from 'ant-design-vue'
|
||||
import { computed, defineComponent, Ref } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { MutationTypes, State } from '@/store'
|
||||
import { PPTElement, Slide } 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 { Button, Divider, Tooltip } from 'ant-design-vue'
|
||||
import IconFont from '@/components/IconFont'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'multi-position-panel',
|
||||
@ -30,6 +51,138 @@ export default defineComponent({
|
||||
Button,
|
||||
ButtonGroup: Button.Group,
|
||||
Divider,
|
||||
Tooltip,
|
||||
IconFont,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore<State>()
|
||||
const activeElementIdList = computed(() => store.state.activeElementIdList)
|
||||
const activeElementList: Ref<PPTElement[]> = computed(() => store.getters.activeElementList)
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
const { combineElements, uncombineElements } = useCombineElement()
|
||||
|
||||
const canCombine = computed(() => {
|
||||
const firstGroupId = activeElementList.value[0].groupId
|
||||
if(!firstGroupId) return true
|
||||
|
||||
const inSameGroup = activeElementList.value.every(el => (el.groupId && el.groupId) === firstGroupId)
|
||||
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 {
|
||||
canCombine,
|
||||
combineElements,
|
||||
uncombineElements,
|
||||
alignActiveElement,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user