返回 slidev
Arrow.vue
根目录 / packages / client / builtin / Arrow.vue
1 <!--
2
3 Simple Arrow
4
5 <arrow x1="10" y1="20" x2="100" y2="200" color="green" width="3" />
6
7 <arrow v-bind="{ x1:10, y1:10, x2:200, y2:200 }"/>
8
9 -->
10
11 <script setup lang="ts">
12 import { onClickOutside } from '@vueuse/core'
13 import { ref } from 'vue'
14 import { makeId } from '../logic/utils'
15
16 defineProps<{
17 x1: number | string
18 y1: number | string
19 x2: number | string
20 y2: number | string
21 width?: number | string
22 color?: string
23 twoWay?: boolean
24 }>()
25
26 const emit = defineEmits(['dblclick', 'clickOutside'])
27
28 const id = makeId()
29
30 const markerAttrs = {
31 markerUnits: 'strokeWidth',
32 markerHeight: 7,
33 refY: 3.5,
34 orient: 'auto',
35 }
36
37 const clickArea = ref<HTMLElement>()
38 onClickOutside(clickArea, () => emit('clickOutside'))
39 </script>
40
41 <template>
42 <svg
43 class="absolute left-0 top-0"
44 :width="Math.max(+x1, +x2) + 50"
45 :height="Math.max(+y1, +y2) + 50"
46 >
47 <defs>
48 <marker :id="id" markerWidth="10" refX="9" v-bind="markerAttrs">
49 <polygon points="0 0, 10 3.5, 0 7" :fill="color || 'currentColor'" @dblclick="emit('dblclick')" />
50 </marker>
51 <marker v-if="twoWay" :id="`${id}-rev`" markerWidth="20" refX="11" v-bind="markerAttrs">
52 <polygon points="20 0, 10 3.5, 20 7" :fill="color || 'currentColor'" @dblclick="emit('dblclick')" />
53 </marker>
54 </defs>
55 <line
56 :x1 :y1 :x2 :y2
57 :stroke="color || 'currentColor'"
58 :stroke-width="width || 2"
59 :marker-end="`url(#${id})`"
60 :marker-start="twoWay ? `url(#${id}-rev)` : 'none'"
61 @dblclick="emit('dblclick')"
62 />
63 <line
64 ref="clickArea"
65 :x1 :y1 :x2 :y2
66 stroke="transparent"
67 stroke-linecap="round"
68 :stroke-width="20"
69 @dblclick="emit('dblclick')"
70 />
71 </svg>
72 </template>
73
73 lines Plain Text