import { Component , ElementRef , EventEmitter , Input , OnInit , Output , Renderer2 } from '@angular/core' ; import { ImageLoader } from '../providers/image-loader' ; import { ImageLoaderConfig } from '../providers/image-loader-config' ; const propMap = { display : 'display' , height : 'height' , width : 'width' , backgroundSize : 'background-size' , backgroundRepeat : 'background-repeat' , } ; export interface ImageAttribute { element : string ; value : string ; } @ Component ( { selector : 'img-loader' , template : '<ion-spinner *ngIf="spinner && isLoading && !fallbackAsPlaceholder" [name]="spinnerName" [color]="spinnerColor"></ion-spinner>' + '<ng-content></ng-content>' , styles : [ 'ion-spinner { float: none; margin-left: auto; margin-right: auto; display: block; }' , ] , } ) export class ImgLoaderComponent implements OnInit { /**
     * Fallback URL to load when the image url fails to load or does not exist.
     */ @ Input ( ) fallbackUrl : string = this . config . fallbackUrl ; /**
     * Whether to show a spinner while the image loads
     */ @ Input ( ) spinner : boolean = this . config . spinnerEnabled ; /**
     * Whether to show the fallback image instead of a spinner while the image loads
     */ @ Input ( ) fallbackAsPlaceholder : boolean = this . config . fallbackAsPlaceholder ; /**
     * Attributes to pass through to img tag if _useImg == true
     */ @ Input ( 'imgAttributes' ) imgAttributes : ImageAttribute [ ] = [ ] ; type { boolean } @ Input ( ) cache = true ; /**
     * Width of the image. This will be ignored if using useImg.
     */ @ Input ( ) width : string = this . config . width ; /**
     * Height of the image. This will be ignored if using useImg.
     */ @ Input ( ) height : string = this . config . height ; /**
     * Display type of the image. This will be ignored if using useImg.
     */ @ Input ( ) display : string = this . config . display ; /**
     * Background size. This will be ignored if using useImg.
     */ @ Input ( ) backgroundSize : string = this . config . backgroundSize ; /**
     * Background repeat. This will be ignored if using useImg.
     */ @ Input ( ) backgroundRepeat : string = this . config . backgroundRepeat ; /**
     * Name of the spinner
     */ @ Input ( ) spinnerName : string = this . config . spinnerName ; /**
     * Color of the spinner
     */ @ Input ( ) spinnerColor : string = this . config . spinnerColor ; /**
     * Notify on image load..
     */ @ Output ( ) load : EventEmitter < ImgLoaderComponent > = new EventEmitter < ImgLoaderComponent > ( ) ; type { boolean } isLoading = true ; element : HTMLElement ; constructor ( private _element , private renderer , private imageLoader , private config ) { } private _useImg : boolean = this . config . useImg ; /**
     * Use <img> tag
     */ @ Input ( ) set useImg ( val ) { this . _useImg = val !== false ; } param val @ Input ( ) set noCache ( val ) { this . cache = val !== false ; } private _src : string ; get src ( ) : string { return this . _src ; } /**
     * The URL of the image to load.
     */ @ Input ( ) set src ( imageUrl ) { this . _src = this . processImageUrl ( imageUrl ) ; this . updateImage ( this . _src ) ; } ; ngOnInit ( ) { if ( this . fallbackAsPlaceholder && this . fallbackUrl ) { this . setImage ( this . fallbackUrl , false ) ; } if ( ! this . src ) { if ( ! this . fallbackAsPlaceholder && this . fallbackUrl ) { this . setImage ( this . fallbackUrl ) ; } else { this . isLoading = false ; } } } private updateImage ( imageUrl ) { this . imageLoader . getImagePath ( imageUrl ) . then ( ( url ) => this . setImage ( url ) ) . catch ( ( error ) => this . setImage ( this . fallbackUrl || imageUrl ) ) ; } returns { string } private processImageUrl ( imageUrl ) { if ( this . cache === false ) { if ( imageUrl . indexOf ( '?' ) === - 1 ) { imageUrl += '?' ; } if ( [ '&' , '?' ] . indexOf ( imageUrl . charAt ( imageUrl . length ) ) === - 1 ) { imageUrl += '&' ; } imageUrl += 'cache_buster=' + Date . now ( ) ; } return imageUrl ; } param imageUrl { string } param stopLoading { boolean } private setImage ( imageUrl , stopLoading = true ) { this . isLoading = ! stopLoading ; if ( this . _useImg ) { if ( ! this . element ) { this . element = this . renderer . createElement ( 'img' ) ; this . renderer . appendChild ( this . _element . nativeElement , this . element ) ; } this . renderer . setAttribute ( this . element , 'src' , imageUrl ) ; this . imgAttributes . forEach ( ( attribute ) => { this . renderer . setAttribute ( this . element , attribute . element , attribute . value ) ; } ) ; if ( this . fallbackUrl && ! this . imageLoader . nativeAvailable ) { this . renderer . listen ( this . element , 'error' , ( ) => this . renderer . setAttribute ( this . element , 'src' , this . fallbackUrl ) ) ; } } else { this . element = this . _element . nativeElement ; for ( const prop in propMap ) { if ( this [ prop ] ) { this . renderer . setStyle ( this . element , propMap [ prop ] , this [ prop ] ) ; } } this . renderer . setStyle ( this . element , 'background-image' , `url("${ imageUrl || this . fallbackUrl }")` ) ; } if ( stopLoading ) { this . load . emit ( this ) ; } } }