File size: 3,901 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<template>
  <div class="line-element-operate">
    <template v-if="handlerVisible">
      <ResizeHandler
        class="operate-resize-handler" 
        v-for="point in resizeHandlers"
        :key="point.handler"
        :style="point.style"
        @mousedown.stop="$event => dragLineElement($event, elementInfo, point.handler)"
      />

      <svg 
        :width="svgWidth || 1" 
        :height="svgHeight || 1" 
        :stroke="elementInfo.color"
        overflow="visible" 
        :style="{ transform: `scale(${canvasScale})` }"
      >
        <template v-if="elementInfo.curve">
          <g>
            <line class="anchor-line" :x1="elementInfo.start[0]" :y1="elementInfo.start[1]" :x2="elementInfo.curve[0]" :y2="elementInfo.curve[1]"></line>
            <line class="anchor-line" :x1="elementInfo.end[0]" :y1="elementInfo.end[1]" :x2="elementInfo.curve[0]" :y2="elementInfo.curve[1]"></line>
          </g>
        </template>
        <template v-if="elementInfo.cubic">
          <g v-for="(item, index) in elementInfo.cubic" :key="index">
            <line class="anchor-line" v-if="index === 0" :x1="elementInfo.start[0]" :y1="elementInfo.start[1]" :x2="item[0]" :y2="item[1]"></line>
            <line class="anchor-line" v-if="index === 1" :x1="elementInfo.end[0]" :y1="elementInfo.end[1]" :x2="item[0]" :y2="item[1]"></line>
          </g>
        </template>
      </svg>
    </template>
  </div>
</template>

<script lang="ts">
export default {
  inheritAttrs: false,
}
</script>

<script lang="ts" setup>
import { computed } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore } from '@/store'
import type { PPTLineElement } from '@/types/slides'
import { OperateLineHandlers } from '@/types/edit'

import ResizeHandler from './ResizeHandler.vue'

const props = defineProps<{
  elementInfo: PPTLineElement
  handlerVisible: boolean
  dragLineElement: (e: MouseEvent, element: PPTLineElement, command: OperateLineHandlers) => void
}>()

const { canvasScale } = storeToRefs(useMainStore())

const svgWidth = computed(() => Math.max(props.elementInfo.start[0], props.elementInfo.end[0]))
const svgHeight = computed(() => Math.max(props.elementInfo.start[1], props.elementInfo.end[1]))

const resizeHandlers = computed(() => {
  const handlers = [
    {
      handler: OperateLineHandlers.START,
      style: {
        left: props.elementInfo.start[0] * canvasScale.value + 'px',
        top: props.elementInfo.start[1] * canvasScale.value + 'px',
      }
    },
    {
      handler: OperateLineHandlers.END,
      style: {
        left: props.elementInfo.end[0] * canvasScale.value + 'px',
        top: props.elementInfo.end[1] * canvasScale.value + 'px',
      }
    },
  ]

  if (props.elementInfo.curve || props.elementInfo.broken || props.elementInfo.broken2) {
    const ctrlHandler = (props.elementInfo.curve || props.elementInfo.broken || props.elementInfo.broken2) as [number, number]

    handlers.push({
      handler: OperateLineHandlers.C,
      style: {
        left: ctrlHandler[0] * canvasScale.value + 'px',
        top: ctrlHandler[1] * canvasScale.value + 'px',
      }
    })
  }
  else if (props.elementInfo.cubic) {
    const [ctrlHandler1, ctrlHandler2] = props.elementInfo.cubic
    handlers.push({
      handler: OperateLineHandlers.C1,
      style: {
        left: ctrlHandler1[0] * canvasScale.value + 'px',
        top: ctrlHandler1[1] * canvasScale.value + 'px',
      }
    })
    handlers.push({
      handler: OperateLineHandlers.C2,
      style: {
        left: ctrlHandler2[0] * canvasScale.value + 'px',
        top: ctrlHandler2[1] * canvasScale.value + 'px',
      }
    })
  }

  return handlers
})
</script>

<style lang="scss" scoped>
svg {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
  transform-origin: 0 0;
}
.anchor-line {
  stroke-width: 1px;
  stroke-dasharray: 5 5;
  opacity: .5;
}
</style>