| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- <template>
- <div
- class="multi-select-operate"
- :style="{
- left: minX + 'px',
- top: minY + 'px',
- transform: `scale(${1 / canvasScale})`,
- }"
- >
- <BorderLine v-for="line in borderLines" :key="line.type" :type="line.type" :style="line.style" />
- <template v-if="!disableResizablePoint">
- <ResizablePoint
- v-for="point in resizablePoints"
- :key="point.type"
- :type="point.type"
- :style="point.style"
- @mousedown.stop="scaleMultiElement($event, { minX, maxX, minY, maxY }, point.direction)"
- />
- </template>
- </div>
- </template>
- <script lang="ts">
- import { computed, defineComponent, reactive, PropType, watchEffect, toRefs } from 'vue'
- import { useStore } from 'vuex'
- import { State } from '@/store'
- import { PPTElement, ElementTypes } from '@/types/slides'
- import { getElementListRange } from '@/utils/element'
- import { ElementScaleHandler, OperateResizablePointTypes, OperateBorderLineTypes, MultiSelectRange, OperatePoints } from '@/types/edit'
- import ResizablePoint from '@/views/_common/_operate/ResizablePoint.vue'
- import BorderLine from '@/views/_common/_operate/BorderLine.vue'
- export default defineComponent({
- name: 'multi-select-operate',
- components: {
- ResizablePoint,
- BorderLine,
- },
- props: {
- elementList: {
- type: Array as PropType<PPTElement[]>,
- required: true,
- },
- scaleMultiElement: {
- type: Function as PropType<(e: MouseEvent, range: MultiSelectRange, command: ElementScaleHandler) => void>,
- required: true,
- },
- },
- setup(props) {
- const store = useStore<State>()
- const activeElementIdList = computed(() => store.state.activeElementIdList)
- const canvasScale = computed(() => store.state.canvasScale)
- const localActiveElementList = computed(() => props.elementList.filter(el => activeElementIdList.value.includes(el.id)))
- const range = reactive({
- minX: 0,
- maxX: 0,
- minY: 0,
- maxY: 0,
- })
- const width = computed(() => (range.maxX - range.minX) * canvasScale.value)
- const height = computed(() => (range.maxY - range.minY) * canvasScale.value)
- const resizablePoints = computed(() => {
- return [
- { type: OperateResizablePointTypes.TL, direction: OperatePoints.LEFT_TOP, style: {} },
- { type: OperateResizablePointTypes.TC, direction: OperatePoints.TOP, style: {left: width.value / 2 + 'px'} },
- { type: OperateResizablePointTypes.TR, direction: OperatePoints.RIGHT_TOP, style: {left: width.value + 'px'} },
- { type: OperateResizablePointTypes.ML, direction: OperatePoints.LEFT, style: {top: height.value / 2 + 'px'} },
- { type: OperateResizablePointTypes.MR, direction: OperatePoints.RIGHT, style: {left: width.value + 'px', top: height.value / 2 + 'px'} },
- { type: OperateResizablePointTypes.BL, direction: OperatePoints.LEFT_BOTTOM, style: {top: height.value + 'px'} },
- { type: OperateResizablePointTypes.BC, direction: OperatePoints.BOTTOM, style: {left: width.value / 2 + 'px', top: height.value + 'px'} },
- { type: OperateResizablePointTypes.BR, direction: OperatePoints.RIGHT_BOTTOM, style: {left: width.value + 'px', top: height.value + 'px'} },
- ]
- })
- const borderLines = computed(() => {
- return [
- { type: OperateBorderLineTypes.T, style: {width: width.value + 'px'} },
- { type: OperateBorderLineTypes.B, style: {top: height.value + 'px', width: width.value + 'px'} },
- { type: OperateBorderLineTypes.L, style: {height: height.value + 'px'} },
- { type: OperateBorderLineTypes.R, style: {left: width.value + 'px', height: height.value + 'px'} },
- ]
- })
- const disableResizablePoint = computed(() => {
- return localActiveElementList.value.some(item => {
- if(
- (item.type === ElementTypes.IMAGE || item.type === ElementTypes.SHAPE) &&
- !item.rotate
- ) return false
- return true
- })
- })
- const setRange = () => {
- const { minX, maxX, minY, maxY } = getElementListRange(localActiveElementList.value)
- range.minX = minX
- range.maxX = maxX
- range.minY = minY
- range.maxY = maxY
- }
- watchEffect(setRange)
- return {
- ...toRefs(range),
- borderLines,
- disableResizablePoint,
- resizablePoints,
- }
- },
- })
- </script>
- <style lang="scss" scoped>
- .multi-select-operate {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 100;
- }
- </style>
|