function indexOf ( element , arr ) { for ( let i = 0 ; i < arr . length ; i ++ ) { if ( arr [ i ] === element ) { return i ; } } } function noop ( ) { } export interface PreloadOptions { source : string | string [ ] ; crossOrigin ? : string ; preloadCount ? : number ; initiated ? : ( images : HTMLImageElement [ ] ) => void ; progress ? : ( p : PreloadProgress ) => void ; complete ? : ( images : HTMLImageElement [ ] ) => void ; } export interface PreloadProgress { index : number ; loaded : number ; total : number ; percent : number ; } export function preload ( opts ) { let src ; const input = opts . source ; src = typeof input === 'string' ? [ input ] : input ; const images = [ ] ; const targetCount = ( opts . preloadCount || src . length ) ; const onInitiated = opts . initiated || noop ; const onProgress = opts . progress || noop ; const onComplete = opts . complete || noop ; let count = 0 ; let completed = false ; let firstLoaded = false ; const tick = function ( ) { count += 1 ; onProgress ( { index : indexOf ( this , images ) , loaded : count , total : src . length , percent : Math . round ( ( count / src . length ) * 100 ) } ) ; firstLoaded = firstLoaded || ( this === images [ 0 ] ) ; if ( firstLoaded && ! completed && ( count >= targetCount ) ) { completed = true ; onComplete ( images ) ; } } ; for ( const url of src ) { const img = new Image ( ) ; images . push ( img ) ; img . crossOrigin = opts . crossOrigin ; img . onload = img . onabort = img . onerror = tick ; img . src = url ; } onInitiated ( images ) ; }