1
+ <script lang="ts">
2
+ import { defineComponent , ref , reactive , h , getCurrentInstance , ComponentInternalInstance , PropType , onMounted , nextTick , onBeforeUnmount , computed } from ' vue'
3
+ // @ts-ignore
4
+ import { on , off } from ' @/utils/dom'
5
+ import { renderThumbStyle , BAR_MAP , BaseMap } from ' ./util'
6
+ import { EventType } from ' mitt'
7
+
8
+ export default defineComponent ({
9
+ name: ' Bar' ,
10
+
11
+ props: {
12
+ vertical: Boolean ,
13
+ size: String ,
14
+ move: Number
15
+ },
16
+
17
+ setup(props ) {
18
+ const state = reactive ({
19
+ X: 0 ,
20
+ Y: 0 ,
21
+ cursorDown: false
22
+ })
23
+ const bar = computed (() => {
24
+ return BAR_MAP [props .vertical ? ' vertical' : ' horizontal' ] as BaseMap
25
+ })
26
+ const instance = getCurrentInstance () as ComponentInternalInstance
27
+ const wrap = instance .parent ?.refs .wrap as HTMLElement
28
+ const thumb = instance .refs .thumb as HTMLElement
29
+ const clickTrackHandler = (e : MouseEvent ) => {
30
+ const target = e .target as HTMLElement
31
+
32
+ const { direction, offset, client, scroll, scrollSize} = bar .value
33
+ const el = instance .vnode ?.el as HTMLElement
34
+ const newOffset = Math .abs (target .getBoundingClientRect ()[direction ] - e [client ])
35
+ const thumbHalf = (thumb [offset ] / 2 )
36
+ const thumbPositionPercentage = ((newOffset - thumbHalf ) * 100 / el [offset ])
37
+
38
+ wrap [scroll ] = (thumbPositionPercentage * wrap [scrollSize ] / 100 )
39
+ }
40
+
41
+ const clickThumbHandler = (e : MouseEvent ) => {
42
+ // prevent click event of right button
43
+ if (e .ctrlKey || e .button === 2 ) {
44
+ return
45
+ }
46
+ startDrag (e )
47
+ const { axis, direction, offset, client } = bar .value
48
+ const currentTarget = e .currentTarget as HTMLElement
49
+ state [axis ] = (currentTarget [offset ] - (e [client ] - currentTarget .getBoundingClientRect ()[direction ]))
50
+ }
51
+
52
+ const startDrag = (e : Event ) => {
53
+ e .stopImmediatePropagation ()
54
+ state .cursorDown = true
55
+
56
+ on (document , ' mousemove' , mouseMoveDocumentHandler )
57
+ on (document , ' mouseup' , mouseUpDocumentHandler )
58
+ document .onselectstart = () => false
59
+ }
60
+
61
+ const mouseMoveDocumentHandler = (e : MouseEvent ) => {
62
+ if (state .cursorDown === false ) return
63
+ const { axis, offset, scroll, direction, client, scrollSize } = bar .value
64
+ const prevPage = state [axis ]
65
+
66
+ if (! prevPage ) return
67
+ const el = instance .vnode .el as HTMLElement
68
+
69
+ const newOffset = ((el .getBoundingClientRect ()[direction ] - e [client ]) * - 1 )
70
+ const thumbClickPosition = (thumb [offset ] - prevPage )
71
+ const thumbPositionPercentage = ((newOffset - thumbClickPosition ) * 100 / el [offset ])
72
+
73
+ wrap [scroll ] = (thumbPositionPercentage * wrap [scrollSize ] / 100 )
74
+ }
75
+
76
+ const mouseUpDocumentHandler = (e : Event ) => {
77
+ state .cursorDown = false
78
+ state [bar .value .axis ] = 0
79
+ off (document , ' mousemove' , mouseMoveDocumentHandler )
80
+ document .onselectstart = null
81
+ }
82
+
83
+ return () => {
84
+ const { size, move } = props
85
+ return h (' div' , {
86
+ class: [' el-scrollbar__bar' , ' is-' + bar .value .key ],
87
+ onMousedown: clickTrackHandler
88
+ }, [
89
+ h (' div' , {
90
+ ref: ' thumb' ,
91
+ class: ' el-scrollbar__thumb' ,
92
+ style: renderThumbStyle ({ size , move , bar: bar .value }),
93
+ onMousedown: clickThumbHandler
94
+ })
95
+ ])
96
+ }
97
+ },
98
+
99
+ // destroyed() {
100
+ // off(document, 'mouseup', this.mouseUpDocumentHandler)
101
+ // }
102
+ })
103
+ </script >
0 commit comments