angular-x-image-viewer
Version:
A configurable Angular image viewer component, compatible with Angular 7.x+
16 lines (14 loc) • 11.8 kB
JavaScript
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@angular/core"),require("@angular/common"),require("@angular/platform-browser")):"function"==typeof define&&define.amd?define("angular-x-image-viewer",["exports","@angular/core","@angular/common","@angular/platform-browser"],n):n((t=t||self)["angular-x-image-viewer"]={},t.ng.core,t.ng.common,t.ng.platformBrowser)}(this,(function(t,n,e,o){"use strict";
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */var i=function(){return(i=Object.assign||function(t){for(var n,e=1,o=arguments.length;e<o;e++)for(var i in n=arguments[e])Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i]);return t}).apply(this,arguments)};function r(t,n,e,o){var i,r=arguments.length,s=r<3?n:null===o?o=Object.getOwnPropertyDescriptor(n,e):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,n,e,o);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(r<3?i(s):r>3?i(n,e,s):i(n,e))||s);return r>3&&s&&Object.defineProperty(n,e,s),s}function s(t,n){return function(e,o){n(e,o,t)}}var a=function(t,n){this.name=t,this.imageIndex=n},c={btnClass:"default",zoomFactor:.1,containerBackgroundColor:"#ccc",wheelZoom:!1,allowFullscreen:!0,allowKeyboardNavigation:!0,btnShow:{zoomIn:!0,zoomOut:!0,rotateClockwise:!0,rotateCounterClockwise:!0,next:!0,prev:!0},btnIcons:{zoomIn:"fa fa-plus",zoomOut:"fa fa-minus",rotateClockwise:"fa fa-repeat",rotateCounterClockwise:"fa fa-undo",next:"fa fa-arrow-right",prev:"fa fa-arrow-left",fullscreen:"fa fa-arrows-alt"}},l=function(){function t(t,e){this.moduleConfig=t,this.sanitizer=e,this.index=0,this.indexChange=new n.EventEmitter,this.configChange=new n.EventEmitter,this.customImageEvent=new n.EventEmitter,this.styleHeight="98vh",this.style={transform:"",msTransform:"",oTransform:"",webkitTransform:""},this.fullscreen=!1,this.loading=!0,this.scale=1,this.rotation=0,this.translateX=0,this.translateY=0,this.hovered=!1}return t.prototype.ngOnChanges=function(t){t.screenHeightOccupied&&(this.styleHeight="calc(98vh - "+this.screenHeightOccupied+"px)")},t.prototype.ngOnInit=function(){var t=this.mergeConfig(c,this.moduleConfig);this.config=this.mergeConfig(t,this.config),this.triggerConfigBinding()},t.prototype.nextImage=function(t){this.canNavigate(t)&&this.index<this.src.length-1&&(this.loading=!0,this.index++,this.triggerIndexBinding(),this.reset())},t.prototype.prevImage=function(t){this.canNavigate(t)&&this.index>0&&(this.loading=!0,this.index--,this.triggerIndexBinding(),this.reset())},t.prototype.zoomIn=function(){this.scale*=1+this.config.zoomFactor,this.updateStyle()},t.prototype.zoomOut=function(){this.scale>this.config.zoomFactor&&(this.scale/=1+this.config.zoomFactor),this.updateStyle()},t.prototype.scrollZoom=function(t){if(this.config.wheelZoom)return t.deltaY>0?this.zoomOut():this.zoomIn(),!1},t.prototype.rotateClockwise=function(){this.rotation+=90,this.updateStyle()},t.prototype.rotateCounterClockwise=function(){this.rotation-=90,this.updateStyle()},t.prototype.onLoad=function(t){console.log("Loading Image Done:",t),this.loading=!1},t.prototype.onLoadStart=function(t){console.log("Loading Image:",t),this.loading=!0},t.prototype.imageNotFound=function(t){console.log("Image not found Url:",t)},t.prototype.onDragOver=function(t){this.translateX+=t.clientX-this.prevX,this.translateY+=t.clientY-this.prevY,this.prevX=t.clientX,this.prevY=t.clientY,this.updateStyle()},t.prototype.onDragStart=function(t){t.dataTransfer&&t.dataTransfer.setDragImage&&t.dataTransfer.setDragImage(t.target.nextElementSibling,0,0),this.prevX=t.clientX,this.prevY=t.clientY},t.prototype.toggleFullscreen=function(){this.fullscreen=!this.fullscreen,this.fullscreen||this.reset()},t.prototype.triggerIndexBinding=function(){this.indexChange.emit(this.index)},t.prototype.triggerConfigBinding=function(){this.configChange.next(this.config)},t.prototype.fireCustomEvent=function(t,n){this.customImageEvent.emit(new a(t,n))},t.prototype.reset=function(){this.scale=1,this.rotation=0,this.translateX=0,this.translateY=0,this.updateStyle()},t.prototype.onMouseOver=function(){this.hovered=!0},t.prototype.onMouseLeave=function(){this.hovered=!1},t.prototype.canNavigate=function(t){return null==t||this.config.allowKeyboardNavigation&&this.hovered},t.prototype.updateStyle=function(){this.style.transform="translate("+this.translateX+"px, "+this.translateY+"px) rotate("+this.rotation+"deg) scale("+this.scale+")",this.style.msTransform=this.style.transform,this.style.webkitTransform=this.style.transform,this.style.oTransform=this.style.transform},t.prototype.mergeConfig=function(t,n){var e=i({},t);return n&&(e=i(i({},t),n),n.btnIcons&&(e.btnIcons=i(i({},t.btnIcons),n.btnIcons))),e},t.ctorParameters=function(){return[{type:void 0,decorators:[{type:n.Optional},{type:n.Inject,args:["config"]}]},{type:o.DomSanitizer}]},r([n.Input()],t.prototype,"src",void 0),r([n.Input()],t.prototype,"screenHeightOccupied",void 0),r([n.Input()],t.prototype,"index",void 0),r([n.Input()],t.prototype,"config",void 0),r([n.Output()],t.prototype,"indexChange",void 0),r([n.Output()],t.prototype,"configChange",void 0),r([n.Output()],t.prototype,"customImageEvent",void 0),r([n.HostListener("window:keyup.ArrowRight",["$event"])],t.prototype,"nextImage",null),r([n.HostListener("window:keyup.ArrowLeft",["$event"])],t.prototype,"prevImage",null),r([n.HostListener("mouseover")],t.prototype,"onMouseOver",null),r([n.HostListener("mouseleave")],t.prototype,"onMouseLeave",null),t=r([n.Component({selector:"angular-image-viewer",template:'<div [appScreenfull]="fullscreen" class="img-container" [style.height]="styleHeight"\n [style.backgroundColor]="config.containerBackgroundColor" (wheel)="scrollZoom($event)"\n (dragover)="onDragOver($event)">\n <img [src]="src[index]" [ngStyle]="style" alt="Image not found..." (dragstart)="onDragStart($event)"\n (load)="onLoad(src[index])" (error)="imageNotFound(src[index])" (loadstart)="onLoadStart(src[index])" />\n \x3c!-- Div below will be used to hide the \'ghost\' image when dragging --\x3e\n <div></div>\n <div class="spinner-container" *ngIf="loading">\n <div class="spinner"></div>\n </div>\n\n <button type="button" [class]="config.btnClass" *ngIf="config.btnShow.rotateCounterClockwise"\n (click)="rotateCounterClockwise()">\n <span [class]="config.btnIcons.rotateCounterClockwise"></span>\n </button>\n <button type="button" [class]="config.btnClass" *ngIf="config.btnShow.rotateClockwise" (click)="rotateClockwise()">\n <span [class]="config.btnIcons.rotateClockwise"></span>\n </button>\n\n <button type="button" [class]="config.btnClass" *ngIf="config.btnShow.zoomOut" (click)="zoomOut()">\n <span [class]="config.btnIcons.zoomOut"></span>\n </button>\n <button type="button" [class]="config.btnClass" *ngIf="config.btnShow.zoomIn" (click)="zoomIn()">\n <span [class]="config.btnIcons.zoomIn"></span>\n </button>\n\n <button type="button" [class]="config.btnClass" *ngFor="let cBtn of config.customBtns"\n (click)="fireCustomEvent(cBtn.name, index)">\n <span [class]="cBtn.icon"></span>\n </button>\n\n <button type="button" id="ngx-fs-btn" [class]="config.btnClass" (click)="toggleFullscreen()"\n *ngIf="config.allowFullscreen">\n <span [class]="config.btnIcons.fullscreen"></span>\n </button>\n\n <div class="nav-button-container" *ngIf="src.length > 1">\n <button type="button" [class]="config.btnClass" (click)="prevImage($event)" [disabled]="index === 0">\n <span [class]="config.btnIcons.prev"></span>\n </button>\n <button type="button" [class]="config.btnClass" (click)="nextImage($event)"\n [disabled]="index === src.length - 1">\n <span [class]="config.btnIcons.next"></span>\n </button>\n </div>\n</div>',styles:[".img-container{width:100%;display:-webkit-box;display:flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;overflow:hidden}.img-container img{max-width:90%;max-height:95%}.img-container button{z-index:99;position:absolute;right:15px}.img-container button:not(:disabled){cursor:pointer}.img-container>button:nth-of-type(1):not(#ngx-fs-btn){bottom:15px}.img-container>button:nth-of-type(2):not(#ngx-fs-btn){bottom:65px}.img-container>button:nth-of-type(3):not(#ngx-fs-btn){bottom:115px}.img-container>button:nth-of-type(4):not(#ngx-fs-btn){bottom:165px}.img-container>button:nth-of-type(5):not(#ngx-fs-btn){bottom:215px}.img-container>button:nth-of-type(6):not(#ngx-fs-btn){bottom:265px}.img-container>button:nth-of-type(7):not(#ngx-fs-btn){bottom:315px}#ngx-fs-btn{top:15px}button.default{height:40px;width:40px;border:1px solid #555;border-radius:50%;background-color:#fff;opacity:.7;-webkit-transition:opacity .2s;transition:opacity .2s}button.default:hover{opacity:1}button.default:disabled{opacity:.25}.nav-button-container>button{position:relative;right:0;margin:0 10px}.nav-button-container{text-align:center;position:absolute;z-index:98;bottom:10px;left:0;right:0}.spinner-container{position:absolute;left:0;right:0;top:0;bottom:0;width:60px;height:60px;margin:auto;padding:10px;background-color:rgba(0,0,0,.4);border-radius:25%}.spinner{border-width:7px;border-style:solid;border-color:#ccc #ccc #222;border-radius:50%;height:100%;width:100%;box-sizing:border-box;-webkit-animation:2s linear infinite rotation;animation:2s linear infinite rotation}@keyframes rotation{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(359deg)}}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(359deg)}}"]}),s(0,n.Optional()),s(0,n.Inject("config"))],t)}(),u=function(){function t(t){this.el=t}return t.prototype.ngOnChanges=function(t){var n,e;(console.log("fullscreenState isFirstChange:",t.fullscreenState.isFirstChange()),console.log("fullscreenState",this.fullscreenState),t.fullscreenState.isFirstChange())||(this.fullscreenState?(e=(n=this.el.nativeElement).requestFullscreen||n.webkitRequestFullScreen||n.mozRequestFullScreen||n.msRequestFullScreen)?e.call(n):console.log("FullScreen Request Method Not Supported on this browser."):(e=(n=document).cancelFullscreen||n.webkitExitFullscreen||n.webkitCancelFullScreen||n.mozCancelFullScreen||n.msExitFullScreen)?e.call(n):console.log("FullScreen Cancel Request Method Not Supported on this browser."))},t.prototype.ngOnInit=function(){},t.ctorParameters=function(){return[{type:n.ElementRef}]},r([n.Input("appScreenfull")],t.prototype,"fullscreenState",void 0),t=r([n.Directive({selector:"[appScreenfull]"})],t)}(),g=function(){function t(){}return t=r([n.NgModule({declarations:[l,u],imports:[e.CommonModule],exports:[l,u]})],t)}();t.AngularImageViewerComponent=l,t.AngularImageViewerModule=g,t.CustomImageEvent=a,t.FullScreenDirective=u,Object.defineProperty(t,"__esModule",{value:!0})}));
//# sourceMappingURL=angular-x-image-viewer.umd.min.js.map