@@ -78,11 +78,12 @@ export function collectScroller(ele: HTMLElement) {
7878 const scrollerList : HTMLElement [ ] = [ ] ;
7979 let current = ele ?. parentElement ;
8080
81- const scrollStyle = [ 'hidden' , 'scroll' , 'auto' ] ;
81+ const scrollStyle = [ 'hidden' , 'scroll' , 'clip' , ' auto'] ;
8282
8383 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 ) ) ) {
8687 scrollerList . push ( current ) ;
8788 }
8889
@@ -92,8 +93,12 @@ export function collectScroller(ele: HTMLElement) {
9293 return scrollerList ;
9394}
9495
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 ) ;
97102}
98103
99104export interface VisibleArea {
@@ -103,6 +108,28 @@ export interface VisibleArea {
103108 bottom : number ;
104109}
105110
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+ */
106133export function getVisibleArea (
107134 initArea : VisibleArea ,
108135 scrollerList ?: HTMLElement [ ] ,
@@ -115,10 +142,14 @@ export function getVisibleArea(
115142 }
116143
117144 // 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 ) ;
122153
123154 const eleRect = ele . getBoundingClientRect ( ) ;
124155 const {
@@ -128,20 +159,61 @@ export function getVisibleArea(
128159 clientWidth : eleInnerWidth ,
129160 } = ele ;
130161
162+ const borderTopNum = getPxValue ( borderTopWidth ) ;
163+ const borderBottomNum = getPxValue ( borderBottomWidth ) ;
164+ const borderLeftNum = getPxValue ( borderLeftWidth ) ;
165+ const borderRightNum = getPxValue ( borderRightWidth ) ;
166+
131167 const scaleX = toNum (
132168 Math . round ( ( eleRect . width / eleOutWidth ) * 1000 ) / 1000 ,
133169 ) ;
134170 const scaleY = toNum (
135171 Math . round ( ( eleRect . height / eleOutHeight ) * 1000 ) / 1000 ,
136172 ) ;
137173
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+ }
142194
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 ) ;
145217 visibleArea . right = Math . min ( visibleArea . right , eleRight ) ;
146218 visibleArea . bottom = Math . min ( visibleArea . bottom , eleBottom ) ;
147219 } ) ;
0 commit comments