Forked from lukasasorensen/progressiveImageLoader.directive.ts
Created
November 9, 2018 23:56
-
-
Save wesleyegberto/5174d9c44d94a9c4e88a0a5172147cda to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
AfterContentInit, Directive, ElementRef, EventEmitter, Inject, Input, OnDestroy, Output, PLATFORM_ID, | |
Renderer2 | |
} from "@angular/core"; | |
import {isPlatformBrowser} from "@angular/common"; | |
@Directive({ | |
selector: '[image-loader]' | |
}) | |
export class ProgressiveImageLoaderDirective implements AfterContentInit, OnDestroy { | |
private nativeElement: HTMLElement; | |
private cancelOnError: Function; | |
private cancelOnLoad: Function; | |
private largeImage; | |
acceptedSizes = ['sm','md', 'lg']; | |
sizes = { sm: 80, md: 200, lg: 800}; | |
@Input() fallback: string = ''; | |
@Input() imgSize: string; | |
@Output() emitOnError: EventEmitter<any> = new EventEmitter(); | |
constructor(@Inject(PLATFORM_ID) private platformId: Object, | |
private el: ElementRef, | |
private renderer: Renderer2){ | |
} | |
ngAfterContentInit(){ | |
if(this.acceptedSizes.indexOf(this.imgSize) < 0){ | |
console.log("please input a correct size ['sm','md', 'lg']"); | |
return; | |
} | |
this.registerEvents(); | |
} | |
registerEvents(){ | |
this.nativeElement = this.el.nativeElement; | |
this.onError = this.onError.bind(this); | |
this.onLoad = this.onLoad.bind(this); | |
this.cancelOnError = this.renderer.listen(this.nativeElement, 'error', this.onError); | |
this.cancelOnLoad = this.renderer.listen(this.nativeElement, 'load', this.onLoad); | |
} | |
loadLargeImage(url){ | |
url = url + '_' + this.sizes[this.imgSize] + '.jpg'; | |
this.largeImage = new Image(); | |
this.largeImage.src = url; | |
this.largeImage.onload = () => { | |
//console.log('image loaded, ', this.largeImage.src); | |
this.renderer.setAttribute(this.nativeElement, 'src', this.largeImage.src); | |
} | |
} | |
private onError(){ | |
if(this.nativeElement.getAttribute('src') !== this.fallback){ | |
this.renderer.setAttribute(this.nativeElement, 'src', this.fallback); | |
this.emitOnError.emit(); | |
}else{ | |
this.removeOnLoadEvent(); | |
} | |
} | |
private onLoad(){ | |
this.removeOnLoadEvent(); | |
let src = this.nativeElement.getAttribute('src'); | |
let srcSplit = src.split(/[_ ]+/); | |
let strippedArr = srcSplit; | |
strippedArr.pop(); | |
let stripped = strippedArr.join('_'); | |
this.loadLargeImage(stripped); | |
} | |
private removeErrorEvent() { | |
if (this.cancelOnError) { | |
this.cancelOnError(); | |
} | |
} | |
private removeOnLoadEvent() { | |
if (this.cancelOnLoad) { | |
this.cancelOnLoad(); | |
} | |
} | |
ngOnDestroy(){ | |
this.removeErrorEvent(); | |
this.removeOnLoadEvent(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment