@@ -34,13 +34,11 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
34
34
private _api ! : AlphaTabApiBase < unknown > ;
35
35
private _contents : string | null = null ;
36
36
private _file : string | null = null ;
37
- private _visibilityCheckIntervalId : number = 0 ;
38
- private _visibilityCheckInterval : number = 0 ;
39
37
private _totalResultCount : number = 0 ;
40
38
private _initialTrackIndexes : number [ ] | null = null ;
39
+ private _intersectionObserver : IntersectionObserver ;
41
40
42
- private _rootContainerBecameVisible : IEventEmitter = new EventEmitter ( ) ;
43
- public rootContainerBecameVisible : IEventEmitter ;
41
+ public rootContainerBecameVisible : IEventEmitter = new EventEmitter ( ) ;
44
42
public canRenderChanged : IEventEmitter = new EventEmitter ( ) ;
45
43
46
44
public get resizeThrottle ( ) : number {
@@ -61,7 +59,7 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
61
59
}
62
60
63
61
let isAnyNotLoaded = false ;
64
- for ( const checker of this . _fontCheckers . values ( ) ) {
62
+ for ( const checker of this . _fontCheckers . values ( ) ) {
65
63
if ( ! checker . isFontLoaded ) {
66
64
isAnyNotLoaded = true ;
67
65
}
@@ -88,29 +86,25 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
88
86
this . areWorkersSupported = 'Worker' in window ;
89
87
Environment . bravuraFontChecker . fontLoaded . on ( this . onFontLoaded . bind ( this ) ) ;
90
88
91
- this . rootContainerBecameVisible = {
92
- on : ( value : any ) => {
93
- if ( this . rootContainer . isVisible ) {
94
- value ( ) ;
95
- } else {
96
- this . _rootContainerBecameVisible . on ( value ) ;
97
-
98
- if ( this . _visibilityCheckIntervalId === 0 ) {
99
- this . _visibilityCheckIntervalId = window . setInterval ( ( ) => {
100
- if ( this . _api . container . isVisible ) {
101
- window . clearInterval ( this . _visibilityCheckIntervalId ) ;
102
- this . _visibilityCheckIntervalId = 0 ;
103
- ( this . _rootContainerBecameVisible as EventEmitter ) . trigger ( ) ;
104
- }
105
- } , this . _visibilityCheckInterval ) ;
106
- }
89
+ this . _intersectionObserver = new IntersectionObserver ( this . onElementVisibilityChanged . bind ( this ) , {
90
+ threshold : [ 0 , 0.01 , 1 ]
91
+ } ) ;
92
+ this . _intersectionObserver . observe ( rootElement ) ;
93
+ }
94
+
95
+ private onElementVisibilityChanged ( entries : IntersectionObserverEntry [ ] ) {
96
+ for ( const e of entries ) {
97
+ if ( e . isIntersecting ) {
98
+ const htmlElement = e . target as HTMLElement ;
99
+ if ( htmlElement === ( this . rootContainer as HtmlElementContainer ) . element ) {
100
+ ( this . rootContainerBecameVisible as EventEmitter ) . trigger ( ) ;
101
+ this . _intersectionObserver . unobserve ( ( this . rootContainer as HtmlElementContainer ) . element ) ;
102
+ } else if ( 'svg' in htmlElement . dataset ) {
103
+ this . replacePlaceholder ( htmlElement , htmlElement . dataset [ 'svg' ] as string ) ;
104
+ this . _intersectionObserver . unobserve ( htmlElement ) ;
107
105
}
108
- } ,
109
-
110
- off : ( value : any ) => {
111
- this . _rootContainerBecameVisible . off ( value ) ;
112
106
}
113
- } ;
107
+ }
114
108
}
115
109
116
110
public createWorkerRenderer ( ) : IScoreRenderer {
@@ -132,10 +126,6 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
132
126
settings . setSongBookModeSettings ( ) ;
133
127
}
134
128
api . settings = settings ;
135
- if ( settings . core . engine === 'default' || settings . core . engine === 'svg' ) {
136
- api . container . scroll . on ( this . showSvgsInViewPort . bind ( this ) ) ;
137
- api . container . resize . on ( this . showSvgsInViewPort . bind ( this ) ) ;
138
- }
139
129
this . setupFontCheckers ( settings ) ;
140
130
141
131
this . _initialTrackIndexes = this . parseTracks ( settings . core . tracks ) ;
@@ -147,8 +137,6 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
147
137
}
148
138
this . createStyleElement ( settings ) ;
149
139
this . _file = settings . core . file ;
150
-
151
- this . _visibilityCheckInterval = settings . core . visibilityCheckInterval ;
152
140
}
153
141
154
142
private setupFontCheckers ( settings : Settings ) : void {
@@ -284,28 +272,6 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
284
272
} ) ;
285
273
}
286
274
287
- private showSvgsInViewPort ( ) : void {
288
- let placeholders : NodeList = ( this . _api . canvasElement as HtmlElementContainer ) . element . querySelectorAll (
289
- '[data-lazy=true]'
290
- ) ;
291
- for ( let i : number = 0 ; i < placeholders . length ; i ++ ) {
292
- let placeholder : HTMLElement = placeholders . item ( i ) as HTMLElement ;
293
- if ( this . isElementInViewPort ( placeholder ) ) {
294
- this . replacePlaceholder ( placeholder , ( placeholder as any ) [ 'svg' ] ) ;
295
- }
296
- }
297
- }
298
-
299
- public isElementInViewPort ( element : HTMLElement ) : boolean {
300
- let rect : DOMRect = element . getBoundingClientRect ( ) ;
301
- return (
302
- rect . top + rect . height >= 0 &&
303
- rect . top <= window . innerHeight &&
304
- rect . left + rect . width >= 0 &&
305
- rect . left <= window . innerWidth
306
- ) ;
307
- }
308
-
309
275
private createStyleElement ( settings : Settings ) : void {
310
276
let elementDocument : HTMLDocument = ( this . _api . container as HtmlElementContainer ) . element . ownerDocument ! ;
311
277
Environment . createStyleElement ( elementDocument , settings . core . fontDirectory ) ;
@@ -402,10 +368,6 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
402
368
while ( canvasElement . childElementCount > this . _totalResultCount ) {
403
369
canvasElement . removeChild ( canvasElement . lastChild ! ) ;
404
370
}
405
- // directly show the elements in the viewport once we're done.
406
- if ( this . _api . settings . core . enableLazyLoading ) {
407
- this . showSvgsInViewPort ( ) ;
408
- }
409
371
} else {
410
372
let body : unknown = renderResult . renderResult ;
411
373
if ( typeof body === 'string' ) {
@@ -419,11 +381,11 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
419
381
placeholder . style . width = renderResult . width + 'px' ;
420
382
placeholder . style . height = renderResult . height + 'px' ;
421
383
placeholder . style . display = 'inline-block' ;
422
- if ( ! this . _api . settings . core . enableLazyLoading || this . isElementInViewPort ( placeholder ) ) {
384
+ if ( ! this . _api . settings . core . enableLazyLoading ) {
423
385
this . replacePlaceholder ( placeholder , body ) ;
424
386
} else {
425
- ( placeholder as any ) [ 'svg' ] = body ;
426
- placeholder . setAttribute ( 'data-lazy' , 'true' ) ;
387
+ placeholder . dataset [ 'svg' ] = body ;
388
+ this . _intersectionObserver . observe ( placeholder ) ;
427
389
}
428
390
} else {
429
391
if ( this . _totalResultCount < canvasElement . childElementCount ) {
0 commit comments