@@ -78,11 +78,12 @@ export function collectScroller(ele: HTMLElement) {
78
78
const scrollerList : HTMLElement [ ] = [ ] ;
79
79
let current = ele ?. parentElement ;
80
80
81
- const scrollStyle = [ 'hidden' , 'scroll' , 'auto' ] ;
81
+ const scrollStyle = [ 'hidden' , 'scroll' , 'clip' , ' auto'] ;
82
82
83
83
while ( current ) {
84
- const { overflowX, overflowY } = getWin ( current ) . getComputedStyle ( current ) ;
85
- if ( scrollStyle . includes ( overflowX ) || scrollStyle . includes ( overflowY ) ) {
84
+ const { overflowX, overflowY, overflow } =
85
+ getWin ( current ) . getComputedStyle ( current ) ;
86
+ if ( [ overflowX , overflowY , overflow ] . some ( ( o ) => scrollStyle . includes ( o ) ) ) {
86
87
scrollerList . push ( current ) ;
87
88
}
88
89
@@ -92,8 +93,12 @@ export function collectScroller(ele: HTMLElement) {
92
93
return scrollerList ;
93
94
}
94
95
95
- export function toNum ( num : number ) {
96
- return Number . isNaN ( num ) ? 1 : num ;
96
+ export function toNum ( num : number , defaultValue = 1 ) {
97
+ return Number . isNaN ( num ) ? defaultValue : num ;
98
+ }
99
+
100
+ function getPxValue ( val : string ) {
101
+ return toNum ( parseFloat ( val ) , 0 ) ;
97
102
}
98
103
99
104
export interface VisibleArea {
@@ -103,6 +108,28 @@ export interface VisibleArea {
103
108
bottom : number ;
104
109
}
105
110
111
+ /**
112
+ *
113
+ *
114
+ * **************************************
115
+ * * Border *
116
+ * * ************************** *
117
+ * * * * * *
118
+ * * B * * S * B *
119
+ * * o * * c * o *
120
+ * * r * Content * r * r *
121
+ * * d * * o * d *
122
+ * * e * * l * e *
123
+ * * r ******************** l * r *
124
+ * * * Scroll * *
125
+ * * ************************** *
126
+ * * Border *
127
+ * **************************************
128
+ *
129
+ */
130
+ /**
131
+ * Get visible area of element
132
+ */
106
133
export function getVisibleArea (
107
134
initArea : VisibleArea ,
108
135
scrollerList ?: HTMLElement [ ] ,
@@ -115,10 +142,14 @@ export function getVisibleArea(
115
142
}
116
143
117
144
// Skip if static position which will not affect visible area
118
- const { position } = getWin ( ele ) . getComputedStyle ( ele ) ;
119
- if ( position === 'static' ) {
120
- return ;
121
- }
145
+ const {
146
+ overflow,
147
+ overflowClipMargin,
148
+ borderTopWidth,
149
+ borderBottomWidth,
150
+ borderLeftWidth,
151
+ borderRightWidth,
152
+ } = getWin ( ele ) . getComputedStyle ( ele ) ;
122
153
123
154
const eleRect = ele . getBoundingClientRect ( ) ;
124
155
const {
@@ -128,20 +159,61 @@ export function getVisibleArea(
128
159
clientWidth : eleInnerWidth ,
129
160
} = ele ;
130
161
162
+ const borderTopNum = getPxValue ( borderTopWidth ) ;
163
+ const borderBottomNum = getPxValue ( borderBottomWidth ) ;
164
+ const borderLeftNum = getPxValue ( borderLeftWidth ) ;
165
+ const borderRightNum = getPxValue ( borderRightWidth ) ;
166
+
131
167
const scaleX = toNum (
132
168
Math . round ( ( eleRect . width / eleOutWidth ) * 1000 ) / 1000 ,
133
169
) ;
134
170
const scaleY = toNum (
135
171
Math . round ( ( eleRect . height / eleOutHeight ) * 1000 ) / 1000 ,
136
172
) ;
137
173
138
- const eleScrollWidth = ( eleOutWidth - eleInnerWidth ) * scaleX ;
139
- const eleScrollHeight = ( eleOutHeight - eleInnerHeight ) * scaleY ;
140
- const eleRight = eleRect . x + eleRect . width - eleScrollWidth ;
141
- const eleBottom = eleRect . y + eleRect . height - eleScrollHeight ;
174
+ // Original visible area
175
+ const eleScrollWidth =
176
+ ( eleOutWidth - eleInnerWidth - borderLeftNum - borderRightNum ) * scaleX ;
177
+ const eleScrollHeight =
178
+ ( eleOutHeight - eleInnerHeight - borderTopNum - borderBottomNum ) * scaleY ;
179
+
180
+ // Cut border size
181
+ const scaledBorderTopWidth = borderTopNum * scaleY ;
182
+ const scaledBorderBottomWidth = borderBottomNum * scaleY ;
183
+ const scaledBorderLeftWidth = borderLeftNum * scaleX ;
184
+ const scaledBorderRightWidth = borderRightNum * scaleX ;
185
+
186
+ // Clip margin
187
+ let clipMarginWidth = 0 ;
188
+ let clipMarginHeight = 0 ;
189
+ if ( overflow === 'clip' ) {
190
+ const clipNum = getPxValue ( overflowClipMargin ) ;
191
+ clipMarginWidth = clipNum * scaleX ;
192
+ clipMarginHeight = clipNum * scaleY ;
193
+ }
142
194
143
- visibleArea . left = Math . max ( visibleArea . left , eleRect . x ) ;
144
- visibleArea . top = Math . max ( visibleArea . top , eleRect . y ) ;
195
+ // Region
196
+ const eleLeft = eleRect . x + scaledBorderLeftWidth - clipMarginWidth ;
197
+ const eleTop = eleRect . y + scaledBorderTopWidth - clipMarginHeight ;
198
+
199
+ const eleRight =
200
+ eleLeft +
201
+ eleRect . width +
202
+ 2 * clipMarginWidth -
203
+ scaledBorderLeftWidth -
204
+ scaledBorderRightWidth -
205
+ eleScrollWidth ;
206
+
207
+ const eleBottom =
208
+ eleTop +
209
+ eleRect . height +
210
+ 2 * clipMarginHeight -
211
+ scaledBorderTopWidth -
212
+ scaledBorderBottomWidth -
213
+ eleScrollHeight ;
214
+
215
+ visibleArea . left = Math . max ( visibleArea . left , eleLeft ) ;
216
+ visibleArea . top = Math . max ( visibleArea . top , eleTop ) ;
145
217
visibleArea . right = Math . min ( visibleArea . right , eleRight ) ;
146
218
visibleArea . bottom = Math . min ( visibleArea . bottom , eleBottom ) ;
147
219
} ) ;
0 commit comments