shixian.shi
2023-11-23 adc88bd9e76644badbbe006913addfa7cbe5d89c
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
<script>
    import { on, off, renderThumbStyle, BAR_MAP } from './util'
 
    export default {
        name: 'scrollbar-Bar',
        props: {
            vertical: Boolean,
            size: String,
            move: Number
        },
        computed: {
            bar () {
                return BAR_MAP[this.vertical ? 'vertical' : 'horizontal']
            },
 
            wrap () {
                return this.$parent.wrap
            }
        },
        destroyed () {
            off(document, 'mouseup', this.mouseUpDocumentHandler)
        },
        methods: {
            clickThumbHandler (e) {
                // prevent click event of right button
                if (e.ctrlKey || e.button === 2) {
                    return
                }
                this.startDrag(e)
                this[this.bar.axis] =
                    e.currentTarget[this.bar.offset] -
                    (e[this.bar.client] -
                    e.currentTarget.getBoundingClientRect()[this.bar.direction])
            },
 
            clickTrackHandler (e) {
                const offset = Math.abs(
                    e.target.getBoundingClientRect()[this.bar.direction] -
                        e[this.bar.client]
                )
                const thumbHalf = this.$refs.thumb[this.bar.offset] / 2
                const thumbPositionPercentage =
                    ((offset - thumbHalf) * 100) / this.$el[this.bar.offset]
 
                this.wrap[this.bar.scroll] =
                    (thumbPositionPercentage * this.wrap[this.bar.scrollSize]) /
                    100
            },
 
            startDrag (e) {
                e.stopImmediatePropagation()
                this.cursorDown = true
 
                on(document, 'mousemove', this.mouseMoveDocumentHandler)
                on(document, 'mouseup', this.mouseUpDocumentHandler)
                document.onselectstart = () => false
            },
 
            mouseMoveDocumentHandler (e) {
                if (this.cursorDown === false) return
                const prevPage = this[this.bar.axis]
 
                if (!prevPage) return
 
                const offset =
                    (this.$el.getBoundingClientRect()[this.bar.direction] -
                    e[this.bar.client]) *
                    -1
                const thumbClickPosition =
                    this.$refs.thumb[this.bar.offset] - prevPage
                const thumbPositionPercentage =
                    ((offset - thumbClickPosition) * 100) /
                    this.$el[this.bar.offset]
 
                this.wrap[this.bar.scroll] =
                    (thumbPositionPercentage * this.wrap[this.bar.scrollSize]) /
                    100
            },
 
            mouseUpDocumentHandler (e) {
                this.cursorDown = false
                this[this.bar.axis] = 0
                off(document, 'mousemove', this.mouseMoveDocumentHandler)
                document.onselectstart = null
            }
        },
        render (h) {
            const { size, move, bar } = this
            return (
            <div
                class={['ui-scrollbar__bar', 'is-' + bar.key]}
                onMousedown={this.clickTrackHandler}
            >
                <div
                    ref="thumb"
                    class="ui-scrollbar__thumb"
                    onMousedown={this.clickThumbHandler}
                    style={renderThumbStyle({ size, move, bar })}
                ></div>
            </div>
            )
        }
    }
</script>