UNPKG

ngx-image-uploader

Version:

Angular2 asynchronous image uploader with preview

2 lines 17.5 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("rxjs"),require("@angular/core"),require("@angular/common/http"),require("@angular/forms"),require("cropperjs"),require("@angular/common")):"function"==typeof define&&define.amd?define("ngx-image-uploader",["exports","rxjs","@angular/core","@angular/common/http","@angular/forms","cropperjs","@angular/common"],t):t(e["ngx-image-uploader"]={},e.rxjs,e.ng.core,e.ng.common.http,e.ng.forms,null,e.ng.common)}(this,function(e,a,r,s,t,i,n){"use strict";i=i&&i.hasOwnProperty("default")?i["default"]:i;var o={Pending:0,Success:1,Error:2,Progress:3};o[o.Pending]="Pending",o[o.Success]="Success",o[o.Error]="Error",o[o.Progress]="Progress";var l=function(e){var t=this;this.status=o.Pending,this.progress=0,this.request=null,this.response=null,this.isPending=function(){return t.status===o.Pending},this.isSuccess=function(){return t.status===o.Success},this.isError=function(){return t.status===o.Error},this.inProgress=function(){return t.status===o.Progress},this.isUploadable=function(){return t.status===o.Pending||t.status===o.Error},this.file=e},d=function(){function e(e){this.http=e}return e.prototype.uploadFile=function(e,t,i){var r=this;this.setDefaults(t);var n=new FormData;n.append(t.fieldName,e,e.name),i&&(n.append("X",i.x.toString()),n.append("Y",i.y.toString()),n.append("Width",i.width.toString()),n.append("Height",i.height.toString()));var o=new s.HttpRequest("POST",t.uploadUrl,n,{reportProgress:!0,withCredentials:t.withCredentials,headers:this._buildHeaders(t)});return a.Observable.create(function(t){var i=new l(e);i.request=r.http.request(o).subscribe(function(e){e.type===s.HttpEventType.UploadProgress?(r._uploadProgress(i,e),t.next(i)):e instanceof s.HttpResponse&&(r._uploadComplete(i,e),t.next(i),t.complete())},function(e){e.error,Error,r._uploadFailed(i,e),t.next(i),t.complete()})})},e.prototype.getFile=function(t,r){var n=this;return a.Observable.create(function(i){var e=new s.HttpHeaders;r.authToken&&(e=e.append("Authorization",r.authTokenPrefix+" "+r.authToken)),n.http.get(t,{responseType:"blob",headers:e}).subscribe(function(e){var t=new File([e],"filename",{type:e.type});i.next(t),i.complete()},function(e){i.error(e.status),i.complete()})})},e.prototype._buildHeaders=function(t){var i=new s.HttpHeaders;return t.authToken&&(i=i.append("Authorization",t.authTokenPrefix+" "+t.authToken)),t.customHeaders&&Object.keys(t.customHeaders).forEach(function(e){i=i.append(e,t.customHeaders[e])}),i},e.prototype._uploadProgress=function(e,t){var i=Math.round(100*t.loaded/t.total);e.progress=i,e.status=o.Progress},e.prototype._uploadComplete=function(e,t){e.progress=100,e.status=o.Success,e.response=t},e.prototype._uploadFailed=function(e,t){e.progress=0,e.status=o.Error,e.response=t},e.prototype.setDefaults=function(e){e.withCredentials=e.withCredentials||!1,e.httpMethod=e.httpMethod||"POST",e.authTokenPrefix=e.authTokenPrefix||"Bearer",e.fieldName=e.fieldName||"file"},e.decorators=[{type:r.Injectable,args:[{providedIn:"root"}]}],e.ctorParameters=function(){return[{type:s.HttpClient}]},e.ngInjectableDef=r.defineInjectable({factory:function(){return new e(r.inject(s.HttpClient))},token:e,providedIn:"root"}),e}();var b="imageupload-resize-area";function c(e,t){var i,r=void 0===t?{}:t,n=r.resizeHeight,o=r.resizeWidth,a=r.resizeQuality,s=void 0===a?.7:a,l=r.resizeType,d=void 0===l?"image/jpeg":l,c=r.resizeMode,p=void 0===c?"fill":c,u=((i=document.getElementById(b))||((i=document.createElement("canvas")).id=b,i.style.display="none",document.body.appendChild(i)),i),h=e.height,g=e.width,m=0,f=0;if("fill"===p){o/n<g/h?g=Math.round(h*o/n):h=Math.round(g*n/o),u.width=o<=g?o:g,u.height=n<=h?n:h,m=e.width/2-g/2,f=e.height/2-h/2,u.getContext("2d").drawImage(e,m,f,g,h,0,0,u.width,u.height)}else{if("fit"!==p)throw new Error("Unknown resizeMode: "+p);h<g?o<g&&(h=Math.round(h*=o/g),g=o):n<h&&(g=Math.round(g*=n/h),h=n),u.width=g,u.height=h,u.getContext("2d").drawImage(e,0,0,g,h)}return u.toDataURL(d,s)}var p={NotSelected:0,Selected:1,Uploading:2,Loading:3,Loaded:4,Error:5};p[p.NotSelected]="NotSelected",p[p.Selected]="Selected",p[p.Uploading]="Uploading",p[p.Loading]="Loading",p[p.Loaded]="Loaded",p[p.Error]="Error";var u=function(){function e(e,t,i){this.renderer=e,this.uploader=t,this.changeDetector=i,this.statusEnum=p,this._status=p.NotSelected,this.thumbnailWidth=150,this.thumbnailHeight=150,this.cropper=undefined,this.upload=new r.EventEmitter,this.statusChange=new r.EventEmitter,this.propagateChange=function(e){}}return Object.defineProperty(e.prototype,"imageThumbnail",{get:function(){return this._imageThumbnail},set:function(e){this._imageThumbnail=e,this.propagateChange(this._imageThumbnail),e!==undefined?this.status=p.Selected:this.status=p.NotSelected},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"errorMessage",{get:function(){return this._errorMessage},set:function(e){this._errorMessage=e,this.status=e?p.Error:p.NotSelected},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"status",{get:function(){return this._status},set:function(e){this._status=e,this.statusChange.emit(e)},enumerable:!0,configurable:!0}),e.prototype.writeValue=function(e){e?this.loadAndResize(e):(this._imageThumbnail=undefined,this.status=p.NotSelected)},e.prototype.registerOnChange=function(e){this.propagateChange=e},e.prototype.registerOnTouched=function(){},e.prototype.ngOnInit=function(){if(this.options&&(this.options.thumbnailWidth&&(this.thumbnailWidth=this.options.thumbnailWidth),this.options.thumbnailHeight&&(this.thumbnailHeight=this.options.thumbnailHeight),this.options.resizeOnLoad===undefined&&(this.options.resizeOnLoad=!0),this.options.autoUpload===undefined&&(this.options.autoUpload=!0),this.options.cropEnabled===undefined&&(this.options.cropEnabled=!1),this.options.autoUpload&&this.options.cropEnabled))throw new Error("autoUpload and cropEnabled cannot be enabled simultaneously")},e.prototype.ngAfterViewChecked=function(){this.options&&this.options.cropEnabled&&this.imageElement&&this.fileToUpload&&!this.cropper&&(this.cropper=new i(this.imageElement.nativeElement,{viewMode:1,aspectRatio:this.options.cropAspectRatio?this.options.cropAspectRatio:null}))},e.prototype.ngOnDestroy=function(){this.cropper&&(this.cropper.destroy(),this.cropper=null)},e.prototype.loadAndResize=function(e){var i=this;this.status=p.Loading,this.uploader.getFile(e,this.options).subscribe(function(e){if(i.options.resizeOnLoad){var t={file:e,url:URL.createObjectURL(e)};i.resize(t).then(function(e){i._imageThumbnail=e.resized.dataURL,i.status=p.Loaded})}else{t={file:null,url:null};i.fileToDataURL(e,t).then(function(e){i._imageThumbnail=e.dataURL,i.status=p.Loaded})}},function(e){i.errorMessage=e||"Error while getting an image"})},e.prototype.onImageClicked=function(){this.renderer.invokeElementMethod(this.fileInputElement.nativeElement,"click")},e.prototype.onFileChanged=function(){var e=this.fileInputElement.nativeElement.files[0];e&&this.validateAndUpload(e)},e.prototype.validateAndUpload=function(t){var i=this;if(this.propagateChange(null),this.options&&this.options.allowedImageTypes&&!this.options.allowedImageTypes.some(function(e){return t.type===e}))this.errorMessage="Only these image types are allowed: "+this.options.allowedImageTypes.join(", ");else if(this.options&&this.options.maxImageSize&&t.size>1024*this.options.maxImageSize*1024)this.errorMessage="Image must not be larger than "+this.options.maxImageSize+" MB";else{this.fileToUpload=t,this.options&&this.options.autoUpload&&this.uploadImage();var e={file:t,url:URL.createObjectURL(t)};this.resize(e).then(function(e){i._imageThumbnail=e.resized.dataURL,i.origImageWidth=e.width,i.orgiImageHeight=e.height,i.options&&!i.options.autoUpload&&(i.status=p.Selected)})}},e.prototype.uploadImage=function(){var e,t=this;if(this.progress=0,this.status=p.Uploading,this.cropper){var i=this.origImageWidth/this.cropper.getImageData().naturalWidth,r=this.cropper.getData();e={x:Math.round(r.x*i),y:Math.round(r.y*i),width:Math.round(r.width*i),height:Math.round(r.height*i)}}this.uploader.uploadFile(this.fileToUpload,this.options,e).subscribe(function(e){t.progress=e.progress,e.isError()&&(e.response.status||e.response.statusText?t.errorMessage=e.response.status+": "+e.response.statusText:t.errorMessage="Error while uploading",t.changeDetector.detectChanges()),e.inProgress()||(e.isSuccess()&&(t.propagateChange(t._imageThumbnail),t.status=p.Selected,t.fileToUpload=undefined),t.upload.emit(e))})},e.prototype.removeImage=function(){this.fileInputElement.nativeElement.value=null,this.imageThumbnail=undefined,this.cropper&&(this.cropper.destroy(),this.cropper=null)},e.prototype.dismissError=function(){this.errorMessage=undefined,this.removeImage()},e.prototype.drop=function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer&&e.dataTransfer.files.length&&(this.validateAndUpload(e.dataTransfer.files[0]),this.updateDragOverlayStyles(!1))},e.prototype.dragenter=function(e){e.preventDefault(),e.stopPropagation()},e.prototype.dragover=function(e){e.preventDefault(),e.stopPropagation(),this.updateDragOverlayStyles(!0)},e.prototype.dragleave=function(e){e.preventDefault(),e.stopPropagation(),this.updateDragOverlayStyles(!1)},e.prototype.updateDragOverlayStyles=function(e){},e.prototype.resize=function(n){var o=this,a={resizeHeight:this.thumbnailHeight,resizeWidth:this.thumbnailWidth,resizeType:n.file.type,resizeMode:this.options.thumbnailResizeMode};return new Promise(function(i){var e,t,r;e=n.url,t=function(e){var t=c(e,a);n.width=e.width,n.height=e.height,n.resized={dataURL:t,type:o.getType(t)},i(n)},(r=new Image).onload=function(){t(r)},r.src=e})},e.prototype.getType=function(e){return e.match(/:(.+\/.+;)/)[1]},e.prototype.fileToDataURL=function(e,r){return new Promise(function(t){var i=new FileReader;i.onload=function(e){r.dataURL=i.result,t(r)},i.readAsDataURL(e)})},e.decorators=[{type:r.Component,args:[{selector:"ngx-image-uploader",template:'<div class="image-container">\n <div class="match-parent" [ngSwitch]="status">\n\n <div class="match-parent" *ngSwitchCase="statusEnum.NotSelected">\n <button type="button" class="add-image-btn" (click)="onImageClicked()">\n <div>\n <p class="plus">+</p>\n <p>Click here to add image</p>\n <p>Or drop image here</p>\n </div>\n </button>\n </div>\n\n <div class="selected-status-wrapper match-parent" *ngSwitchCase="statusEnum.Loaded">\n <img [src]="imageThumbnail" #imageElement>\n\n <button type="button" class="remove" (click)="removeImage()">×</button>\n </div>\n\n <div class="selected-status-wrapper match-parent" *ngSwitchCase="statusEnum.Selected">\n <img [src]="imageThumbnail" #imageElement>\n\n <button type="button" class="remove" (click)="removeImage()">×</button>\n </div>\n\n <div *ngSwitchCase="statusEnum.Uploading">\n <img [attr.src]="imageThumbnail ? imageThumbnail : null" (click)="onImageClicked()">\n\n <div class="progress-bar">\n <div class="bar" [style.width]="progress+\'%\'"></div>\n </div>\n </div>\n\n <div class="match-parent" *ngSwitchCase="statusEnum.Loading">\n <div class="sk-fading-circle">\n <div class="sk-circle1 sk-circle"></div>\n <div class="sk-circle2 sk-circle"></div>\n <div class="sk-circle3 sk-circle"></div>\n <div class="sk-circle4 sk-circle"></div>\n <div class="sk-circle5 sk-circle"></div>\n <div class="sk-circle6 sk-circle"></div>\n <div class="sk-circle7 sk-circle"></div>\n <div class="sk-circle8 sk-circle"></div>\n <div class="sk-circle9 sk-circle"></div>\n <div class="sk-circle10 sk-circle"></div>\n <div class="sk-circle11 sk-circle"></div>\n <div class="sk-circle12 sk-circle"></div>\n </div>\n </div>\n\n <div class="match-parent" *ngSwitchCase="statusEnum.Error">\n <div class="error">\n <div class="error-message">\n <p>{{errorMessage}}</p>\n </div>\n <button type="button" class="remove" (click)="dismissError()">×</button>\n </div>\n </div>\n </div>\n\n <input type="file" #fileInput (change)="onFileChanged()">\n <div class="drag-overlay" [hidden]="true" #dragOverlay></div>\n</div>\n',styles:[":host{display:block}.match-parent{width:100%;height:100%}.add-image-btn{width:100%;height:100%;font-weight:700;opacity:.5;border:0}.add-image-btn:hover{opacity:.7;cursor:pointer;background-color:#ddd;box-shadow:inset 0 0 5px rgba(0,0,0,.3)}.add-image-btn .plus{font-size:30px;font-weight:400;margin-bottom:5px;margin-top:5px}img{cursor:pointer;position:absolute;top:50%;left:50%;margin-right:-50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);max-width:100%}.image-container{width:100%;height:100%;position:relative;display:inline-block;background-color:#f1f1f1;box-shadow:inset 0 0 5px rgba(0,0,0,.2)}.remove{position:absolute;top:0;right:0;width:40px;height:40px;font-size:25px;text-align:center;opacity:.8;border:0;cursor:pointer}.selected-status-wrapper>.remove:hover{opacity:.7;background-color:#fff}.error .remove{opacity:.5}.error .remove:hover{opacity:.7}input{display:none}.error{width:100%;height:100%;border:1px solid #e3a5a2;color:#d2706b;background-color:#fbf1f0;position:relative;text-align:center;display:flex;align-items:center}.error-message{width:100%;line-height:18px}.progress-bar{position:absolute;bottom:10%;left:10%;width:80%;height:5px;background-color:grey;opacity:.9;overflow:hidden}.bar{position:absolute;height:100%;background-color:#a4c639}.drag-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ff0;opacity:.3}.sk-fading-circle{width:40px;height:40px;position:relative;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.sk-fading-circle .sk-circle{width:100%;height:100%;position:absolute;left:0;top:0}.sk-fading-circle .sk-circle:before{content:'';display:block;margin:0 auto;width:15%;height:15%;background-color:#333;border-radius:100%;-webkit-animation:1.2s ease-in-out infinite both sk-circleFadeDelay;animation:1.2s ease-in-out infinite both sk-circleFadeDelay}.sk-fading-circle .sk-circle2{-webkit-transform:rotate(30deg);transform:rotate(30deg)}.sk-fading-circle .sk-circle3{-webkit-transform:rotate(60deg);transform:rotate(60deg)}.sk-fading-circle .sk-circle4{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.sk-fading-circle .sk-circle5{-webkit-transform:rotate(120deg);transform:rotate(120deg)}.sk-fading-circle .sk-circle6{-webkit-transform:rotate(150deg);transform:rotate(150deg)}.sk-fading-circle .sk-circle7{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.sk-fading-circle .sk-circle8{-webkit-transform:rotate(210deg);transform:rotate(210deg)}.sk-fading-circle .sk-circle9{-webkit-transform:rotate(240deg);transform:rotate(240deg)}.sk-fading-circle .sk-circle10{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.sk-fading-circle .sk-circle11{-webkit-transform:rotate(300deg);transform:rotate(300deg)}.sk-fading-circle .sk-circle12{-webkit-transform:rotate(330deg);transform:rotate(330deg)}.sk-fading-circle .sk-circle2:before{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.sk-fading-circle .sk-circle3:before{-webkit-animation-delay:-1s;animation-delay:-1s}.sk-fading-circle .sk-circle4:before{-webkit-animation-delay:-.9s;animation-delay:-.9s}.sk-fading-circle .sk-circle5:before{-webkit-animation-delay:-.8s;animation-delay:-.8s}.sk-fading-circle .sk-circle6:before{-webkit-animation-delay:-.7s;animation-delay:-.7s}.sk-fading-circle .sk-circle7:before{-webkit-animation-delay:-.6s;animation-delay:-.6s}.sk-fading-circle .sk-circle8:before{-webkit-animation-delay:-.5s;animation-delay:-.5s}.sk-fading-circle .sk-circle9:before{-webkit-animation-delay:-.4s;animation-delay:-.4s}.sk-fading-circle .sk-circle10:before{-webkit-animation-delay:-.3s;animation-delay:-.3s}.sk-fading-circle .sk-circle11:before{-webkit-animation-delay:-.2s;animation-delay:-.2s}.sk-fading-circle .sk-circle12:before{-webkit-animation-delay:-.1s;animation-delay:-.1s}@-webkit-keyframes sk-circleFadeDelay{0%,100%,39%{opacity:0}40%{opacity:1}}@keyframes sk-circleFadeDelay{0%,100%,39%{opacity:0}40%{opacity:1}}"],host:{"[style.width]":'thumbnailWidth + "px"',"[style.height]":'thumbnailHeight + "px"'},providers:[{provide:t.NG_VALUE_ACCESSOR,useExisting:r.forwardRef(function(){return e}),multi:!0}]}]}],e.ctorParameters=function(){return[{type:r.Renderer},{type:d},{type:r.ChangeDetectorRef}]},e.propDecorators={imageElement:[{type:r.ViewChild,args:["imageElement"]}],fileInputElement:[{type:r.ViewChild,args:["fileInput"]}],dragOverlayElement:[{type:r.ViewChild,args:["dragOverlay"]}],options:[{type:r.Input}],upload:[{type:r.Output}],statusChange:[{type:r.Output}],drop:[{type:r.HostListener,args:["drop",["$event"]]}],dragenter:[{type:r.HostListener,args:["dragenter",["$event"]]}],dragover:[{type:r.HostListener,args:["dragover",["$event"]]}],dragleave:[{type:r.HostListener,args:["dragleave",["$event"]]}]},e}(),h=function(){function e(){}return e.decorators=[{type:r.NgModule,args:[{imports:[n.CommonModule,s.HttpClientModule],declarations:[u],exports:[u]}]}],e}();e.ImageUploaderService=d,e.Status=p,e.ImageUploaderComponent=u,e.ImageUploaderModule=h,e.FileQueueObject=l,Object.defineProperty(e,"__esModule",{value:!0})}); //# sourceMappingURL=ngx-image-uploader.umd.min.js.map