@udhsin/ngx-image-viewer
Version:
A configurable Angular image viewer component, compatible with Angular 2+
299 lines (291 loc) • 15.4 kB
JavaScript
import { __assign, __decorate, __param } from 'tslib';
import { EventEmitter, Optional, Inject, Input, Output, HostListener, Component, ElementRef, Directive, NgModule } from '@angular/core';
import { DOCUMENT, CommonModule } from '@angular/common';
var CustomEvent = /** @class */ (function () {
function CustomEvent(name, imageIndex) {
this.name = name;
this.imageIndex = imageIndex;
}
return CustomEvent;
}());
var DEFAULT_CONFIG = {
btnClass: 'default',
zoomFactor: 0.1,
containerBackgroundColor: '#ccc',
wheelZoom: false,
allowFullscreen: true,
allowKeyboardNavigation: true,
alignCenter: true,
btnShow: {
zoomIn: true,
zoomOut: true,
rotateClockwise: true,
rotateCounterClockwise: true,
next: true,
prev: true,
},
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',
},
};
var ImageViewerComponent = /** @class */ (function () {
function ImageViewerComponent(moduleConfig) {
this.moduleConfig = moduleConfig;
this.index = 0;
this.indexChange = new EventEmitter();
this.configChange = new EventEmitter();
this.customEvent = new EventEmitter();
this.style = {
transform: '',
msTransform: '',
oTransform: '',
webkitTransform: '',
};
this.fullscreen = false;
this.loading = true;
this.scale = 1;
this.rotation = 0;
this.translateX = 0;
this.translateY = 0;
this.hovered = false;
}
ImageViewerComponent.prototype.ngOnInit = function () {
var merged = this.mergeConfig(DEFAULT_CONFIG, this.moduleConfig);
this.config = this.mergeConfig(merged, this.config);
this.triggerConfigBinding();
};
ImageViewerComponent.prototype.nextImage = function (event) {
if (this.canNavigate(event) && this.index < this.src.length - 1) {
this.loading = true;
this.index++;
this.triggerIndexBinding();
this.reset();
}
};
ImageViewerComponent.prototype.prevImage = function (event) {
if (this.canNavigate(event) && this.index > 0) {
this.loading = true;
this.index--;
this.triggerIndexBinding();
this.reset();
}
};
ImageViewerComponent.prototype.zoomIn = function () {
this.scale *= 1 + this.config.zoomFactor;
this.updateStyle();
};
ImageViewerComponent.prototype.zoomOut = function () {
if (this.scale > this.config.zoomFactor) {
this.scale /= 1 + this.config.zoomFactor;
}
this.updateStyle();
};
ImageViewerComponent.prototype.scrollZoom = function (evt) {
if (this.config.wheelZoom) {
evt.deltaY > 0 ? this.zoomOut() : this.zoomIn();
return false;
}
};
ImageViewerComponent.prototype.rotateClockwise = function () {
this.rotation += 90;
this.updateStyle();
};
ImageViewerComponent.prototype.rotateCounterClockwise = function () {
this.rotation -= 90;
this.updateStyle();
};
ImageViewerComponent.prototype.onLoad = function () {
this.loading = false;
};
ImageViewerComponent.prototype.onLoadStart = function () {
this.loading = true;
};
ImageViewerComponent.prototype.onDragOver = function (evt) {
this.translateX += evt.clientX - this.prevX;
this.translateY += evt.clientY - this.prevY;
this.prevX = evt.clientX;
this.prevY = evt.clientY;
this.updateStyle();
};
ImageViewerComponent.prototype.onDragStart = function (evt) {
if (evt.dataTransfer && evt.dataTransfer.setDragImage) {
evt.dataTransfer.setDragImage(evt.target.nextElementSibling, 0, 0);
}
this.prevX = evt.clientX;
this.prevY = evt.clientY;
};
ImageViewerComponent.prototype.toggleFullscreen = function () {
this.fullscreen = !this.fullscreen;
if (!this.fullscreen) {
this.reset();
}
};
ImageViewerComponent.prototype.triggerIndexBinding = function () {
this.indexChange.emit(this.index);
};
ImageViewerComponent.prototype.triggerConfigBinding = function () {
this.configChange.next(this.config);
};
ImageViewerComponent.prototype.fireCustomEvent = function (name, imageIndex) {
this.customEvent.emit(new CustomEvent(name, imageIndex));
};
ImageViewerComponent.prototype.reset = function () {
this.scale = 1;
this.rotation = 0;
this.translateX = 0;
this.translateY = 0;
this.updateStyle();
};
ImageViewerComponent.prototype.onMouseOver = function () {
this.hovered = true;
};
ImageViewerComponent.prototype.onMouseLeave = function () {
this.hovered = false;
};
ImageViewerComponent.prototype.canNavigate = function (event) {
return (event == null || (this.config.allowKeyboardNavigation && this.hovered));
};
ImageViewerComponent.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;
};
ImageViewerComponent.prototype.mergeConfig = function (defaultValues, overrideValues) {
var result = __assign({}, defaultValues);
if (overrideValues) {
result = __assign(__assign({}, defaultValues), overrideValues);
if (overrideValues.btnIcons) {
result.btnIcons = __assign(__assign({}, defaultValues.btnIcons), overrideValues.btnIcons);
}
}
return result;
};
ImageViewerComponent.ctorParameters = function () { return [
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: ['config',] }] }
]; };
__decorate([
Input()
], ImageViewerComponent.prototype, "src", void 0);
__decorate([
Input()
], ImageViewerComponent.prototype, "index", void 0);
__decorate([
Input()
], ImageViewerComponent.prototype, "config", void 0);
__decorate([
Output()
], ImageViewerComponent.prototype, "indexChange", void 0);
__decorate([
Output()
], ImageViewerComponent.prototype, "configChange", void 0);
__decorate([
Output()
], ImageViewerComponent.prototype, "customEvent", void 0);
__decorate([
HostListener('window:keyup.ArrowRight', ['$event'])
], ImageViewerComponent.prototype, "nextImage", null);
__decorate([
HostListener('window:keyup.ArrowLeft', ['$event'])
], ImageViewerComponent.prototype, "prevImage", null);
__decorate([
HostListener('mouseover')
], ImageViewerComponent.prototype, "onMouseOver", null);
__decorate([
HostListener('mouseleave')
], ImageViewerComponent.prototype, "onMouseLeave", null);
ImageViewerComponent = __decorate([
Component({
selector: 'ngx-image-viewer',
template: "<div\r\n [ngxToggleFullscreen]=\"fullscreen\"\r\n class=\"img-container\"\r\n [ngClass]=\"{'align-center': config.alignCenter}\"\r\n [style.backgroundColor]=\"config.containerBackgroundColor\"\r\n (wheel)=\"scrollZoom($event)\"\r\n (dragover)=\"onDragOver($event)\"\r\n>\r\n <img\r\n [src]=\"src[index]\"\r\n [ngStyle]=\"style\"\r\n alt=\"Image not found...\"\r\n (dragstart)=\"onDragStart($event)\"\r\n (load)=\"onLoad()\"\r\n (loadstart)=\"onLoadStart()\"\r\n />\r\n <!-- Div below will be used to hide the 'ghost' image when dragging -->\r\n <div></div>\r\n <div class=\"spinner-container\" *ngIf=\"loading\">\r\n <div class=\"spinner\"></div>\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n [class]=\"config.btnClass\"\r\n *ngIf=\"config.btnShow.rotateCounterClockwise\"\r\n (click)=\"rotateCounterClockwise()\"\r\n >\r\n <span [class]=\"config.btnIcons.rotateCounterClockwise\"></span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [class]=\"config.btnClass\"\r\n *ngIf=\"config.btnShow.rotateClockwise\"\r\n (click)=\"rotateClockwise()\"\r\n >\r\n <span [class]=\"config.btnIcons.rotateClockwise\"></span>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n [class]=\"config.btnClass\"\r\n *ngIf=\"config.btnShow.zoomOut\"\r\n (click)=\"zoomOut()\"\r\n >\r\n <span [class]=\"config.btnIcons.zoomOut\"></span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [class]=\"config.btnClass\"\r\n *ngIf=\"config.btnShow.zoomIn\"\r\n (click)=\"zoomIn()\"\r\n >\r\n <span [class]=\"config.btnIcons.zoomIn\"></span>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n [class]=\"config.btnClass\"\r\n *ngFor=\"let cBtn of config.customBtns\"\r\n (click)=\"fireCustomEvent(cBtn.name, index)\"\r\n >\r\n <span [class]=\"cBtn.icon\"></span>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n id=\"ngx-fs-btn\"\r\n [class]=\"config.btnClass\"\r\n (click)=\"toggleFullscreen()\"\r\n *ngIf=\"config.allowFullscreen\"\r\n >\r\n <span [class]=\"config.btnIcons.fullscreen\"></span>\r\n </button>\r\n\r\n <div class=\"nav-button-container\" *ngIf=\"src.length > 1\">\r\n <button\r\n type=\"button\"\r\n [class]=\"config.btnClass\"\r\n (click)=\"prevImage($event)\"\r\n [disabled]=\"index === 0\"\r\n >\r\n <span [class]=\"config.btnIcons.prev\"></span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [class]=\"config.btnClass\"\r\n (click)=\"nextImage($event)\"\r\n [disabled]=\"index === src.length - 1\"\r\n >\r\n <span [class]=\"config.btnIcons.next\"></span>\r\n </button>\r\n </div>\r\n</div>\r\n",
styles: [".img-container{height:100%;width:100%;overflow:hidden;position:relative}.img-container.align-center{display:flex}.img-container.align-center img{margin:auto!important}.img-container img{z-index:2;margin:0 auto;display:block;max-width:100%;max-height:100%}.img-container button{z-index:99;position:absolute;right:15px}.img-container button:not(:disabled){cursor:pointer}.img-container button.default{height:40px;width:40px;border:1px solid #555;border-radius:50%;background-color:#fff;opacity:.7;transition:opacity .2s}.img-container button.default:hover{opacity:1}.img-container button.default:disabled{opacity:.25}.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}.nav-button-container{text-align:center;position:absolute;z-index:98;bottom:10px;left:0;right:0}.nav-button-container>button{position:relative;right:0;margin:0 10px}.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)}}"]
}),
__param(0, Optional()), __param(0, Inject('config'))
], ImageViewerComponent);
return ImageViewerComponent;
}());
var ToggleFullscreenDirective = /** @class */ (function () {
function ToggleFullscreenDirective(el, document) {
this.el = el;
this.document = document;
this.element = this.el.nativeElement;
this.isEnabled = this.document.fullscreenEnabled;
}
ToggleFullscreenDirective.prototype.ngOnChanges = function () {
if (this.isFullscreen && this.isEnabled) {
this.openFullscreen();
}
else if (this.isEnabled) {
this.closeFullscreen();
}
};
ToggleFullscreenDirective.prototype.openFullscreen = function () {
var methodToBeInvoked = this.element.requestFullscreen ||
this.element.mozRequestFullScreen ||
this.element.msRequestFullscreen ||
this.element.webkitRequestFullscreen;
if (methodToBeInvoked) {
methodToBeInvoked.call(this.element);
}
};
ToggleFullscreenDirective.prototype.closeFullscreen = function () {
if (!this.document.fullscreenElement) {
return;
}
var methodToBeInvoked = this.document.exitFullscreen ||
this.document.mozCancelFullScreen ||
this.document.webkitExitFullscreen ||
this.document.msExitFullscreen;
if (methodToBeInvoked) {
methodToBeInvoked.call(this.document);
}
};
ToggleFullscreenDirective.ctorParameters = function () { return [
{ type: ElementRef },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
]; };
__decorate([
Input('ngxToggleFullscreen')
], ToggleFullscreenDirective.prototype, "isFullscreen", void 0);
ToggleFullscreenDirective = __decorate([
Directive({
selector: '[ngxToggleFullscreen]',
}),
__param(1, Inject(DOCUMENT))
], ToggleFullscreenDirective);
return ToggleFullscreenDirective;
}());
var ImageViewerModule = /** @class */ (function () {
function ImageViewerModule() {
}
ImageViewerModule_1 = ImageViewerModule;
ImageViewerModule.forRoot = function (config) {
return {
ngModule: ImageViewerModule_1,
providers: [{ provide: 'config', useValue: config }],
};
};
var ImageViewerModule_1;
ImageViewerModule = ImageViewerModule_1 = __decorate([
NgModule({
imports: [CommonModule],
declarations: [ImageViewerComponent, ToggleFullscreenDirective],
exports: [ImageViewerComponent, ToggleFullscreenDirective],
})
], ImageViewerModule);
return ImageViewerModule;
}());
/*
* Public API Surface of ngx-imageviewer
*/
/**
* Generated bundle index. Do not edit.
*/
export { CustomEvent, ImageViewerComponent, ImageViewerModule, ToggleFullscreenDirective };
//# sourceMappingURL=udhsin-ngx-image-viewer.js.map