|
<template> |
|
<div |
|
class="mobile-operate" |
|
:style="{ |
|
top: elementInfo.top * canvasScale + 'px', |
|
left: elementInfo.left * canvasScale + 'px', |
|
transform: `rotate(${rotate}deg)`, |
|
transformOrigin: `${elementInfo.width * canvasScale / 2}px ${elementInfo.height * canvasScale / 2}px`, |
|
}" |
|
> |
|
<template v-if="isSelected"> |
|
<BorderLine |
|
class="operate-border-line" |
|
v-for="line in borderLines" |
|
:key="line.type" |
|
:type="line.type" |
|
:style="line.style" |
|
/> |
|
<ResizeHandler |
|
class="operate-resize-handler" |
|
v-for="point in resizeHandlers" |
|
:key="point.direction" |
|
:type="point.direction" |
|
:rotate="elementInfo.rotate" |
|
:style="point.style" |
|
@touchstart.stop="$event => scaleElement($event, elementInfo, point.direction)" |
|
/> |
|
<RotateHandler |
|
class="operate-rotate-handler" |
|
:style="{ left: scaleWidth / 2 + 'px' }" |
|
v-if="!cannotRotate" |
|
@touchstart.stop="$event => rotateElement($event, elementInfo as CanRotatePPTElement)" |
|
/> |
|
</template> |
|
</div> |
|
</template> |
|
|
|
<script lang="ts" setup> |
|
import { computed } from 'vue' |
|
import type { PPTElement, PPTLineElement, PPTChartElement, PPTVideoElement, PPTAudioElement } from '@/types/slides' |
|
import useCommonOperate from '@/views/Editor/Canvas/hooks/useCommonOperate' |
|
import type { OperateResizeHandlers } from '@/types/edit' |
|
|
|
import BorderLine from '@/views/Editor/Canvas/Operate/BorderLine.vue' |
|
import ResizeHandler from '@/views/Editor/Canvas/Operate/ResizeHandler.vue' |
|
import RotateHandler from '@/views/Editor/Canvas/Operate/RotateHandler.vue' |
|
|
|
type CanRotatePPTElement = Exclude<PPTElement, PPTChartElement | PPTLineElement | PPTVideoElement | PPTAudioElement> |
|
|
|
const props = defineProps<{ |
|
elementInfo: Exclude<PPTElement, PPTLineElement> |
|
isSelected: boolean |
|
canvasScale: number |
|
scaleElement: (e: MouseEvent, element: Exclude<PPTElement, PPTLineElement>, command: OperateResizeHandlers) => void |
|
rotateElement: (e: MouseEvent, element: CanRotatePPTElement) => void |
|
}>() |
|
|
|
const rotate = computed(() => 'rotate' in props.elementInfo ? props.elementInfo.rotate : 0) |
|
|
|
const scaleWidth = computed(() => props.elementInfo.width * props.canvasScale) |
|
const scaleHeight = computed(() => props.elementInfo.height * props.canvasScale) |
|
const { |
|
borderLines, |
|
resizeHandlers: _resizeHandlers, |
|
textElementResizeHandlers, |
|
} = useCommonOperate(scaleWidth, scaleHeight) |
|
|
|
const resizeHandlers = props.elementInfo.type === 'text' || props.elementInfo.type === 'table' ? textElementResizeHandlers : _resizeHandlers |
|
|
|
const cannotRotate = computed(() => ['chart', 'video', 'audio'].includes(props.elementInfo.type)) |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.mobile-operate { |
|
position: absolute; |
|
z-index: 100; |
|
user-select: none; |
|
} |
|
</style> |