ngx-image-magnifier
Version:
ngx-image-magnifier is an Angular tool to zoom image
239 lines (232 loc) • 12.3 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Input, ViewChild, Component, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
class NgxImageMagnifierService {
constructor() { }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [] });
class NgxImageMagnifierComponent {
renderer;
zoomContainer;
imageThumbnail;
fullSizeImage;
display;
fullImageTop;
fullImageLeft;
magnifiedWidth;
magnifiedHeight;
lensTop;
lensLeft;
lensBorderRadius = 0;
thumbImage;
fullImage;
_width;
_height;
fullWidth;
fullHeight;
_lensWidth = 100;
_lensHeight = 100;
magnification = 1;
minZoomRatio = 1;
maxZoomRatio = 2;
scrollStepSize = 0.1;
xRatio;
yRatio;
isReady = false;
thumbImageLoaded = false;
fullImageLoaded = false;
latestMouseLeft;
latestMouseTop;
eventListeners = [];
constructor(renderer) {
this.renderer = renderer;
}
set image(thumbImage) {
if (thumbImage == null) {
return;
}
this.thumbImageLoaded = false;
this.isReady = false;
this.thumbImage = thumbImage;
this.fullImage = this.thumbImage;
}
set width(width) {
this._width = width;
}
set lensWidth(width) {
this._lensWidth = Number(width) || this._lensWidth;
this._lensHeight = this._lensWidth;
}
ngOnInit() {
this.setUpEventListeners();
}
ngOnChanges(changes) {
if (changes.image && changes.image.currentValue) {
this.lensBorderRadius = this._lensWidth / 2;
}
}
ngOnDestroy() {
this.eventListeners.forEach((destroyFn) => destroyFn());
}
/**
* Template helper methods
*/
onThumbImageLoaded() {
this.thumbImageLoaded = true;
this.checkImagesLoaded();
}
onFullImageLoaded() {
this.fullImageLoaded = true;
this.checkImagesLoaded();
}
setUpEventListeners() {
this.eventListeners.push(this.renderer.listen(this.zoomContainer.nativeElement, 'mouseenter', (event) => this.hoverMouseEnter(event)));
this.eventListeners.push(this.renderer.listen(this.zoomContainer.nativeElement, 'mouseleave', () => this.hoverMouseLeave()));
this.eventListeners.push(this.renderer.listen(this.zoomContainer.nativeElement, 'mousemove', (event) => this.hoverMouseMove(event)));
this.eventListeners.push(this.renderer.listen(this.zoomContainer.nativeElement, 'mousewheel', (event) => this.onMouseWheel(event)));
}
checkImagesLoaded() {
this.calculateRatioAndOffset();
if (this.thumbImageLoaded && this.fullImageLoaded) {
this.calculateImageAndLensPosition();
this.isReady = true;
}
}
/**
* Zoom position setters
*/
setZoomPosition(left, top) {
this.latestMouseLeft = Number(left) || this.latestMouseLeft;
this.latestMouseTop = Number(top) || this.latestMouseTop;
}
onMouseWheel(event) {
// Don't eat events if zooming isn't active
if (!this.isReady) {
return;
}
const direction = Math.max(Math.min((event.wheelDelta || -event.detail), 1), -1);
if (direction > 0) {
// up
this.magnification = Math.min(this.magnification + this.scrollStepSize, this.maxZoomRatio);
}
else {
// down
this.magnification = Math.max(this.magnification - this.scrollStepSize, this.minZoomRatio);
}
this.calculateRatio();
this.calculateZoomPosition(event);
if (event.preventDefault) {
event.preventDefault(); // Chrome & FF
}
}
hoverMouseEnter(event) {
this.zoomOn(event);
}
hoverMouseLeave() {
this.zoomOff();
}
hoverMouseMove(event) {
this.calculateZoomPosition(event);
}
/**
* Private helper methods
*/
zoomOn(event) {
if (this.isReady) {
if (this.fullWidth > this._width) {
this.maxZoomRatio = this.fullWidth / this._width;
this.scrollStepSize = (this.maxZoomRatio - 1) / 10;
this.magnification = this.maxZoomRatio;
this.calculateRatioAndOffset();
this.display = 'block';
this.calculateZoomPosition(event);
}
}
}
zoomOff() {
this.display = 'none';
}
calculateZoomPosition(event) {
const newLeft = Math.max(Math.min(event.offsetX, this._width), 0);
const newTop = Math.max(Math.min(event.offsetY, this._height), 0);
this.setZoomPosition(newLeft, newTop);
this.calculateImageAndLensPosition();
}
calculateImageAndLensPosition() {
let lensLeftMod = 0;
let lensTopMod = 0;
lensLeftMod = this.lensLeft = this.latestMouseLeft - this._lensWidth / 2;
lensTopMod = this.lensTop = this.latestMouseTop - this._lensHeight / 2;
this.fullImageLeft = (this.latestMouseLeft * -this.xRatio) - lensLeftMod;
this.fullImageTop = (this.latestMouseTop * -this.yRatio) - lensTopMod;
}
calculateRatioAndOffset() {
this._height = this._width * this.imageThumbnail.nativeElement.height / this.imageThumbnail.nativeElement.width;
if (this.fullImageLoaded) {
this.fullWidth = this.fullSizeImage.nativeElement.naturalWidth;
this.fullHeight = this.fullSizeImage.nativeElement.naturalHeight;
this.calculateRatio();
}
}
calculateRatio() {
this.magnifiedWidth = this._width * this.magnification;
this.magnifiedHeight = this._height * this.magnification;
this.xRatio = (this.magnifiedWidth - this._width) / this._width;
this.yRatio = (this.magnifiedHeight - this._height) / this._height;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.3", type: NgxImageMagnifierComponent, isStandalone: false, selector: "ngx-image-magnifier", inputs: { image: "image", width: "width", lensWidth: "lensWidth" }, viewQueries: [{ propertyName: "zoomContainer", first: true, predicate: ["zoomContainer"], descendants: true, static: true }, { propertyName: "imageThumbnail", first: true, predicate: ["imageThumbnail"], descendants: true, static: true }, { propertyName: "fullSizeImage", first: true, predicate: ["fullSizeImage"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #zoomContainer class=\"ngxImageZoomContainer\">\r\n\r\n <img #imageThumbnail class=\"ngxImageZoomThumbnail\" [src]=\"thumbImage\" (load)=\"onThumbImageLoaded()\"\r\n [style.width.px]=\"this._width\" />\r\n\r\n <div class=\"ngxImageZoomFullContainer ngxImageZoomLensEnabled\" [style.display]=\"this.display\"\r\n [style.top.px]=\"this.lensTop\" [style.left.px]=\"this.lensLeft\" [style.width.px]=\"this._lensWidth\"\r\n [style.height.px]=\"this._lensHeight\" [style.border-radius.px]=\"this.lensBorderRadius\">\r\n <img #fullSizeImage class=\"ngxImageZoomFull\" [src]=\"fullImage\" (load)=\"onFullImageLoaded()\"\r\n [style.display]=\"this.display\" [style.top.px]=\"this.fullImageTop\" [style.left.px]=\"this.fullImageLeft\"\r\n [style.width.px]=\"this.magnifiedWidth\" [style.height.px]=\"this.magnifiedHeight\" />\r\n </div>\r\n</div>", styles: [".ngxImageZoomContainer{position:relative;margin:auto;overflow:hidden;pointer-events:none}.ngxImageZoomThumbnail{pointer-events:all}.ngxImageZoomFull{position:absolute;max-width:none;max-height:none;display:none;pointer-events:none}.ngxImageZoomFullContainer{position:absolute;overflow:hidden;pointer-events:none}.ngxImageZoomFullContainer.ngxImageZoomLensEnabled{border:2px solid red;cursor:crosshair;pointer-events:none}\n"] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-image-magnifier', standalone: false, template: "<div #zoomContainer class=\"ngxImageZoomContainer\">\r\n\r\n <img #imageThumbnail class=\"ngxImageZoomThumbnail\" [src]=\"thumbImage\" (load)=\"onThumbImageLoaded()\"\r\n [style.width.px]=\"this._width\" />\r\n\r\n <div class=\"ngxImageZoomFullContainer ngxImageZoomLensEnabled\" [style.display]=\"this.display\"\r\n [style.top.px]=\"this.lensTop\" [style.left.px]=\"this.lensLeft\" [style.width.px]=\"this._lensWidth\"\r\n [style.height.px]=\"this._lensHeight\" [style.border-radius.px]=\"this.lensBorderRadius\">\r\n <img #fullSizeImage class=\"ngxImageZoomFull\" [src]=\"fullImage\" (load)=\"onFullImageLoaded()\"\r\n [style.display]=\"this.display\" [style.top.px]=\"this.fullImageTop\" [style.left.px]=\"this.fullImageLeft\"\r\n [style.width.px]=\"this.magnifiedWidth\" [style.height.px]=\"this.magnifiedHeight\" />\r\n </div>\r\n</div>", styles: [".ngxImageZoomContainer{position:relative;margin:auto;overflow:hidden;pointer-events:none}.ngxImageZoomThumbnail{pointer-events:all}.ngxImageZoomFull{position:absolute;max-width:none;max-height:none;display:none;pointer-events:none}.ngxImageZoomFullContainer{position:absolute;overflow:hidden;pointer-events:none}.ngxImageZoomFullContainer.ngxImageZoomLensEnabled{border:2px solid red;cursor:crosshair;pointer-events:none}\n"] }]
}], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { zoomContainer: [{
type: ViewChild,
args: ['zoomContainer', { static: true }]
}], imageThumbnail: [{
type: ViewChild,
args: ['imageThumbnail', { static: true }]
}], fullSizeImage: [{
type: ViewChild,
args: ['fullSizeImage', { static: true }]
}], image: [{
type: Input
}], width: [{
type: Input
}], lensWidth: [{
type: Input
}] } });
class NgxImageMagnifierModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierModule, declarations: [NgxImageMagnifierComponent], imports: [CommonModule], exports: [NgxImageMagnifierComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierModule, imports: [CommonModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: NgxImageMagnifierModule, decorators: [{
type: NgModule,
args: [{
declarations: [
NgxImageMagnifierComponent
],
imports: [
CommonModule
],
exports: [
NgxImageMagnifierComponent
]
}]
}] });
/*
* Public API Surface of ngx-image-magnifier
*/
/**
* Generated bundle index. Do not edit.
*/
export { NgxImageMagnifierComponent, NgxImageMagnifierModule, NgxImageMagnifierService };
//# sourceMappingURL=ngx-image-magnifier.mjs.map