ngx-pinch-zoom
Version:
Pinch zoom component for Angular.
1,157 lines (1,153 loc) • 60.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define('ngx-pinch-zoom', ['exports', '@angular/core', '@angular/common'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['ngx-pinch-zoom'] = {}, global.ng.core, global.ng.common));
}(this, (function (exports, core, common) { 'use strict';
var defaultProperties = {
transitionDuration: 200,
doubleTap: true,
doubleTapScale: 2,
limitZoom: "original image size",
autoZoomOut: false,
zoomControlScale: 1,
minPanScale: 1.0001,
minScale: 0,
listeners: "mouse and touch",
wheel: true,
wheelZoomFactor: 0.2,
draggableImage: false
};
var backwardCompatibilityProperties = {
"transition-duration": "transitionDuration",
"transitionDurationBackwardCompatibility": "transitionDuration",
"double-tap": "doubleTap",
"doubleTapBackwardCompatibility": "doubleTap",
"double-tap-scale": "doubleTapScale",
"doubleTapScaleBackwardCompatibility": "doubleTapScale",
"auto-zoom-out": "autoZoomOut",
"autoZoomOutBackwardCompatibility": "autoZoomOut",
"limit-zoom": "limitZoom",
"limitZoomBackwardCompatibility": "limitZoom"
};
var Touches = /** @class */ (function () {
function Touches(properties) {
var _this = this;
this.eventType = undefined;
this.handlers = {};
this.startX = 0;
this.startY = 0;
this.lastTap = 0;
this.doubleTapMinTimeout = 300;
this.tapMinTimeout = 200;
this.touchstartTime = 0;
this.i = 0;
this.isMousedown = false;
this._touchListeners = {
"touchstart": "handleTouchstart",
"touchmove": "handleTouchmove",
"touchend": "handleTouchend"
};
this._mouseListeners = {
"mousedown": "handleMousedown",
"mousemove": "handleMousemove",
"mouseup": "handleMouseup",
"wheel": "handleWheel"
};
this._otherListeners = {
"resize": "handleResize"
};
/*
* Listeners
*/
/* Touchstart */
this.handleTouchstart = function (event) {
_this.elementPosition = _this.getElementPosition();
_this.touchstartTime = new Date().getTime();
if (_this.eventType === undefined) {
_this.getTouchstartPosition(event);
}
_this.runHandler("touchstart", event);
};
/* Touchmove */
this.handleTouchmove = function (event) {
var touches = event.touches;
// Pan
if (_this.detectPan(touches)) {
_this.runHandler("pan", event);
}
// Pinch
if (_this.detectPinch(event)) {
_this.runHandler("pinch", event);
}
};
/* Touchend */
this.handleTouchend = function (event) {
var touches = event.touches;
// Double Tap
if (_this.detectDoubleTap()) {
_this.runHandler("double-tap", event);
}
// Tap
_this.detectTap();
_this.runHandler("touchend", event);
_this.eventType = 'touchend';
if (touches && touches.length === 0) {
_this.eventType = undefined;
_this.i = 0;
}
};
/* Mousedown */
this.handleMousedown = function (event) {
_this.isMousedown = true;
_this.elementPosition = _this.getElementPosition();
_this.touchstartTime = new Date().getTime();
if (_this.eventType === undefined) {
_this.getMousedownPosition(event);
}
_this.runHandler("mousedown", event);
};
/* Mousemove */
this.handleMousemove = function (event) {
//event.preventDefault();
if (!_this.isMousedown) {
return;
}
// Pan
_this.runHandler("pan", event);
// Linear swipe
switch (_this.detectLinearSwipe(event)) {
case "horizontal-swipe":
event.swipeType = "horizontal-swipe";
_this.runHandler("horizontal-swipe", event);
break;
case "vertical-swipe":
event.swipeType = "vertical-swipe";
_this.runHandler("vertical-swipe", event);
break;
}
// Linear swipe
if (_this.detectLinearSwipe(event) ||
_this.eventType === 'horizontal-swipe' ||
_this.eventType === 'vertical-swipe') {
_this.handleLinearSwipe(event);
}
};
/* Mouseup */
this.handleMouseup = function (event) {
// Tap
_this.detectTap();
_this.isMousedown = false;
_this.runHandler("mouseup", event);
_this.eventType = undefined;
_this.i = 0;
};
/* Wheel */
this.handleWheel = function (event) {
_this.runHandler("wheel", event);
};
/* Resize */
this.handleResize = function (event) {
_this.runHandler("resize", event);
};
this.properties = properties;
this.element = this.properties.element;
this.elementPosition = this.getElementPosition();
this.toggleEventListeners('addEventListener');
}
Object.defineProperty(Touches.prototype, "touchListeners", {
get: function () {
return this.properties.touchListeners ? this.properties.touchListeners : this._touchListeners;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Touches.prototype, "mouseListeners", {
get: function () {
return this.properties.mouseListeners ? this.properties.mouseListeners : this._mouseListeners;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Touches.prototype, "otherListeners", {
get: function () {
return this.properties.otherListeners ? this.properties.otherListeners : this._otherListeners;
},
enumerable: false,
configurable: true
});
Touches.prototype.destroy = function () {
this.toggleEventListeners('removeEventListener');
};
Touches.prototype.toggleEventListeners = function (action) {
var listeners;
if (this.properties.listeners === 'mouse and touch') {
listeners = Object.assign(this.touchListeners, this.mouseListeners);
}
else {
listeners = this.detectTouchScreen() ? this.touchListeners : this.mouseListeners;
}
if (this.properties.resize) {
listeners = Object.assign(listeners, this.otherListeners);
}
for (var listener in listeners) {
var handler = listeners[listener];
// Window
if (listener === "resize") {
if (action === 'addEventListener') {
window.addEventListener(listener, this[handler], false);
}
if (action === 'removeEventListener') {
window.removeEventListener(listener, this[handler], false);
}
// Document
}
else if (listener === 'mouseup' || listener === "mousemove") {
if (action === 'addEventListener') {
document.addEventListener(listener, this[handler], false);
}
if (action === 'removeEventListener') {
document.removeEventListener(listener, this[handler], false);
}
// Element
}
else {
if (action === 'addEventListener') {
this.element.addEventListener(listener, this[handler], false);
}
if (action === 'removeEventListener') {
this.element.removeEventListener(listener, this[handler], false);
}
}
}
};
Touches.prototype.addEventListeners = function (listener) {
var handler = this._mouseListeners[listener];
window.addEventListener(listener, this[handler], false);
};
Touches.prototype.removeEventListeners = function (listener) {
var handler = this._mouseListeners[listener];
window.removeEventListener(listener, this[handler], false);
};
Touches.prototype.handleLinearSwipe = function (event) {
//event.preventDefault();
this.i++;
if (this.i > 3) {
this.eventType = this.getLinearSwipeType(event);
}
if (this.eventType === 'horizontal-swipe') {
this.runHandler('horizontal-swipe', event);
}
if (this.eventType === 'vertical-swipe') {
this.runHandler('vertical-swipe', event);
}
};
Touches.prototype.runHandler = function (eventName, response) {
if (this.handlers[eventName]) {
this.handlers[eventName](response);
}
};
/*
* Detection
*/
Touches.prototype.detectPan = function (touches) {
return touches.length === 1 && !this.eventType || this.eventType === 'pan';
};
Touches.prototype.detectDoubleTap = function () {
var _this = this;
if (this.eventType != undefined) {
return;
}
var currentTime = new Date().getTime();
var tapLength = currentTime - this.lastTap;
clearTimeout(this.doubleTapTimeout);
if (tapLength < this.doubleTapMinTimeout && tapLength > 0) {
return true;
}
else {
this.doubleTapTimeout = setTimeout(function () {
clearTimeout(_this.doubleTapTimeout);
}, this.doubleTapMinTimeout);
}
this.lastTap = currentTime;
return undefined;
};
Touches.prototype.detectTap = function () {
if (this.eventType != undefined) {
return;
}
var currentTime = new Date().getTime();
var tapLength = currentTime - this.touchstartTime;
if (tapLength > 0) {
if (tapLength < this.tapMinTimeout) {
this.runHandler("tap", {});
}
else {
this.runHandler("longtap", {});
}
}
};
Touches.prototype.detectPinch = function (event) {
var touches = event.touches;
return (touches.length === 2 && this.eventType === undefined) || this.eventType === 'pinch';
};
Touches.prototype.detectLinearSwipe = function (event) {
var touches = event.touches;
if (touches) {
if (touches.length === 1 && !this.eventType || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') {
return this.getLinearSwipeType(event);
}
}
else {
if (!this.eventType || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') {
return this.getLinearSwipeType(event);
}
}
return undefined;
};
Touches.prototype.getLinearSwipeType = function (event) {
if (this.eventType !== 'horizontal-swipe' && this.eventType !== 'vertical-swipe') {
var movementX = Math.abs(this.moveLeft(0, event) - this.startX);
var movementY = Math.abs(this.moveTop(0, event) - this.startY);
if ((movementY * 3) > movementX) {
return 'vertical-swipe';
}
else {
return 'horizontal-swipe';
}
}
else {
return this.eventType;
}
};
Touches.prototype.getElementPosition = function () {
return this.element.getBoundingClientRect();
};
Touches.prototype.getTouchstartPosition = function (event) {
this.startX = event.touches[0].clientX - this.elementPosition.left;
this.startY = event.touches[0].clientY - this.elementPosition.top;
};
Touches.prototype.getMousedownPosition = function (event) {
this.startX = event.clientX - this.elementPosition.left;
this.startY = event.clientY - this.elementPosition.top;
};
Touches.prototype.moveLeft = function (index, event) {
var touches = event.touches;
if (touches) {
return touches[index].clientX - this.elementPosition.left;
}
else {
return event.clientX - this.elementPosition.left;
}
};
Touches.prototype.moveTop = function (index, event) {
var touches = event.touches;
if (touches) {
return touches[index].clientY - this.elementPosition.top;
}
else {
return event.clientY - this.elementPosition.top;
}
};
Touches.prototype.detectTouchScreen = function () {
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var mq = function (query) {
return window.matchMedia(query).matches;
};
if (('ontouchstart' in window)) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
return mq(query);
};
/* Public properties and methods */
Touches.prototype.on = function (event, handler) {
if (event) {
this.handlers[event] = handler;
}
};
return Touches;
}());
var IvyPinch = /** @class */ (function () {
function IvyPinch(properties) {
var _this = this;
this.properties = defaultProperties;
this.i = 0;
this.scale = 1;
this.initialScale = 1;
this.startX = 0;
this.startY = 0;
this.moveX = 0;
this.moveY = 0;
this.initialMoveX = 0;
this.initialMoveY = 0;
this.moveXC = 0;
this.moveYC = 0;
this.lastTap = 0;
this.draggingMode = false;
this.distance = 0;
this.doubleTapTimeout = 0;
this.initialDistance = 0;
this.events = {};
this.defaultMaxScale = 3;
/* Touchstart */
this.handleTouchstart = function (event) {
_this.touches.addEventListeners("mousemove", "handleMousemove");
_this.getElementPosition();
if (_this.eventType === undefined) {
_this.getTouchstartPosition(event);
}
};
/* Touchend */
this.handleTouchend = function (event) {
/* touchend */
if (event.type === "touchend") {
_this.i = 0;
_this.draggingMode = false;
var touches = event.touches;
// Min scale
if (_this.scale < 1) {
_this.scale = 1;
}
// Auto Zoom Out
if (_this.properties.autoZoomOut && _this.eventType === 'pinch') {
_this.scale = 1;
}
// Align image
if (_this.eventType === 'pinch' ||
_this.eventType === 'pan' && _this.scale > _this.minPanScale) {
_this.alignImage();
}
// Update initial values
if (_this.eventType === 'pinch' ||
_this.eventType === 'pan' ||
_this.eventType === 'horizontal-swipe' ||
_this.eventType === 'vertical-swipe') {
_this.updateInitialValues();
}
_this.eventType = 'touchend';
if (touches && touches.length === 0) {
_this.eventType = undefined;
}
}
/* mouseup */
if (event.type === "mouseup") {
_this.draggingMode = false;
_this.updateInitialValues();
_this.eventType = undefined;
}
_this.touches.removeEventListeners("mousemove", "handleMousemove");
};
/*
* Handlers
*/
this.handlePan = function (event) {
if (_this.scale < _this.minPanScale || _this.properties.disablePan) {
return;
}
event.preventDefault();
var _a = _this.getClientPosition(event), clientX = _a.clientX, clientY = _a.clientY;
if (!_this.eventType) {
_this.startX = clientX - _this.elementPosition.left;
_this.startY = clientY - _this.elementPosition.top;
}
_this.eventType = 'pan';
_this.moveX = _this.initialMoveX + (_this.moveLeft(event, 0) - _this.startX);
_this.moveY = _this.initialMoveY + (_this.moveTop(event, 0) - _this.startY);
if (_this.properties.limitPan) {
_this.limitPanY();
_this.limitPanX();
}
/* mousemove */
if (event.type === "mousemove" && _this.scale > _this.minPanScale) {
_this.centeringImage();
}
_this.transformElement(0);
};
this.handleDoubleTap = function (event) {
_this.toggleZoom(event);
return;
};
this.handlePinch = function (event) {
event.preventDefault();
if (_this.eventType === undefined || _this.eventType === 'pinch') {
var touches = event.touches;
if (!_this.eventType) {
_this.initialDistance = _this.getDistance(touches);
var moveLeft0 = _this.moveLeft(event, 0);
var moveLeft1 = _this.moveLeft(event, 1);
var moveTop0 = _this.moveTop(event, 0);
var moveTop1 = _this.moveTop(event, 1);
_this.moveXC = ((moveLeft0 + moveLeft1) / 2) - _this.initialMoveX;
_this.moveYC = ((moveTop0 + moveTop1) / 2) - _this.initialMoveY;
}
_this.eventType = 'pinch';
_this.distance = _this.getDistance(touches);
_this.scale = _this.initialScale * (_this.distance / _this.initialDistance);
_this.moveX = _this.initialMoveX - (((_this.distance / _this.initialDistance) * _this.moveXC) - _this.moveXC);
_this.moveY = _this.initialMoveY - (((_this.distance / _this.initialDistance) * _this.moveYC) - _this.moveYC);
_this.handleLimitZoom();
if (_this.properties.limitPan) {
_this.limitPanY();
_this.limitPanX();
}
_this.transformElement(0);
}
};
this.handleWheel = function (event) {
event.preventDefault();
var wheelZoomFactor = _this.properties.wheelZoomFactor || 0;
var zoomFactor = event.deltaY < 0 ? (wheelZoomFactor) : (-wheelZoomFactor);
var newScale = _this.initialScale + zoomFactor;
/* Round value */
if (newScale < (1 + wheelZoomFactor)) {
newScale = 1;
}
else if (newScale < _this.maxScale && newScale > _this.maxScale - wheelZoomFactor) {
newScale = _this.maxScale;
}
if (newScale < 1 || newScale > _this.maxScale) {
return;
}
if (newScale === _this.scale) {
return;
}
_this.getElementPosition();
_this.scale = newScale;
/* Get cursor position over image */
var xCenter = (event.clientX - _this.elementPosition.left) - _this.initialMoveX;
var yCenter = (event.clientY - _this.elementPosition.top) - _this.initialMoveY;
_this.setZoom({
scale: newScale,
center: [xCenter, yCenter]
});
};
this.handleResize = function (_event) {
_this.setAutoHeight();
};
this.element = properties.element;
if (!this.element) {
return;
}
this.elementTarget = this.element.querySelector('*').tagName;
this.parentElement = this.element.parentElement;
this.properties = Object.assign({}, defaultProperties, properties);
this.detectLimitZoom();
this.touches = new Touches({
element: properties.element,
listeners: properties.listeners,
resize: properties.autoHeight,
mouseListeners: {
"mousedown": "handleMousedown",
"mouseup": "handleMouseup",
"wheel": "handleWheel"
}
});
/* Init */
this.setBasicStyles();
/*
* Listeners
*/
this.touches.on('touchstart', this.handleTouchstart);
this.touches.on('touchend', this.handleTouchend);
this.touches.on('mousedown', this.handleTouchstart);
this.touches.on('mouseup', this.handleTouchend);
this.touches.on('pan', this.handlePan);
this.touches.on('mousemove', this.handlePan);
this.touches.on('pinch', this.handlePinch);
if (this.properties.wheel) {
this.touches.on('wheel', this.handleWheel);
}
if (this.properties.doubleTap) {
this.touches.on('double-tap', this.handleDoubleTap);
}
if (this.properties.autoHeight) {
this.touches.on('resize', this.handleResize);
}
}
Object.defineProperty(IvyPinch.prototype, "minPanScale", {
// Minimum scale at which panning works
get: function () {
return this.getPropertiesValue("minPanScale");
},
enumerable: false,
configurable: true
});
Object.defineProperty(IvyPinch.prototype, "fullImage", {
get: function () {
return this.properties.fullImage;
},
enumerable: false,
configurable: true
});
IvyPinch.prototype.handleLimitZoom = function () {
var limitZoom = this.maxScale;
var minScale = this.properties.minScale || 0;
if (this.scale > limitZoom || this.scale <= minScale) {
var imageWidth = this.getImageWidth();
var imageHeight = this.getImageHeight();
var enlargedImageWidth = imageWidth * this.scale;
var enlargedImageHeight = imageHeight * this.scale;
var moveXRatio = this.moveX / (enlargedImageWidth - imageWidth);
var moveYRatio = this.moveY / (enlargedImageHeight - imageHeight);
if (this.scale > limitZoom) {
this.scale = limitZoom;
}
if (this.scale <= minScale) {
this.scale = minScale;
}
var newImageWidth = imageWidth * this.scale;
var newImageHeight = imageHeight * this.scale;
this.moveX = -Math.abs((moveXRatio * (newImageWidth - imageWidth)));
this.moveY = -Math.abs((-moveYRatio * (newImageHeight - imageHeight)));
}
};
IvyPinch.prototype.moveLeft = function (event, index) {
if (index === void 0) { index = 0; }
var clientX = this.getClientPosition(event, index).clientX;
return clientX - this.elementPosition.left;
};
IvyPinch.prototype.moveTop = function (event, index) {
if (index === void 0) { index = 0; }
var clientY = this.getClientPosition(event, index).clientY;
return clientY - this.elementPosition.top;
};
/*
* Detection
*/
IvyPinch.prototype.centeringImage = function () {
var img = this.element.getElementsByTagName(this.elementTarget)[0];
var initialMoveX = this.moveX;
var initialMoveY = this.moveY;
if (this.moveY > 0) {
this.moveY = 0;
}
if (this.moveX > 0) {
this.moveX = 0;
}
if (img) {
this.limitPanY();
this.limitPanX();
}
if (img && this.scale < 1) {
if (this.moveX < this.element.offsetWidth * (1 - this.scale)) {
this.moveX = this.element.offsetWidth * (1 - this.scale);
}
}
return initialMoveX !== this.moveX || initialMoveY !== this.moveY;
};
IvyPinch.prototype.limitPanY = function () {
var imgHeight = this.getImageHeight();
var scaledImgHeight = imgHeight * this.scale;
var parentHeight = this.parentElement.offsetHeight;
var elementHeight = this.element.offsetHeight;
if (scaledImgHeight < parentHeight) {
this.moveY = (parentHeight - elementHeight * this.scale) / 2;
}
else {
var imgOffsetTop = ((imgHeight - elementHeight) * this.scale) / 2;
if (this.moveY > imgOffsetTop) {
this.moveY = imgOffsetTop;
}
else if ((scaledImgHeight + Math.abs(imgOffsetTop) - parentHeight) + this.moveY < 0) {
this.moveY = -(scaledImgHeight + Math.abs(imgOffsetTop) - parentHeight);
}
}
};
IvyPinch.prototype.limitPanX = function () {
var imgWidth = this.getImageWidth();
var scaledImgWidth = imgWidth * this.scale;
var parentWidth = this.parentElement.offsetWidth;
var elementWidth = this.element.offsetWidth;
if (scaledImgWidth < parentWidth) {
this.moveX = (parentWidth - elementWidth * this.scale) / 2;
}
else {
var imgOffsetLeft = ((imgWidth - elementWidth) * this.scale) / 2;
if (this.moveX > imgOffsetLeft) {
this.moveX = imgOffsetLeft;
}
else if ((scaledImgWidth + Math.abs(imgOffsetLeft) - parentWidth) + this.moveX < 0) {
this.moveX = -(imgWidth * this.scale + Math.abs(imgOffsetLeft) - parentWidth);
}
}
};
IvyPinch.prototype.setBasicStyles = function () {
this.element.style.display = 'flex';
this.element.style.alignItems = 'center';
this.element.style.justifyContent = 'center';
this.element.style.transformOrigin = '0 0';
this.setImageSize();
this.setDraggableImage();
};
IvyPinch.prototype.removeBasicStyles = function () {
this.element.style.display = '';
this.element.style.alignItems = '';
this.element.style.justifyContent = '';
this.element.style.transformOrigin = '';
this.removeImageSize();
this.removeDraggableImage();
};
IvyPinch.prototype.setDraggableImage = function () {
var imgElement = this.getImageElement();
if (imgElement) {
imgElement.draggable = this.properties.draggableImage;
}
};
IvyPinch.prototype.removeDraggableImage = function () {
var imgElement = this.getImageElement();
if (imgElement) {
imgElement.draggable = true;
}
};
IvyPinch.prototype.setImageSize = function () {
var imgElement = this.element.getElementsByTagName(this.elementTarget);
if (imgElement.length) {
imgElement[0].style.maxWidth = '100%';
imgElement[0].style.maxHeight = '100%';
this.setAutoHeight();
}
};
IvyPinch.prototype.setAutoHeight = function () {
var imgElement = this.element.getElementsByTagName(this.elementTarget);
if (!this.properties.autoHeight || !imgElement.length) {
return;
}
var imgNaturalWidth = imgElement[0].getAttribute("width");
var imgNaturalHeight = imgElement[0].getAttribute("height");
var sizeRatio = imgNaturalWidth / imgNaturalHeight;
var parentWidth = this.parentElement.offsetWidth;
imgElement[0].style.maxHeight = parentWidth / sizeRatio + "px";
};
IvyPinch.prototype.removeImageSize = function () {
var imgElement = this.element.getElementsByTagName(this.elementTarget);
if (imgElement.length) {
imgElement[0].style.maxWidth = '';
imgElement[0].style.maxHeight = '';
}
};
IvyPinch.prototype.getElementPosition = function () {
this.elementPosition = this.element.parentElement.getBoundingClientRect();
};
IvyPinch.prototype.getTouchstartPosition = function (event) {
var _a = this.getClientPosition(event), clientX = _a.clientX, clientY = _a.clientY;
this.startX = clientX - this.elementPosition.left;
this.startY = clientY - this.elementPosition.top;
};
IvyPinch.prototype.getClientPosition = function (event, index) {
if (index === void 0) { index = 0; }
var clientX;
var clientY;
if (event.type === "touchstart" || event.type === "touchmove") {
clientX = event.touches[index].clientX;
clientY = event.touches[index].clientY;
}
if (event.type === "mousedown" || event.type === "mousemove") {
clientX = event.clientX;
clientY = event.clientY;
}
return {
clientX: clientX,
clientY: clientY
};
};
IvyPinch.prototype.resetScale = function () {
this.scale = 1;
this.moveX = 0;
this.moveY = 0;
this.updateInitialValues();
this.transformElement(this.properties.transitionDuration);
};
IvyPinch.prototype.updateInitialValues = function () {
this.initialScale = this.scale;
this.initialMoveX = this.moveX;
this.initialMoveY = this.moveY;
};
IvyPinch.prototype.getDistance = function (touches) {
return Math.sqrt(Math.pow(touches[0].pageX - touches[1].pageX, 2) + Math.pow(touches[0].pageY - touches[1].pageY, 2));
};
IvyPinch.prototype.getImageHeight = function () {
var img = this.element.getElementsByTagName(this.elementTarget)[0];
return img.offsetHeight;
};
IvyPinch.prototype.getImageWidth = function () {
var img = this.element.getElementsByTagName(this.elementTarget)[0];
return img.offsetWidth;
};
IvyPinch.prototype.transformElement = function (duration) {
this.element.style.transition = "all " + duration + "ms";
this.element.style.transform = "matrix(" + Number(this.scale) + ", 0, 0, " + Number(this.scale) + ", " + Number(this.moveX) + ", " + Number(this.moveY) + ")";
};
IvyPinch.prototype.isTouchScreen = function () {
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
if (('ontouchstart' in window)) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
return this.getMatchMedia(query);
};
IvyPinch.prototype.getMatchMedia = function (query) {
return window.matchMedia(query).matches;
};
IvyPinch.prototype.isDragging = function () {
if (this.properties.disablePan) {
return false;
}
var imgHeight = this.getImageHeight();
var imgWidth = this.getImageWidth();
if (this.scale > 1) {
return imgHeight * this.scale > this.parentElement.offsetHeight ||
imgWidth * this.scale > this.parentElement.offsetWidth;
}
if (this.scale === 1) {
return imgHeight > this.parentElement.offsetHeight ||
imgWidth > this.parentElement.offsetWidth;
}
return undefined;
};
IvyPinch.prototype.detectLimitZoom = function () {
this.maxScale = this.defaultMaxScale;
if (this.properties.limitZoom === "original image size" &&
this.elementTarget === "IMG") {
// We are waiting for the element with the image to be available
this.pollLimitZoomForOriginalImage();
}
};
IvyPinch.prototype.pollLimitZoomForOriginalImage = function () {
var _this = this;
var poll = setInterval(function () {
var maxScaleForOriginalImage = _this.getMaxScaleForOriginalImage();
if (typeof maxScaleForOriginalImage === 'number') {
_this.maxScale = maxScaleForOriginalImage;
clearInterval(poll);
}
}, 10);
};
IvyPinch.prototype.getMaxScaleForOriginalImage = function () {
var maxScale;
var img = this.element.getElementsByTagName("img")[0];
if (img.naturalWidth && img.offsetWidth) {
maxScale = img.naturalWidth / img.offsetWidth;
}
return maxScale;
};
IvyPinch.prototype.getImageElement = function () {
var imgElement = this.element.getElementsByTagName(this.elementTarget);
if (imgElement.length) {
return imgElement[0];
}
};
IvyPinch.prototype.toggleZoom = function (event) {
if (event === void 0) { event = false; }
if (this.initialScale === 1) {
if (event && event.changedTouches) {
if (this.properties.doubleTapScale === undefined) {
return;
}
var changedTouches = event.changedTouches;
this.scale = this.initialScale * this.properties.doubleTapScale;
this.moveX = this.initialMoveX - (changedTouches[0].clientX - this.elementPosition.left) * (this.properties.doubleTapScale - 1);
this.moveY = this.initialMoveY - (changedTouches[0].clientY - this.elementPosition.top) * (this.properties.doubleTapScale - 1);
}
else {
var zoomControlScale = this.properties.zoomControlScale || 0;
this.scale = this.initialScale * (zoomControlScale + 1);
this.moveX = this.initialMoveX - this.element.offsetWidth * (this.scale - 1) / 2;
this.moveY = this.initialMoveY - this.element.offsetHeight * (this.scale - 1) / 2;
}
this.centeringImage();
this.updateInitialValues();
this.transformElement(this.properties.transitionDuration);
}
else {
this.resetScale();
}
};
IvyPinch.prototype.setZoom = function (properties) {
this.scale = properties.scale;
var xCenter;
var yCenter;
var visibleAreaWidth = this.element.offsetWidth;
var visibleAreaHeight = this.element.offsetHeight;
var scalingPercent = (visibleAreaWidth * this.scale) / (visibleAreaWidth * this.initialScale);
if (properties.center) {
xCenter = properties.center[0];
yCenter = properties.center[1];
}
else {
xCenter = visibleAreaWidth / 2 - this.initialMoveX;
yCenter = visibleAreaHeight / 2 - this.initialMoveY;
}
this.moveX = this.initialMoveX - ((scalingPercent * xCenter) - xCenter);
this.moveY = this.initialMoveY - ((scalingPercent * yCenter) - yCenter);
this.centeringImage();
this.updateInitialValues();
this.transformElement(this.properties.transitionDuration);
};
IvyPinch.prototype.alignImage = function () {
var isMoveChanged = this.centeringImage();
if (isMoveChanged) {
this.updateInitialValues();
this.transformElement(this.properties.transitionDuration);
}
};
IvyPinch.prototype.destroy = function () {
this.removeBasicStyles();
this.touches.destroy();
};
IvyPinch.prototype.getPropertiesValue = function (propertyName) {
if (this.properties && this.properties[propertyName]) {
return this.properties[propertyName];
}
else {
return defaultProperties[propertyName];
}
};
return IvyPinch;
}());
var _defaultComponentProperties = {
overflow: "hidden",
disableZoomControl: "auto",
backgroundColor: "rgba(0,0,0,0.85)"
};
var PinchZoomComponent = /** @class */ (function () {
function PinchZoomComponent(elementRef) {
this.elementRef = elementRef;
this.defaultComponentProperties = this.getDefaultComponentProperties();
this.applyPropertiesDefault(this.defaultComponentProperties, {});
}
Object.defineProperty(PinchZoomComponent.prototype, "properties", {
get: function () {
return this._properties;
},
set: function (value) {
if (value) {
this._properties = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "transitionDurationBackwardCompatibility", {
// transitionDuration
set: function (value) {
if (value) {
this._transitionDuration = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "transitionDuration", {
get: function () {
return this._transitionDuration;
},
set: function (value) {
if (value) {
this._transitionDuration = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "doubleTapBackwardCompatibility", {
// doubleTap
set: function (value) {
if (value) {
this._doubleTap = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "doubleTap", {
get: function () {
return this._doubleTap;
},
set: function (value) {
if (value) {
this._doubleTap = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "doubleTapScaleBackwardCompatibility", {
// doubleTapScale
set: function (value) {
if (value) {
this._doubleTapScale = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "doubleTapScale", {
get: function () {
return this._doubleTapScale;
},
set: function (value) {
if (value) {
this._doubleTapScale = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "autoZoomOutBackwardCompatibility", {
// autoZoomOut
set: function (value) {
if (value) {
this._autoZoomOut = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "autoZoomOut", {
get: function () {
return this._autoZoomOut;
},
set: function (value) {
if (value) {
this._autoZoomOut = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "limitZoomBackwardCompatibility", {
// limitZoom
set: function (value) {
if (value) {
this._limitZoom = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "limitZoom", {
get: function () {
return this._limitZoom;
},
set: function (value) {
if (value) {
this._limitZoom = value;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "hostOverflow", {
get: function () {
return this.properties['overflow'];
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "hostBackgroundColor", {
get: function () {
return this.properties['backgroundColor'];
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "isTouchScreen", {
get: function () {
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var mq = function (query) {
return window.matchMedia(query).matches;
};
if (('ontouchstart' in window)) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
return mq(query);
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "isDragging", {
get: function () {
return this.pinchZoom ? this.pinchZoom.isDragging() : undefined;
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "isDisabled", {
get: function () {
return this.properties['disabled'];
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "scale", {
get: function () {
return this.pinchZoom.scale;
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "isZoomedIn", {
get: function () {
return this.scale > 1;
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "scaleLevel", {
get: function () {
return Math.round(this.scale / this._zoomControlScale);
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "maxScale", {
get: function () {
return this.pinchZoom.maxScale;
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "isZoomLimitReached", {
get: function () {
return this.scale >= this.maxScale;
},
enumerable: false,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "_zoomControlScale", {
get: function () {
return this.getPropertiesValue('zoomControlScale');
},
enumerable: false,
configurable: true
});
PinchZoomComponent.prototype.ngOnInit = function () {
this.initPinchZoom();
/* Calls the method until the image size is available */
this.detectLimitZoom();
};
PinchZoomComponent.prototype.ngOnChanges = function (changes) {
var changedProperties = this.getProperties(changes);
changedProperties = this.renameProperties(changedProperties);
this.applyPropertiesDefault(this.defaultComponentProperties, changedProperties);
};
PinchZoomComponent.prototype.ngOnDestroy = function () {
this.destroy();
};
PinchZoomComponent.prototype.initPinchZoom = function () {
if (this.properties['disabled']) {
return;
}
this.properties['element'] = this.elementRef.nativeElement.querySelector('.pinch-zoom-content');
this.pinchZoom = new IvyPinch(this.properties);
};
PinchZoomComponent.prototype.getProperties = function (changes) {
var properties = {};
for (var pr