File size: 2,861 Bytes
89ce340
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<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>