diff --git a/demo/basic.html b/demo/basic.html
index 6bf43d7..6b66d06 100644
--- a/demo/basic.html
+++ b/demo/basic.html
@@ -18,7 +18,6 @@
}
.cropit-image-background {
- opacity: .2;
cursor: auto;
}
@@ -52,6 +51,7 @@
imageState: {
src: 'http://lorempixel.com/500/400/',
},
+ crossOrigin: true
});
$('.export').click(function() {
diff --git a/dist/jquery.cropit.js b/dist/jquery.cropit.js
index 5aafa63..f10a073 100644
--- a/dist/jquery.cropit.js
+++ b/dist/jquery.cropit.js
@@ -124,6 +124,10 @@ return /******/ (function(modules) { // webpackBootstrap
return callOnFirst(this, 'getImageSize');
},
+ exportGeometry: function exportGeometry() {
+ return callOnFirst(this, 'getExportGeometry');
+ },
+
prop: function prop(name, value) {
if ((0, _utils.exists)(value)) {
return applyOnEach(this, function (cropit) {
@@ -181,9 +185,9 @@ return /******/ (function(modules) { // webpackBootstrap
var _jquery2 = _interopRequireDefault(_jquery);
- var _Zoomer = __webpack_require__(3);
+ var _jqueryPanzoom = __webpack_require__(3);
- var _Zoomer2 = _interopRequireDefault(_Zoomer);
+ var _jqueryPanzoom2 = _interopRequireDefault(_jqueryPanzoom);
var _constants = __webpack_require__(4);
@@ -217,8 +221,21 @@ return /******/ (function(modules) { // webpackBootstrap
};
this.$fileInput = this.options.$fileInput.attr({ accept: 'image/*' });
- this.$preview = this.options.$preview.css({ backgroundRepeat: 'no-repeat' });
- this.$zoomSlider = this.options.$zoomSlider.attr({ min: 0, max: 1, step: 0.01 });
+ this.$imageBg = (0, _jquery2['default'])('
').addClass(_constants.CLASS_NAMES.IMAGE_BACKGROUND).attr({ alt: '' }).css({ position: 'absolute' });
+ this.$imageBgContainer = (0, _jquery2['default'])('
').addClass(_constants.CLASS_NAMES.IMAGE_BACKGROUND_CONTAINER).css({
+ position: 'absolute',
+ zIndex: 0
+ }).prepend(this.$imageBg);
+ this.$previewContainer = (0, _jquery2['default'])('').css({ position: 'relative' }).prepend(this.$imageBgContainer);
+ this.$preview = this.options.$preview.css({
+ backgroundRepeat: 'no-repeat',
+ position: 'relative'
+ }).append(this.$previewContainer);
+ this.$zoomSlider = this.options.$zoomSlider.attr({
+ min: 0,
+ max: 1,
+ step: 0.01
+ });
this.previewSize = {
w: this.options.width || this.$preview.width(),
@@ -231,51 +248,44 @@ return /******/ (function(modules) { // webpackBootstrap
this.$preview.height(this.previewSize.h);
}
+ this.imageBgBorderWidthArray = [0, 0, 0, 0];
if (this.options.imageBackground) {
if (_jquery2['default'].isArray(this.options.imageBackgroundBorderWidth)) {
this.imageBgBorderWidthArray = this.options.imageBackgroundBorderWidth;
} else {
- this.imageBgBorderWidthArray = [];
[0, 1, 2, 3].forEach(function (i) {
_this.imageBgBorderWidthArray[i] = _this.options.imageBackgroundBorderWidth;
});
}
-
- var $previewContainer = this.options.$previewContainer;
- this.$imageBg = (0, _jquery2['default'])('
').addClass(_constants.CLASS_NAMES.IMAGE_BACKGROUND).attr('alt', '').css('position', 'absolute');
- this.$imageBgContainer = (0, _jquery2['default'])('').addClass(_constants.CLASS_NAMES.IMAGE_BACKGROUND_CONTAINER).css({
- position: 'absolute',
- zIndex: 0,
- left: -this.imageBgBorderWidthArray[3] + window.parseInt(this.$preview.css('border-left-width') || 0),
- top: -this.imageBgBorderWidthArray[0] + window.parseInt(this.$preview.css('border-top-width') || 0),
- width: this.previewSize.w + this.imageBgBorderWidthArray[1] + this.imageBgBorderWidthArray[3],
- height: this.previewSize.h + this.imageBgBorderWidthArray[0] + this.imageBgBorderWidthArray[2]
- }).append(this.$imageBg);
if (this.imageBgBorderWidthArray[0] > 0) {
this.$imageBgContainer.css('overflow', 'hidden');
}
- $previewContainer.css('position', 'relative').prepend(this.$imageBgContainer);
- this.$preview.css('position', 'relative');
-
- this.$preview.hover(function () {
- _this.$imageBg.addClass(_constants.CLASS_NAMES.PREVIEW_HOVERED);
- }, function () {
- _this.$imageBg.removeClass(_constants.CLASS_NAMES.PREVIEW_HOVERED);
- });
}
+ this.$imageBgContainer.css({
+ left: -this.imageBgBorderWidthArray[3] + window.parseInt(this.$preview.css('border-left-width') || 0),
+ top: -this.imageBgBorderWidthArray[0] + window.parseInt(this.$preview.css('border-top-width') || 0),
+ width: this.previewSize.w + this.imageBgBorderWidthArray[1] + this.imageBgBorderWidthArray[3],
+ height: this.previewSize.h + this.imageBgBorderWidthArray[0] + this.imageBgBorderWidthArray[2]
+ });
- this.setInitialZoom(this.options.initialZoom);
+ this.$preview.hover(function () {
+ _this.$imageBg.addClass(_constants.CLASS_NAMES.PREVIEW_HOVERED);
+ }, function () {
+ _this.$imageBg.removeClass(_constants.CLASS_NAMES.PREVIEW_HOVERED);
+ });
this.imageLoaded = false;
- this.moveContinue = false;
-
- this.zoomer = new _Zoomer2['default']();
-
if (this.options.allowDragNDrop) {
_jquery2['default'].event.props.push('dataTransfer');
}
+ this.$imageBg.panzoom({
+ eventNamespace: '.cropit',
+ $zoomRange: this.$zoomSlider,
+ contain: 'invert'
+ }).panzoom('zoom');
+
this.bindListeners();
if (this.options.imageState && this.options.imageState.src) {
@@ -286,9 +296,6 @@ return /******/ (function(modules) { // webpackBootstrap
key: 'bindListeners',
value: function bindListeners() {
this.$fileInput.on('change.cropit', this.onFileChange.bind(this));
- this.$preview.on(_constants.EVENTS.PREVIEW, this.onPreviewEvent.bind(this));
- this.$zoomSlider.on(_constants.EVENTS.ZOOM_INPUT, this.onZoomSliderChange.bind(this));
-
if (this.options.allowDragNDrop) {
this.$preview.on('dragover.cropit dragleave.cropit', this.onDragOver.bind(this));
this.$preview.on('drop.cropit', this.onDrop.bind(this));
@@ -298,15 +305,12 @@ return /******/ (function(modules) { // webpackBootstrap
key: 'unbindListeners',
value: function unbindListeners() {
this.$fileInput.off('change.cropit');
- this.$preview.off(_constants.EVENTS.PREVIEW);
this.$preview.off('dragover.cropit dragleave.cropit drop.cropit');
- this.$zoomSlider.off(_constants.EVENTS.ZOOM_INPUT);
}
}, {
key: 'onFileChange',
value: function onFileChange(e) {
this.options.onFileChange(e);
-
if (this.$fileInput.get(0).files) {
this.loadFileReader(this.$fileInput.get(0).files[0]);
}
@@ -347,17 +351,14 @@ return /******/ (function(modules) { // webpackBootstrap
e.preventDefault();
e.stopPropagation();
-
var files = Array.prototype.slice.call(e.dataTransfer.files, 0);
files.some(function (file) {
if (!file.type.match('image')) {
return false;
}
-
_this2.loadFileReader(file);
return true;
});
-
this.$preview.removeClass(_constants.CLASS_NAMES.DRAG_HOVERED);
}
}, {
@@ -366,10 +367,8 @@ return /******/ (function(modules) { // webpackBootstrap
if (!imageSrc) {
return;
}
-
this.options.onImageLoading();
this.setImageLoadingClass();
-
this.preImage.src = imageSrc;
}
}, {
@@ -389,7 +388,11 @@ return /******/ (function(modules) { // webpackBootstrap
}
if (this.options.allowCrossOrigin) {
- this.image.crossOrigin = this.preImage.src.indexOf('data:') === 0 ? null : 'Anonymous';
+ if (this.preImage.src.indexOf('data:') === 0) {
+ this.image.crossOrigin = null;
+ } else {
+ this.image.crossOrigin = 'Anonymous';
+ }
}
this.image.src = this.imageSrc = this.preImage.src;
@@ -401,25 +404,20 @@ return /******/ (function(modules) { // webpackBootstrap
w: this.image.width,
h: this.image.height
};
-
- this.setupZoomer(this.options.imageState && this.options.imageState.zoom || this.initialZoom);
- if (this.options.imageState && this.options.imageState.offset) {
- this.setOffset(this.options.imageState.offset);
- } else {
- this.centerImage();
+ var max_ratio = Math.max(this.previewSize.w / this.imageSize.w, this.previewSize.h / this.imageSize.h);
+ var min_zoom = max_ratio;
+ var max_zoom = Math.max(max_ratio, 1);
+ console.log(this.imageSize);
+ console.log(this.previewSize);
+ if (min_zoom > 1) {
+ this.$imageBg.css({ width: this.imageSize.w * max_ratio,
+ height: this.imageSize.h * max_ratio });
+ min_zoom = 1;
+ max_zoom = 1;
}
-
- this.options.imageState = {};
-
- this.$preview.css('background-image', 'url(' + this.imageSrc + ')');
- if (this.options.imageBackground) {
- this.$imageBg.attr('src', this.imageSrc);
- }
-
+ this.$imageBg.attr('src', this.imageSrc).panzoom('option', 'maxScale', max_zoom).panzoom('option', 'minScale', min_zoom).panzoom('resetDimensions').panzoom('option', 'contain', 'invert').panzoom('zoom', min_zoom);
this.setImageLoadedClass();
-
this.imageLoaded = true;
-
this.options.onImageLoaded();
}
}, {
@@ -443,199 +441,59 @@ return /******/ (function(modules) { // webpackBootstrap
value: function removeImageLoadingClass() {
this.$preview.removeClass(_constants.CLASS_NAMES.IMAGE_LOADING);
}
- }, {
- key: 'getEventPosition',
- value: function getEventPosition(e) {
- if (e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0]) {
- e = e.originalEvent.touches[0];
- }
- if (e.clientX && e.clientY) {
- return { x: e.clientX, y: e.clientY };
- }
- }
- }, {
- key: 'onPreviewEvent',
- value: function onPreviewEvent(e) {
- if (!this.imageLoaded) {
- return;
- }
-
- this.moveContinue = false;
- this.$preview.off(_constants.EVENTS.PREVIEW_MOVE);
-
- if (e.type === 'mousedown' || e.type === 'touchstart') {
- this.origin = this.getEventPosition(e);
- this.moveContinue = true;
- this.$preview.on(_constants.EVENTS.PREVIEW_MOVE, this.onMove.bind(this));
- } else {
- (0, _jquery2['default'])(document.body).focus();
- }
-
- e.stopPropagation();
- return false;
- }
- }, {
- key: 'onMove',
- value: function onMove(e) {
- var eventPosition = this.getEventPosition(e);
-
- if (this.moveContinue && eventPosition) {
- this.setOffset({
- x: this.offset.x + eventPosition.x - this.origin.x,
- y: this.offset.y + eventPosition.y - this.origin.y
- });
- }
-
- this.origin = eventPosition;
-
- e.stopPropagation();
- return false;
- }
- }, {
- key: 'setOffset',
- value: function setOffset(position) {
- if (!position || !(0, _utils.exists)(position.x) || !(0, _utils.exists)(position.y)) {
- return;
- }
-
- this.offset = this.fixOffset(position);
- this.$preview.css('background-position', '' + this.offset.x + 'px ' + this.offset.y + 'px');
- if (this.options.imageBackground) {
- this.$imageBg.css({
- left: this.offset.x + this.imageBgBorderWidthArray[3],
- top: this.offset.y + this.imageBgBorderWidthArray[0]
- });
- }
-
- this.options.onOffsetChange(position);
- }
- }, {
- key: 'fixOffset',
- value: function fixOffset(offset) {
- if (!this.imageLoaded) {
- return offset;
- }
-
- var ret = { x: offset.x, y: offset.y };
-
- if (!this.options.freeMove) {
- if (this.imageSize.w * this.zoom >= this.previewSize.w) {
- ret.x = Math.min(0, Math.max(ret.x, this.previewSize.w - this.imageSize.w * this.zoom));
- } else {
- ret.x = Math.max(0, Math.min(ret.x, this.previewSize.w - this.imageSize.w * this.zoom));
- }
-
- if (this.imageSize.h * this.zoom >= this.previewSize.h) {
- ret.y = Math.min(0, Math.max(ret.y, this.previewSize.h - this.imageSize.h * this.zoom));
- } else {
- ret.y = Math.max(0, Math.min(ret.y, this.previewSize.h - this.imageSize.h * this.zoom));
- }
- }
-
- ret.x = (0, _utils.round)(ret.x);
- ret.y = (0, _utils.round)(ret.y);
-
- return ret;
- }
}, {
key: 'centerImage',
value: function centerImage() {
if (!this.imageSize || !this.zoom) {
return;
}
-
- this.setOffset({
- x: (this.previewSize.w - this.imageSize.w * this.zoom) / 2,
- y: (this.previewSize.h - this.imageSize.h * this.zoom) / 2
- });
- }
- }, {
- key: 'onZoomSliderChange',
- value: function onZoomSliderChange() {
- if (!this.imageLoaded) {
- return;
- }
-
- this.zoomSliderPos = Number(this.$zoomSlider.val());
- var newZoom = this.zoomer.getZoom(this.zoomSliderPos);
- if (newZoom === this.zoom) {
- return;
- }
- this.setZoom(newZoom);
+ this.$imageBg.panzoom('resetPan');
}
}, {
key: 'enableZoomSlider',
value: function enableZoomSlider() {
this.$zoomSlider.removeAttr('disabled');
+ this.$imageBg.panzoom('option', 'disableZoom', false);
this.options.onZoomEnabled();
}
}, {
key: 'disableZoomSlider',
value: function disableZoomSlider() {
this.$zoomSlider.attr('disabled', true);
+ this.$imageBg.panzoom('option', 'disableZoom', true);
this.options.onZoomDisabled();
}
}, {
- key: 'setupZoomer',
- value: function setupZoomer(zoom) {
- this.zoomer.setup({
- imageSize: this.imageSize,
- previewSize: this.previewSize,
- exportZoom: this.options.exportZoom,
- maxZoom: this.options.maxZoom,
- minZoom: this.options.minZoom,
- smallImage: this.options.smallImage
- });
- this.setZoom((0, _utils.exists)(zoom) ? zoom : this.zoom);
-
- if (this.isZoomable()) {
- this.enableZoomSlider();
- } else {
- this.disableZoomSlider();
- }
+ key: 'isZoomable',
+ value: function isZoomable() {
+ return this.$imageBg.panzoom('option', 'disablezoom');
}
}, {
- key: 'setZoom',
- value: function setZoom(newZoom) {
- newZoom = this.fixZoom(newZoom);
-
- var updatedWidth = (0, _utils.round)(this.imageSize.w * newZoom);
- var updatedHeight = (0, _utils.round)(this.imageSize.h * newZoom);
-
- if (this.imageLoaded) {
- var oldZoom = this.zoom;
-
- var newX = this.previewSize.w / 2 - (this.previewSize.w / 2 - this.offset.x) * newZoom / oldZoom;
- var newY = this.previewSize.h / 2 - (this.previewSize.h / 2 - this.offset.y) * newZoom / oldZoom;
-
- this.zoom = newZoom;
- this.setOffset({ x: newX, y: newY });
- } else {
- this.zoom = newZoom;
- }
-
- this.zoomSliderPos = this.zoomer.getSliderPos(this.zoom);
- this.$zoomSlider.val(this.zoomSliderPos);
-
- this.$preview.css('background-size', '' + updatedWidth + 'px ' + updatedHeight + 'px');
- if (this.options.imageBackground) {
- this.$imageBg.css({
- width: updatedWidth,
- height: updatedHeight
- });
+ key: 'getExportGeometry',
+ value: function getExportGeometry() {
+ if (!this.imageSrc) {
+ return;
}
-
- this.options.onZoomChange(newZoom);
- }
- }, {
- key: 'fixZoom',
- value: function fixZoom(zoom) {
- return this.zoomer.fixZoom(zoom);
- }
- }, {
- key: 'isZoomable',
- value: function isZoomable() {
- return this.zoomer.isZoomable();
+ var matrix = this.$imageBg.panzoom('getMatrix');
+ var offset = { x: parseFloat(matrix[4]),
+ y: parseFloat(matrix[5]) };
+ var zoom = matrix[0];
+ var image_view = { height: this.previewSize.w,
+ width: this.previewSize.h };
+ var image_size = { height: this.image.height,
+ width: this.image.width };
+ var zoom_offset = { x: (image_size.width - image_size.width * zoom) / 2,
+ y: (image_size.height - image_size.height * zoom) / 2 };
+ var drag_offset = { x: (zoom_offset.x + offset.x) * -1,
+ y: (zoom_offset.y + offset.y) * -1 };
+ var scale_drag = { x: drag_offset.x * 1 / zoom,
+ y: drag_offset.y * 1 / zoom };
+ var scale_image_view = { width: image_view.width * 1 / zoom,
+ height: image_view.height * 1 / zoom };
+ return {
+ outputOffset: scale_drag,
+ outputSize: scale_image_view
+ };
}
}, {
key: 'getCroppedImageData',
@@ -643,7 +501,6 @@ return /******/ (function(modules) { // webpackBootstrap
if (!this.imageSrc) {
return;
}
-
var exportDefaults = {
type: 'image/png',
quality: 0.75,
@@ -651,53 +508,24 @@ return /******/ (function(modules) { // webpackBootstrap
fillBg: '#fff'
};
exportOptions = _jquery2['default'].extend({}, exportDefaults, exportOptions);
-
- var exportZoom = exportOptions.originalSize ? 1 / this.zoom : this.options.exportZoom;
-
- var zoomedSize = {
- w: this.zoom * exportZoom * this.imageSize.w,
- h: this.zoom * exportZoom * this.imageSize.h
- };
-
+ var geometry = this.getExportGeometry(exportOptions);
var canvas = (0, _jquery2['default'])('').attr({
- width: this.previewSize.w * exportZoom,
- height: this.previewSize.h * exportZoom
+ width: geometry.outputSize.width,
+ height: geometry.outputSize.height
}).get(0);
var canvasContext = canvas.getContext('2d');
-
if (exportOptions.type === 'image/jpeg') {
canvasContext.fillStyle = exportOptions.fillBg;
canvasContext.fillRect(0, 0, canvas.width, canvas.height);
}
-
- canvasContext.drawImage(this.image, this.offset.x * exportZoom, this.offset.y * exportZoom, zoomedSize.w, zoomedSize.h);
-
+ canvasContext.drawImage(this.image, geometry.outputOffset.x, geometry.outputOffset.y, geometry.outputSize.width, geometry.outputSize.height, 0, 0, geometry.outputSize.width, geometry.outputSize.height);
return canvas.toDataURL(exportOptions.type, exportOptions.quality);
}
- }, {
- key: 'getImageState',
- value: function getImageState() {
- return {
- src: this.imageSrc,
- offset: this.offset,
- zoom: this.zoom
- };
- }
}, {
key: 'getImageSrc',
value: function getImageSrc() {
return this.imageSrc;
}
- }, {
- key: 'getOffset',
- value: function getOffset() {
- return this.offset;
- }
- }, {
- key: 'getZoom',
- value: function getZoom() {
- return this.zoom;
- }
}, {
key: 'getImageSize',
value: function getImageSize() {
@@ -710,34 +538,6 @@ return /******/ (function(modules) { // webpackBootstrap
height: this.imageSize.h
};
}
- }, {
- key: 'getInitialZoom',
- value: function getInitialZoom() {
- return this.options.initialZoom;
- }
- }, {
- key: 'setInitialZoom',
- value: function setInitialZoom(initialZoomOption) {
- this.options.initialZoom = initialZoomOption;
- if (initialZoomOption === 'min') {
- this.initialZoom = 0; // Will be fixed when image loads
- } else if (initialZoomOption === 'image') {
- this.initialZoom = 1;
- } else {
- this.initialZoom = 0;
- }
- }
- }, {
- key: 'getExportZoom',
- value: function getExportZoom() {
- return this.options.exportZoom;
- }
- }, {
- key: 'setExportZoom',
- value: function setExportZoom(exportZoom) {
- this.options.exportZoom = exportZoom;
- this.setupZoomer();
- }
}, {
key: 'getMinZoom',
value: function getMinZoom() {
@@ -747,7 +547,7 @@ return /******/ (function(modules) { // webpackBootstrap
key: 'setMinZoom',
value: function setMinZoom(minZoom) {
this.options.minZoom = minZoom;
- this.setupZoomer();
+ this.$imageBg.panzoom('option', 'minScale', minZoom).panzoom('zoom');
}
}, {
key: 'getMaxZoom',
@@ -758,7 +558,7 @@ return /******/ (function(modules) { // webpackBootstrap
key: 'setMaxZoom',
value: function setMaxZoom(maxZoom) {
this.options.maxZoom = maxZoom;
- this.setupZoomer();
+ this.$imageBg.panzoom('option', 'maxScale', maxZoom).panzoom('zoom');
}
}, {
key: 'getPreviewSize',
@@ -784,16 +584,10 @@ return /******/ (function(modules) { // webpackBootstrap
height: this.previewSize.h
});
- if (this.options.imageBackground) {
- this.$imageBgContainer.css({
- width: this.previewSize.w + this.imageBgBorderWidthArray[1] + this.imageBgBorderWidthArray[3],
- height: this.previewSize.h + this.imageBgBorderWidthArray[0] + this.imageBgBorderWidthArray[2]
- });
- }
-
- if (this.imageLoaded) {
- this.setupZoomer();
- }
+ this.$imageBgContainer.css({
+ width: this.previewSize.w + this.imageBgBorderWidthArray[1] + this.imageBgBorderWidthArray[3],
+ height: this.previewSize.h + this.imageBgBorderWidthArray[0] + this.imageBgBorderWidthArray[2]
+ });
}
}, {
key: 'disable',
@@ -801,6 +595,7 @@ return /******/ (function(modules) { // webpackBootstrap
this.unbindListeners();
this.disableZoomSlider();
this.$el.addClass(_constants.CLASS_NAMES.DISABLED);
+ this.$imageBg.panzoom('disable');
}
}, {
key: 'reenable',
@@ -808,6 +603,7 @@ return /******/ (function(modules) { // webpackBootstrap
this.bindListeners();
this.enableZoomSlider();
this.$el.removeClass(_constants.CLASS_NAMES.DISABLED);
+ this.$imageBg.panzoom('enable');
}
}, {
key: '$',
@@ -827,91 +623,1243 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 3 */
-/***/ function(module, exports) {
-
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
-
- var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
-
- var Zoomer = (function () {
- function Zoomer() {
- _classCallCheck(this, Zoomer);
-
- this.minZoom = this.maxZoom = 1;
- }
-
- _createClass(Zoomer, [{
- key: 'setup',
- value: function setup(_ref) {
- var imageSize = _ref.imageSize;
- var previewSize = _ref.previewSize;
- var exportZoom = _ref.exportZoom;
- var maxZoom = _ref.maxZoom;
- var minZoom = _ref.minZoom;
- var smallImage = _ref.smallImage;
-
- var widthRatio = previewSize.w / imageSize.w;
- var heightRatio = previewSize.h / imageSize.h;
-
- if (minZoom === 'fit') {
- this.minZoom = Math.min(widthRatio, heightRatio);
- } else {
- this.minZoom = Math.max(widthRatio, heightRatio);
- }
-
- if (smallImage === 'allow') {
- this.minZoom = Math.min(this.minZoom, 1);
- }
-
- this.maxZoom = Math.max(this.minZoom, maxZoom / exportZoom);
- }
- }, {
- key: 'getZoom',
- value: function getZoom(sliderPos) {
- if (!this.minZoom || !this.maxZoom) {
- return null;
- }
-
- return sliderPos * (this.maxZoom - this.minZoom) + this.minZoom;
- }
- }, {
- key: 'getSliderPos',
- value: function getSliderPos(zoom) {
- if (!this.minZoom || !this.maxZoom) {
- return null;
- }
-
- if (this.minZoom === this.maxZoom) {
- return 0;
- } else {
- return (zoom - this.minZoom) / (this.maxZoom - this.minZoom);
- }
- }
- }, {
- key: 'isZoomable',
- value: function isZoomable() {
- if (!this.minZoom || !this.maxZoom) {
- return null;
- }
-
- return this.minZoom !== this.maxZoom;
- }
- }, {
- key: 'fixZoom',
- value: function fixZoom(zoom) {
- return Math.max(this.minZoom, Math.min(this.maxZoom, zoom));
- }
- }]);
+/***/ function(module, exports, __webpack_require__) {
- return Zoomer;
- })();
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
+ * @license jquery.panzoom.js v2.0.5
+ * Updated: Thu Apr 03 2014
+ * Add pan and zoom functionality to any element
+ * Copyright (c) 2014 timmy willison
+ * Released under the MIT license
+ * https://github.com/timmywil/jquery.panzoom/blob/master/MIT-License.txt
+ */
+
+ (function(global, factory) {
+ // AMD
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1) ], __WEBPACK_AMD_DEFINE_RESULT__ = function(jQuery) {
+ return factory(global, jQuery);
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+ // CommonJS/Browserify
+ } else if (typeof exports === 'object') {
+ factory(global, require('jquery'));
+ // Global
+ } else {
+ factory(global, global.jQuery);
+ }
+ }(typeof window !== 'undefined' ? window : this, function(window, $) {
+ 'use strict';
+
+ // Common properties to lift for touch or pointer events
+ var list = 'over out down up move enter leave cancel'.split(' ');
+ var hook = $.extend({}, $.event.mouseHooks);
+ var events = {};
+
+ // Support pointer events in IE11+ if available
+ if ( window.PointerEvent ) {
+ $.each(list, function( i, name ) {
+ // Add event name to events property and add fixHook
+ $.event.fixHooks[
+ (events[name] = 'pointer' + name)
+ ] = hook;
+ });
+ } else {
+ var mouseProps = hook.props;
+ // Add touch properties for the touch hook
+ hook.props = mouseProps.concat(['touches', 'changedTouches', 'targetTouches', 'altKey', 'ctrlKey', 'metaKey', 'shiftKey']);
+
+ /**
+ * Support: Android
+ * Android sets pageX/Y to 0 for any touch event
+ * Attach first touch's pageX/pageY and clientX/clientY if not set correctly
+ */
+ hook.filter = function( event, originalEvent ) {
+ var touch;
+ var i = mouseProps.length;
+ if ( !originalEvent.pageX && originalEvent.touches && (touch = originalEvent.touches[0]) ) {
+ // Copy over all mouse properties
+ while(i--) {
+ event[mouseProps[i]] = touch[mouseProps[i]];
+ }
+ }
+ return event;
+ };
+
+ $.each(list, function( i, name ) {
+ // No equivalent touch events for over and out
+ if (i < 2) {
+ events[ name ] = 'mouse' + name;
+ } else {
+ var touch = 'touch' +
+ (name === 'down' ? 'start' : name === 'up' ? 'end' : name);
+ // Add fixHook
+ $.event.fixHooks[ touch ] = hook;
+ // Add event names to events property
+ events[ name ] = touch + ' mouse' + name;
+ }
+ });
+ }
+
+ $.pointertouch = events;
+
+ var datakey = '__pz__';
+ var slice = Array.prototype.slice;
+ var pointerEvents = !!window.PointerEvent;
+
+ // Regex
+ var rupper = /([A-Z])/g;
+ var rsvg = /^http:[\w\.\/]+svg$/;
+ var rinline = /^inline/;
+
+ var floating = '(\\-?[\\d\\.e]+)';
+ var commaSpace = '\\,?\\s*';
+ var rmatrix = new RegExp(
+ '^matrix\\(' +
+ floating + commaSpace +
+ floating + commaSpace +
+ floating + commaSpace +
+ floating + commaSpace +
+ floating + commaSpace +
+ floating + '\\)$'
+ );
+
+ /**
+ * Utility for determing transform matrix equality
+ * Checks backwards to test translation first
+ * @param {Array} first
+ * @param {Array} second
+ */
+ function matrixEquals(first, second) {
+ var i = first.length;
+ while(--i) {
+ if (+first[i] !== +second[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Creates the options object for reset functions
+ * @param {Boolean|Object} opts See reset methods
+ * @returns {Object} Returns the newly-created options object
+ */
+ function createResetOptions(opts) {
+ var options = { range: true, animate: true };
+ if (typeof opts === 'boolean') {
+ options.animate = opts;
+ } else {
+ $.extend(options, opts);
+ }
+ return options;
+ }
+
+ /**
+ * Represent a transformation matrix with a 3x3 matrix for calculations
+ * Matrix functions adapted from Louis Remi's jQuery.transform (https://github.com/louisremi/jquery.transform.js)
+ * @param {Array|Number} a An array of six values representing a 2d transformation matrix
+ */
+ function Matrix(a, b, c, d, e, f, g, h, i) {
+ if ($.type(a) === 'array') {
+ this.elements = [
+ +a[0], +a[2], +a[4],
+ +a[1], +a[3], +a[5],
+ 0, 0, 1
+ ];
+ } else {
+ this.elements = [
+ a, b, c,
+ d, e, f,
+ g || 0, h || 0, i || 1
+ ];
+ }
+ }
+
+ Matrix.prototype = {
+ /**
+ * Multiply a 3x3 matrix by a similar matrix or a vector
+ * @param {Matrix|Vector} matrix
+ * @return {Matrix|Vector} Returns a vector if multiplying by a vector
+ */
+ x: function(matrix) {
+ var isVector = matrix instanceof Vector;
+
+ var a = this.elements,
+ b = matrix.elements;
+
+ if (isVector && b.length === 3) {
+ // b is actually a vector
+ return new Vector(
+ a[0] * b[0] + a[1] * b[1] + a[2] * b[2],
+ a[3] * b[0] + a[4] * b[1] + a[5] * b[2],
+ a[6] * b[0] + a[7] * b[1] + a[8] * b[2]
+ );
+ } else if (b.length === a.length) {
+ // b is a 3x3 matrix
+ return new Matrix(
+ a[0] * b[0] + a[1] * b[3] + a[2] * b[6],
+ a[0] * b[1] + a[1] * b[4] + a[2] * b[7],
+ a[0] * b[2] + a[1] * b[5] + a[2] * b[8],
+
+ a[3] * b[0] + a[4] * b[3] + a[5] * b[6],
+ a[3] * b[1] + a[4] * b[4] + a[5] * b[7],
+ a[3] * b[2] + a[4] * b[5] + a[5] * b[8],
+
+ a[6] * b[0] + a[7] * b[3] + a[8] * b[6],
+ a[6] * b[1] + a[7] * b[4] + a[8] * b[7],
+ a[6] * b[2] + a[7] * b[5] + a[8] * b[8]
+ );
+ }
+ return false; // fail
+ },
+ /**
+ * Generates an inverse of the current matrix
+ * @returns {Matrix}
+ */
+ inverse: function() {
+ var d = 1 / this.determinant(),
+ a = this.elements;
+ return new Matrix(
+ d * ( a[8] * a[4] - a[7] * a[5]),
+ d * (-(a[8] * a[1] - a[7] * a[2])),
+ d * ( a[5] * a[1] - a[4] * a[2]),
+
+ d * (-(a[8] * a[3] - a[6] * a[5])),
+ d * ( a[8] * a[0] - a[6] * a[2]),
+ d * (-(a[5] * a[0] - a[3] * a[2])),
+
+ d * ( a[7] * a[3] - a[6] * a[4]),
+ d * (-(a[7] * a[0] - a[6] * a[1])),
+ d * ( a[4] * a[0] - a[3] * a[1])
+ );
+ },
+ /**
+ * Calculates the determinant of the current matrix
+ * @returns {Number}
+ */
+ determinant: function() {
+ var a = this.elements;
+ return a[0] * (a[8] * a[4] - a[7] * a[5]) - a[3] * (a[8] * a[1] - a[7] * a[2]) + a[6] * (a[5] * a[1] - a[4] * a[2]);
+ }
+ };
+
+ /**
+ * Create a vector containing three values
+ */
+ function Vector(x, y, z) {
+ this.elements = [ x, y, z ];
+ }
+
+ /**
+ * Get the element at zero-indexed index i
+ * @param {Number} i
+ */
+ Vector.prototype.e = Matrix.prototype.e = function(i) {
+ return this.elements[ i ];
+ };
+
+ /**
+ * Create a Panzoom object for a given element
+ * @constructor
+ * @param {Element} elem - Element to use pan and zoom
+ * @param {Object} [options] - An object literal containing options to override default options
+ * (See Panzoom.defaults for ones not listed below)
+ * @param {jQuery} [options.$zoomIn] - zoom in buttons/links collection (you can also bind these yourself
+ * e.g. $button.on('click', function(e) { e.preventDefault(); $elem.panzooom('zoomIn'); });)
+ * @param {jQuery} [options.$zoomOut] - zoom out buttons/links collection on which to bind zoomOut
+ * @param {jQuery} [options.$zoomRange] - zoom in/out with this range control
+ * @param {jQuery} [options.$reset] - Reset buttons/links collection on which to bind the reset method
+ * @param {Function} [options.on[Start|Change|Zoom|Pan|End|Reset] - Optional callbacks for panzoom events
+ */
+ function Panzoom(elem, options) {
+
+ // Allow instantiation without `new` keyword
+ if (!(this instanceof Panzoom)) {
+ return new Panzoom(elem, options);
+ }
+
+ // Sanity checks
+ if (elem.nodeType !== 1) {
+ $.error('Panzoom called on non-Element node');
+ }
+ if (!$.contains(document, elem)) {
+ $.error('Panzoom element must be attached to the document');
+ }
+
+ // Don't remake
+ var d = $.data(elem, datakey);
+ if (d) {
+ return d;
+ }
+
+ // Extend default with given object literal
+ // Each instance gets its own options
+ this.options = options = $.extend({}, Panzoom.defaults, options);
+ this.elem = elem;
+ var $elem = this.$elem = $(elem);
+ this.$set = options.$set && options.$set.length ? options.$set : $elem;
+ this.$doc = $(elem.ownerDocument || document);
+ this.$parent = $elem.parent();
+
+ // This is SVG if the namespace is SVG
+ // However, while