-
Notifications
You must be signed in to change notification settings - Fork 14
/
link.vue
93 lines (83 loc) · 2.04 KB
/
link.vue
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
<template>
<g class="link">
<line
:x1="link.source.x"
:y1="link.source.y"
:x2="link.target.x"
:y2="link.target.y"
class="shadow"
@mouseenter.stop.prevent="$emit('mouseenter', link, $event)"
@mouseleave.stop.prevent="$emit('mouseleave', link, $event)"
/>
<line
:x1="link.source.x"
:y1="link.source.y"
:x2="arrow.x0"
:y2="arrow.y0"
:class="link.type"
/>
<line
:x1="arrow.x0"
:y1="arrow.y0"
:x2="arrow.x1"
:y2="arrow.y1"
/>
<line
:x1="arrow.x0"
:y1="arrow.y0"
:x2="arrow.x2"
:y2="arrow.y2"
/>
</g>
</template>
<script lang="ts" setup>
import { Link, constants } from './utils'
import { computed } from 'vue'
const props = defineProps<{
link: Link
}>()
defineEmits(['mouseenter', 'mouseleave'])
const arrow = computed(() => {
const { source, target } = props.link
const dx = target.x - source.x
const dy = target.y - source.y
const theta = Math.atan2(dy, dx)
const x0 = target.x - constants.arrowOffset * Math.cos(theta)
const y0 = target.y - constants.arrowOffset * Math.sin(theta)
const x1 = x0 - constants.arrowLength * Math.cos(theta - constants.arrowAngle)
const y1 = y0 - constants.arrowLength * Math.sin(theta - constants.arrowAngle)
const x2 = x0 - constants.arrowLength * Math.cos(theta + constants.arrowAngle)
const y2 = y0 - constants.arrowLength * Math.sin(theta + constants.arrowAngle)
return { x0, y0, x1, y1, x2, y2 }
})
</script>
<style lang="scss" scoped>
g.link {
line {
transition: 0.3s ease;
&:hover {
stroke-width: 5;
}
&.dashed {
stroke-dasharray: 6 6;
}
&.shadow {
stroke: transparent !important;
stroke-width: 6;
cursor: pointer;
}
&:not(.shadow) {
stroke: var(--k-text-light);
stroke-opacity: 0.3;
stroke-width: 3;
pointer-events: none;
}
}
.has-highlight &:not(.highlight) line {
stroke-opacity: 0.1;
}
&.highlight line {
stroke: var(--k-text-dark);
}
}
</style>