@@ -34,13 +34,11 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
3434 private _api ! : AlphaTabApiBase < unknown > ;
3535 private _contents : string | null = null ;
3636 private _file : string | null = null ;
37- private _visibilityCheckIntervalId : number = 0 ;
38- private _visibilityCheckInterval : number = 0 ;
3937 private _totalResultCount : number = 0 ;
4038 private _initialTrackIndexes : number [ ] | null = null ;
39+ private _intersectionObserver : IntersectionObserver ;
4140
42- private _rootContainerBecameVisible : IEventEmitter = new EventEmitter ( ) ;
43- public rootContainerBecameVisible : IEventEmitter ;
41+ public rootContainerBecameVisible : IEventEmitter = new EventEmitter ( ) ;
4442 public canRenderChanged : IEventEmitter = new EventEmitter ( ) ;
4543
4644 public get resizeThrottle ( ) : number {
@@ -61,7 +59,7 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
6159 }
6260
6361 let isAnyNotLoaded = false ;
64- for ( const checker of this . _fontCheckers . values ( ) ) {
62+ for ( const checker of this . _fontCheckers . values ( ) ) {
6563 if ( ! checker . isFontLoaded ) {
6664 isAnyNotLoaded = true ;
6765 }
@@ -88,29 +86,25 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
8886 this . areWorkersSupported = 'Worker' in window ;
8987 Environment . bravuraFontChecker . fontLoaded . on ( this . onFontLoaded . bind ( this ) ) ;
9088
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 ) ;
107105 }
108- } ,
109-
110- off : ( value : any ) => {
111- this . _rootContainerBecameVisible . off ( value ) ;
112106 }
113- } ;
107+ }
114108 }
115109
116110 public createWorkerRenderer ( ) : IScoreRenderer {
@@ -132,10 +126,6 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
132126 settings . setSongBookModeSettings ( ) ;
133127 }
134128 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- }
139129 this . setupFontCheckers ( settings ) ;
140130
141131 this . _initialTrackIndexes = this . parseTracks ( settings . core . tracks ) ;
@@ -147,8 +137,6 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
147137 }
148138 this . createStyleElement ( settings ) ;
149139 this . _file = settings . core . file ;
150-
151- this . _visibilityCheckInterval = settings . core . visibilityCheckInterval ;
152140 }
153141
154142 private setupFontCheckers ( settings : Settings ) : void {
@@ -284,28 +272,6 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
284272 } ) ;
285273 }
286274
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-
309275 private createStyleElement ( settings : Settings ) : void {
310276 let elementDocument : HTMLDocument = ( this . _api . container as HtmlElementContainer ) . element . ownerDocument ! ;
311277 Environment . createStyleElement ( elementDocument , settings . core . fontDirectory ) ;
@@ -402,10 +368,6 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
402368 while ( canvasElement . childElementCount > this . _totalResultCount ) {
403369 canvasElement . removeChild ( canvasElement . lastChild ! ) ;
404370 }
405- // directly show the elements in the viewport once we're done.
406- if ( this . _api . settings . core . enableLazyLoading ) {
407- this . showSvgsInViewPort ( ) ;
408- }
409371 } else {
410372 let body : unknown = renderResult . renderResult ;
411373 if ( typeof body === 'string' ) {
@@ -419,11 +381,11 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
419381 placeholder . style . width = renderResult . width + 'px' ;
420382 placeholder . style . height = renderResult . height + 'px' ;
421383 placeholder . style . display = 'inline-block' ;
422- if ( ! this . _api . settings . core . enableLazyLoading || this . isElementInViewPort ( placeholder ) ) {
384+ if ( ! this . _api . settings . core . enableLazyLoading ) {
423385 this . replacePlaceholder ( placeholder , body ) ;
424386 } else {
425- ( placeholder as any ) [ 'svg' ] = body ;
426- placeholder . setAttribute ( 'data-lazy' , 'true' ) ;
387+ placeholder . dataset [ 'svg' ] = body ;
388+ this . _intersectionObserver . observe ( placeholder ) ;
427389 }
428390 } else {
429391 if ( this . _totalResultCount < canvasElement . childElementCount ) {
0 commit comments