@@ -3,18 +3,22 @@ import type { CSSProperties } from 'vue';
33
44const { y, x } = useWindowScroll ();
55const { height : winH, width : winW } = useWindowSize ();
6- const body = useElementBounding (document .body );
6+ const [bodyH, bodyW] = (() => {
7+ const body = useElementSize (document .body );
8+ // 不知道为什么得到的 w/h 比实际 clientHeight/clientWidth 多出 0.2 或 0.4, 使用 Math.floor 去除
9+ return [
10+ computed (() => Math .floor (body .height .value )),
11+ computed (() => Math .floor (body .width .value )),
12+ ];
13+ })();
714
8- const yShow = computed (() => body . height .value > winH .value );
15+ const yShow = computed (() => bodyH .value > winH .value );
916const yHeight = computed (() => {
10- const clientHeight = body .height .value ;
11- const bodyHeight = clientHeight ;
12- return (winH .value / bodyHeight ) * winH .value ;
17+ return (winH .value / bodyH .value ) * winH .value ;
1318});
1419const translateY = computed (() => {
15- const clientHeight = body .height .value ;
1620 const height = yHeight .value ;
17- return (y .value / (clientHeight - winH .value )) * (winH .value - height );
21+ return (y .value / (bodyH . value - winH .value )) * (winH .value - height );
1822});
1923const yStyle = computed <CSSProperties >(() => {
2024 if (! yShow .value ) return {};
@@ -28,10 +32,8 @@ const clickBoxY = async (e: MouseEvent) => {
2832 yHeight .value *
2933 0.9 *
3034 (e .clientY < yHeight .value + translateY .value ? - 1 : 1 );
31- const clientHeight = body .height .value ;
32- const bodyHeight = clientHeight ;
33- const height = (winH .value / bodyHeight ) * winH .value ;
34- y .value += (deltaY / (winH .value - height )) * (clientHeight - winH .value );
35+ const height = (winH .value / bodyH .value ) * winH .value ;
36+ y .value += (deltaY / (winH .value - height )) * (bodyH .value - winH .value );
3537};
3638const yDragging = shallowRef (false );
3739let lastYEvent: MouseEvent | undefined = undefined ;
@@ -43,27 +45,21 @@ useEventListener('pointermove', (e) => {
4345 if (! lastYEvent ) return ;
4446 const deltaY = e .clientY - lastYEvent .clientY ;
4547 lastYEvent = e ;
46- const clientHeight = body .height .value ;
47- const bodyHeight = clientHeight ;
48- const height = (winH .value / bodyHeight ) * winH .value ;
49- y .value += (deltaY / (winH .value - height )) * (clientHeight - winH .value );
48+ const height = (winH .value / bodyH .value ) * winH .value ;
49+ y .value += (deltaY / (winH .value - height )) * (bodyH .value - winH .value );
5050});
5151useEventListener (' pointerup' , () => {
5252 lastYEvent = undefined ;
5353 yDragging .value = false ;
5454});
5555
56- // 不知道为什么 body_width 比 win_width 多出 0.2 或 0.4, 使用 Math.floor 去除
57- const xShow = computed (() => Math .floor (body .width .value ) > winW .value );
56+ const xShow = computed (() => bodyW .value > winW .value );
5857const xWidth = computed (() => {
59- const clientWidth = body .width .value ;
60- const bodyWidth = clientWidth ;
61- return (winW .value / bodyWidth ) * winW .value ;
58+ return (winW .value / bodyW .value ) * winW .value ;
6259});
6360const translateX = computed (() => {
64- const clientWidth = body .width .value ;
6561 const width = xWidth .value ;
66- return (x .value / (clientWidth - winW .value )) * (winW .value - width );
62+ return (x .value / (bodyW . value - winW .value )) * (winW .value - width );
6763});
6864const xStyle = computed <CSSProperties >(() => {
6965 if (! xShow .value ) return {};
@@ -76,11 +72,10 @@ const xStyle = computed<CSSProperties>(() => {
7672const clickBoxX = (e : MouseEvent ) => {
7773 const deltaX =
7874 xWidth .value * 0.9 * (e .clientX < xWidth .value + translateX .value ? - 1 : 1 );
79- const clientWidth = body .width .value ;
80- const bodyWidth = clientWidth ;
81- const width = (winW .value / bodyWidth ) * winW .value ;
75+
76+ const width = (winW .value / bodyW .value ) * winW .value ;
8277 const newX =
83- x .value + (deltaX / (winW .value - width )) * (clientWidth - winW .value );
78+ x .value + (deltaX / (winW .value - width )) * (bodyW . value - winW .value );
8479 x .value = newX ;
8580};
8681const xDragging = shallowRef (false );
@@ -93,10 +88,9 @@ useEventListener('pointermove', (e) => {
9388 if (! lastXEvent ) return ;
9489 const deltaX = e .clientX - lastXEvent .clientX ;
9590 lastXEvent = e ;
96- const clientWidth = body .width .value ;
97- const bodyWidth = clientWidth ;
98- const width = (winW .value / bodyWidth ) * winW .value ;
99- x .value += (deltaX / (winW .value - width )) * (clientWidth - winW .value );
91+
92+ const width = (winW .value / bodyW .value ) * winW .value ;
93+ x .value += (deltaX / (winW .value - width )) * (bodyW .value - winW .value );
10094});
10195useEventListener (' pointerup' , () => {
10296 lastXEvent = undefined ;
@@ -108,28 +102,33 @@ useEventListener('selectstart', (e) => {
108102 e .preventDefault ();
109103 }
110104});
105+ const bodyHoverd = useElementHover (document .body );
111106 </script >
112107<template >
113- <div fixed z-2000 class =" BodyScrollbar" >
108+ <div v-if = " yShow || xShow " class =" BodyScrollbar" fixed z-2000 >
114109 <div
115- v-show =" yShow"
110+ v-if =" yShow"
116111 scrollbar-y
117112 fixed
118113 right-2px
119114 top-0
120115 bottom-0
121116 w-8px
117+ :data-win-h =" winH"
118+ :data-body-h =" bodyW"
122119 @pointerdown =" pointerdownY"
123120 @click =" clickBoxY"
124121 >
125122 <div
126123 w-full
127- bg =" #909399"
128- opacity-30
129- hover:opacity =" 50"
124+ rounded-4px
125+ transition-colors
126+ bg =" #9093994c"
127+ hover:bg =" #9093997f"
130128 :style =" yStyle"
131129 :class =" {
132- 'opacity-50': yDragging,
130+ 'bg-#9093997f': yDragging,
131+ 'bg-#0000!': !bodyHoverd,
133132 }"
134133 @click.stop
135134 />
@@ -142,17 +141,21 @@ useEventListener('selectstart', (e) => {
142141 left-0
143142 right-0
144143 h-8px
144+ :data-win-w =" winW"
145+ :data-body-w =" bodyW"
145146 @pointerdown =" pointerdownX"
146147 @click =" clickBoxX"
147148 >
148149 <div
149150 h-full
150- bg =" #909399"
151- opacity-30
152- hover:opacity =" 50"
151+ rounded-4px
152+ transition-colors
153+ bg =" #9093994c"
154+ hover:bg =" #9093997f"
153155 :style =" xStyle"
154156 :class =" {
155- 'opacity-50': xDragging,
157+ 'bg-#9093997f': xDragging,
158+ 'bg-#0000!': !bodyHoverd,
156159 }"
157160 @click.stop
158161 />
0 commit comments