UNPKG

react-accessible-lightbox

Version:
828 lines (814 loc) 115 kB
!function(root, factory) { "object" == typeof exports && "object" == typeof module ? module.exports = factory(require("react"), require("react-modal")) : "function" == typeof define && define.amd ? define([ "react", "react-modal" ], factory) : "object" == typeof exports ? exports.LightboxReact = factory(require("react"), require("react-modal")) : root.LightboxReact = factory(root.react, root["react-modal"]); }(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_15__) { /******/ return function(modules) { /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if (installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: !1 }; /******/ /******/ // Return the exports of the module /******/ /******/ /******/ // Execute the module function /******/ /******/ /******/ // Flag the module as loaded /******/ return modules[moduleId].call(module.exports, module, module.exports, __webpack_require__), module.loaded = !0, module.exports; } // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // Load entry module and return exports /******/ /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ /******/ /******/ // expose the module cache /******/ /******/ /******/ // __webpack_public_path__ /******/ return __webpack_require__.m = modules, __webpack_require__.c = installedModules, __webpack_require__.p = "", __webpack_require__(0); }([ /* 0 */ /***/ function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(3).default; }, /* 1 */ /***/ function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_1__; }, /* 2 */ /***/ function(module, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }); // Min image zoom level exports.MIN_ZOOM_LEVEL = 0, exports.MAX_ZOOM_LEVEL = 300, exports.ZOOM_RATIO = 1.007, exports.ZOOM_BUTTON_INCREMENT_SIZE = 100, exports.WHEEL_MOVE_X_THRESHOLD = 200, exports.WHEEL_MOVE_Y_THRESHOLD = 1, exports.KEYS = { ESC: 27, LEFT_ARROW: 37, RIGHT_ARROW: 39, UP_ARROW: 38, DOWN_ARROW: 40 }, exports.ACTION_NONE = 0, exports.ACTION_MOVE = 1, exports.ACTION_SWIPE = 2, exports.ACTION_PINCH = 3, exports.ACTION_ROTATE = 4, exports.SOURCE_ANY = 0, exports.SOURCE_MOUSE = 1, exports.SOURCE_TOUCH = 2, exports.SOURCE_POINTER = 3, exports.MIN_SWIPE_DISTANCE = 200; }, /* 3 */ /***/ function(module, exports, __webpack_require__) { "use strict"; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { return key in obj ? Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }) : obj[key] = value, obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); } function _possibleConstructorReturn(self, call) { if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !call || "object" != typeof call && "function" != typeof call ? self : call; } function _inherits(subClass, superClass) { if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: !1, writable: !0, configurable: !0 } }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass); } Object.defineProperty(exports, "__esModule", { value: !0 }); var _slicedToArray = function() { function sliceIterator(arr, i) { var _arr = [], _n = !0, _d = !1, _e = void 0; try { for (var _s, _i = arr[Symbol.iterator](); !(_n = (_s = _i.next()).done) && (_arr.push(_s.value), !i || _arr.length !== i); _n = !0) ; } catch (err) { _d = !0, _e = err; } finally { try { !_n && _i.return && _i.return(); } finally { if (_d) throw _e; } } return _arr; } return function(arr, i) { if (Array.isArray(arr)) return arr; if (Symbol.iterator in Object(arr)) return sliceIterator(arr, i); throw new TypeError("Invalid attempt to destructure non-iterable instance"); }; }(), _createClass = function() { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0, "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor); } } return function(Constructor, protoProps, staticProps) { return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps), Constructor; }; }(), _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); } return target; }, _react = __webpack_require__(1), _react2 = _interopRequireDefault(_react), _propTypes = __webpack_require__(11), _propTypes2 = _interopRequireDefault(_propTypes), _reactModal = __webpack_require__(15), _reactModal2 = _interopRequireDefault(_reactModal), _isReact = __webpack_require__(9), _isReact2 = _interopRequireDefault(_isReact), _util = __webpack_require__(4), _constant = __webpack_require__(2), _style = __webpack_require__(14), _style2 = _interopRequireDefault(_style), styles = _style2.default, _ieVersion = (0, _util.getIEVersion)(); _ieVersion < 10 && (styles = _extends({}, styles, { toolbarSide: styles.toolbarSide + " " + styles.toolbarSideNoFlex, toolbarLeftSide: styles.toolbarLeftSide + " " + styles.toolbarLeftSideNoFlex, toolbarRightSide: styles.toolbarRightSide + " " + styles.toolbarRightSideNoFlex })); var LightboxReact = function(_Component) { function LightboxReact(props) { _classCallCheck(this, LightboxReact); var _this = _possibleConstructorReturn(this, (LightboxReact.__proto__ || Object.getPrototypeOf(LightboxReact)).call(this, props)); return _this.state = { //----------------------------- // Animation //----------------------------- // Lightbox is closing // When Lightbox is mounted, if animation is enabled it will open with the reverse of the closing animation isClosing: !props.animationDisabled, // Component parts should animate (e.g., when images are moving, or image is being zoomed) shouldAnimate: !1, //----------------------------- // Zoom settings //----------------------------- // Zoom level of image zoomLevel: _constant.MIN_ZOOM_LEVEL, //----------------------------- // Image position settings //----------------------------- // Horizontal offset from center offsetX: 0, // Vertical offset from center offsetY: 0 }, _this.closeIfClickInner = _this.closeIfClickInner.bind(_this), _this.handleImageDoubleClick = _this.handleImageDoubleClick.bind(_this), _this.handleImageMouseWheel = _this.handleImageMouseWheel.bind(_this), _this.handleKeyInput = _this.handleKeyInput.bind(_this), _this.handleMouseUp = _this.handleMouseUp.bind(_this), _this.handleMouseDown = _this.handleMouseDown.bind(_this), _this.handleMouseMove = _this.handleMouseMove.bind(_this), _this.handleOuterMousewheel = _this.handleOuterMousewheel.bind(_this), _this.handleTouchStart = _this.handleTouchStart.bind(_this), _this.handleTouchMove = _this.handleTouchMove.bind(_this), _this.handleTouchEnd = _this.handleTouchEnd.bind(_this), _this.handlePointerEvent = _this.handlePointerEvent.bind(_this), _this.handleCaptionMousewheel = _this.handleCaptionMousewheel.bind(_this), _this.handleWindowResize = _this.handleWindowResize.bind(_this), _this.handleZoomInButtonClick = _this.handleZoomInButtonClick.bind(_this), _this.handleZoomOutButtonClick = _this.handleZoomOutButtonClick.bind(_this), _this.requestClose = _this.requestClose.bind(_this), _this.requestMoveNext = _this.requestMoveNext.bind(_this), _this.requestMovePrev = _this.requestMovePrev.bind(_this), _this.handleKeyUpEventEvent = _this.handleKeyUpEventEvent.bind(_this), _this; } return _inherits(LightboxReact, _Component), _createClass(LightboxReact, [ { key: "componentWillMount", value: function() { // Timeouts - always clear it before umount this.timeouts = [], // Current action this.currentAction = _constant.ACTION_NONE, // Events source this.eventsSource = _constant.SOURCE_ANY, // Empty pointers list this.pointerList = [], // Prevent inner close this.preventInnerClose = !1, this.preventInnerCloseTimeout = null, // Whether event listeners for keyboard and mouse input have been attached or not this.listenersAttached = !1, // Used to disable animation when changing props.mainSrc|nextSrc|prevSrc this.keyPressed = !1, // Used to store load state / dimensions of images this.imageCache = {}, // Time the last keydown event was called (used in keyboard action rate limiting) this.lastKeyDownTime = 0, // Used for debouncing window resize event this.resizeTimeout = null, // Used to determine when actions are triggered by the scroll wheel this.wheelActionTimeout = null, this.resetScrollTimeout = null, this.scrollX = 0, this.scrollY = 0, // Used in panning zoomed images this.moveStartX = 0, this.moveStartY = 0, this.moveStartOffsetX = 0, this.moveStartOffsetY = 0, // Used to swipe this.swipeStartX = 0, this.swipeStartY = 0, this.swipeEndX = 0, this.swipeEndY = 0, // Used to pinch this.pinchTouchList = null, this.pinchDistance = 0, // Used to differentiate between images with identical src this.keyCounter = 0, // Used to detect a move when all src's remain unchanged (four or more of the same image in a row) this.moveRequested = !1, this.props.animationDisabled || // Make opening animation play this.setState({ isClosing: !1 }); } }, { key: "componentDidMount", value: function() { this.mounted = !0, this.attachListeners(), this.loadAllImages(); } }, { key: "shouldComponentUpdate", value: function() { // Wait for move... return !this.moveRequested; } }, { key: "componentWillReceiveProps", value: function(nextProps) { var _this2 = this, sourcesChanged = !1, prevSrcDict = {}, nextSrcDict = {}; this.getSrcTypes().forEach(function(srcType) { _this2.props[srcType.name] !== nextProps[srcType.name] && (sourcesChanged = !0, prevSrcDict[_this2.props[srcType.name]] = !0, nextSrcDict[nextProps[srcType.name]] = !0); }), (sourcesChanged || this.moveRequested) && (// Reset the loaded state for images not rendered next Object.keys(prevSrcDict).forEach(function(prevSrc) { !(prevSrc in nextSrcDict) && prevSrc in _this2.imageCache && (_this2.imageCache[prevSrc].loaded = !1); }), this.moveRequested = !1, // Load any new images this.loadAllImages(nextProps)); } }, { key: "componentWillUnmount", value: function() { this.mounted = !1, this.detachListeners(), this.timeouts.forEach(function(tid) { return clearTimeout(tid); }); } }, { key: "setTimeout", value: function(_setTimeout) { function setTimeout(_x, _x2) { return _setTimeout.apply(this, arguments); } return setTimeout.toString = function() { return _setTimeout.toString(); }, setTimeout; }(function(func, time) { var _this3 = this, id = setTimeout(function() { _this3.timeouts = _this3.timeouts.filter(function(tid) { return tid !== id; }), func(); }, time); return this.timeouts.push(id), id; }) }, { key: "clearTimeout", value: function(_clearTimeout) { function clearTimeout(_x3) { return _clearTimeout.apply(this, arguments); } return clearTimeout.toString = function() { return _clearTimeout.toString(); }, clearTimeout; }(function(id) { this.timeouts = this.timeouts.filter(function(tid) { return tid !== id; }), clearTimeout(id); }) }, { key: "attachListeners", value: function() { this.listenersAttached || "undefined" == typeof window || (window.addEventListener("resize", this.handleWindowResize), window.addEventListener("mouseup", this.handleMouseUp), window.addEventListener("touchend", this.handleTouchEnd), window.addEventListener("touchcancel", this.handleTouchEnd), window.addEventListener("pointerdown", this.handlePointerEvent), window.addEventListener("pointermove", this.handlePointerEvent), window.addEventListener("pointerup", this.handlePointerEvent), window.addEventListener("pointercancel", this.handlePointerEvent), window.top.addEventListener("keydown", this.handleKeyUpEventEvent), // Have to add an extra mouseup handler to catch mouseup events outside of the window // if the page containing the lightbox is displayed in an iframe (0, _util.isInSameOriginIframe)() && (window.top.addEventListener("mouseup", this.handleMouseUp), window.top.addEventListener("touchend", this.handleTouchEnd), window.top.addEventListener("touchcancel", this.handleTouchEnd), window.top.addEventListener("pointerdown", this.handlePointerEvent), window.top.addEventListener("pointermove", this.handlePointerEvent), window.top.addEventListener("pointerup", this.handlePointerEvent), window.top.addEventListener("pointercancel", this.handlePointerEvent), window.top.addEventListener("keydown", this.handleKeyUpEventEvent)), this.listenersAttached = !0); } }, { key: "changeZoom", value: function(zoomLevel, clientX, clientY) { // Ignore if zoom disabled if (this.props.enableZoom) { // Constrain zoom level to the set bounds var nextZoomLevel = Math.max(_constant.MIN_ZOOM_LEVEL, Math.min(_constant.MAX_ZOOM_LEVEL, zoomLevel)); // Ignore requests that don't change the zoom level if (nextZoomLevel !== this.state.zoomLevel) { if (nextZoomLevel === _constant.MIN_ZOOM_LEVEL) // Snap back to center if zoomed all the way out return this.setState({ zoomLevel: nextZoomLevel, offsetX: 0, offsetY: 0 }); var imageBaseSize = this.getBestImageForType("mainSrc"); if (null !== imageBaseSize) { var currentZoomMultiplier = this.getZoomMultiplier(), nextZoomMultiplier = this.getZoomMultiplier(nextZoomLevel), boxRect = this.getLightboxRect(), pointerX = "undefined" != typeof clientX ? clientX - boxRect.left : boxRect.width / 2, pointerY = "undefined" != typeof clientY ? clientY - boxRect.top : boxRect.height / 2, currentImageOffsetX = (boxRect.width - imageBaseSize.width * currentZoomMultiplier) / 2, currentImageOffsetY = (boxRect.height - imageBaseSize.height * currentZoomMultiplier) / 2, currentImageRealOffsetX = currentImageOffsetX - this.state.offsetX, currentImageRealOffsetY = currentImageOffsetY - this.state.offsetY, currentPointerXRelativeToImage = (pointerX - currentImageRealOffsetX) / currentZoomMultiplier, currentPointerYRelativeToImage = (pointerY - currentImageRealOffsetY) / currentZoomMultiplier, nextImageRealOffsetX = pointerX - currentPointerXRelativeToImage * nextZoomMultiplier, nextImageRealOffsetY = pointerY - currentPointerYRelativeToImage * nextZoomMultiplier, nextImageOffsetX = (boxRect.width - imageBaseSize.width * nextZoomMultiplier) / 2, nextImageOffsetY = (boxRect.height - imageBaseSize.height * nextZoomMultiplier) / 2, nextOffsetX = nextImageOffsetX - nextImageRealOffsetX, nextOffsetY = nextImageOffsetY - nextImageRealOffsetY; // When zooming out, limit the offset so things don't get left askew if (this.currentAction !== _constant.ACTION_PINCH) { var maxOffsets = this.getMaxOffsets(); this.state.zoomLevel > nextZoomLevel && (nextOffsetX = Math.max(maxOffsets.minX, Math.min(maxOffsets.maxX, nextOffsetX)), nextOffsetY = Math.max(maxOffsets.minY, Math.min(maxOffsets.maxY, nextOffsetY))); } this.setState({ zoomLevel: nextZoomLevel, offsetX: nextOffsetX, offsetY: nextOffsetY }); } } } } }, { key: "closeIfClickInner", value: function(event) { !this.preventInnerClose && event.target.className.search(/\bril-inner\b/) > -1 && this.requestClose(event); } }, { key: "setPreventInnerClose", value: function() { var _this4 = this; this.preventInnerCloseTimeout && this.clearTimeout(this.preventInnerCloseTimeout), this.preventInnerClose = !0, this.preventInnerCloseTimeout = this.setTimeout(function() { _this4.preventInnerClose = !1, _this4.preventInnerCloseTimeout = null; }, 100); } }, { key: "detachListeners", value: function() { this.listenersAttached && (window.removeEventListener("resize", this.handleWindowResize), window.removeEventListener("keydown", this.handleKeyUpEventEvent), window.removeEventListener("mouseup", this.handleMouseUp), window.removeEventListener("touchend", this.handleTouchEnd), window.removeEventListener("touchcancel", this.handleTouchEnd), window.removeEventListener("pointerdown", this.handlePointerEvent), window.removeEventListener("pointermove", this.handlePointerEvent), window.removeEventListener("pointerup", this.handlePointerEvent), window.removeEventListener("pointercancel", this.handlePointerEvent), (0, _util.isInSameOriginIframe)() && (window.top.removeEventListener("mouseup", this.handleMouseUp), window.top.removeEventListener("touchend", this.handleTouchEnd), window.top.removeEventListener("touchcancel", this.handleTouchEnd), window.top.removeEventListener("pointerdown", this.handlePointerEvent), window.top.removeEventListener("pointermove", this.handlePointerEvent), window.top.removeEventListener("pointerup", this.handlePointerEvent), window.top.removeEventListener("pointercancel", this.handlePointerEvent), window.top.removeEventListener("keydown", this.handleKeyUpEventEvent)), this.listenersAttached = !1); } }, { key: "getBestImageForType", value: function(srcType) { var imageSrc = this.props[srcType], fitSizes = {}; if (this.isImageLoaded(imageSrc)) // Use full-size image if available fitSizes = this.getFitSizes(this.imageCache[imageSrc].width, this.imageCache[imageSrc].height); else if (this.isImageLoaded(this.props[srcType + "Thumbnail"])) // Fall back to using thumbnail if the image has not been loaded imageSrc = this.props[srcType + "Thumbnail"], fitSizes = this.getFitSizes(this.imageCache[imageSrc].width, this.imageCache[imageSrc].height, !0); else { if (!_isReact2.default.component(this.props[srcType]) && !_isReact2.default.element(this.props[srcType])) return null; if (document.querySelectorAll(".inner").length > 0 && !(this.state.zoomLevel > _constant.MIN_ZOOM_LEVEL)) { var theCanvases = this.props.prevSrc && this.props.nextSrc ? document.querySelectorAll(".inner")[0].childNodes[1].childNodes[0] : document.querySelectorAll(".inner")[0].childNodes[0].childNodes[0], maxWidth = 900, aCanvasO = theCanvases, theTableO = aCanvasO.getElementsByTagName("table")[0]; // Get the 1st table (should be the only table) //var spacerO = aCanvasO.nextElementSibling // Remove any leftover scaling and spacer sizes - important for viewport resizing theTableO.style.transform = "", theTableO.style.position = "relative", // spacerO.style.height = '' // Pop open each .scaling-canvas to see how big the table becomes // IMPORTANT: '.scaling-canvas table:first-child' MUST have 'position: absolute' defined in CSS // in order for wide tables to not influence measurements on intial page load aCanvasO.style.position = "absolute", aCanvasO.style.width = maxWidth + "px"; // } // Next, we take measurements and scale the tables if needed // for (var i = 0; i < arrayLength; i++) { var aCanvas = theCanvases, theTable = aCanvas.getElementsByTagName("table")[0], spacer = document.querySelectorAll(".inner")[0].childNodes[0], availableWidth = Math.floor(spacer.clientWidth), actualTableWidth = theTable.offsetWidth, actualTableHeight = theTable.offsetHeight, computedStyle = getComputedStyle(theTable); // Measure all table values in pixels actualTableWidth += Math.ceil(parseInt(computedStyle.marginLeft) + parseInt(computedStyle.marginRight)), actualTableHeight += Math.ceil(parseInt(computedStyle.marginTop) + parseInt(computedStyle.marginBottom)); // Calculate the scaling factor var scale = availableWidth / actualTableWidth; // If the scale is < 1, then scale the table, otherwise put .scaling-canvas back to defaults scale < 1 ? (// Scale the table // We hard-set the table width and height here so that it's not recalculated later theTable.style.width = actualTableWidth + "px", theTable.style.transformOrigin = "top left", theTable.style.transform = "scale(" + scale + ")", // Size the spacing container to provide proper vertical spacing. // Its width defaults to 'auto' so no need to adjust that. spacer.style.height = actualTableHeight * scale + "px", // Reposition the zoom button // Size the canvas - in case overflow: hidden is not on parent aCanvas.style.height = actualTableHeight * scale + "px", aCanvas.style.width = availableWidth + "px") : (// Set the scaling canvas back to defaults aCanvas.style.position = "relative", aCanvas.style.width = ""), // let componentWidth = component.offsetWidth; // let componentWrapperWidth = document.querySelectorAll('.inner')[0].childNodes[0].offsetWidth; // let fontSize = 18; // // while (componentWidth >= componentWrapperWidth && fontSize > 4) { // component.style.fontSize = `${fontSize}px`; // componentWidth = component.offsetWidth; // componentWrapperWidth = document.querySelectorAll('.inner')[0].childNodes[0].offsetWidth; // fontSize--; // } fitSizes = this.getFitSizes(theCanvases.style.width, theCanvases.style.height); } else if (document.querySelectorAll(".inner").length > 0) { var _theCanvases = this.props.prevSrc && this.props.nextSrc ? document.querySelectorAll(".inner")[0].childNodes[1].childNodes[0] : document.querySelectorAll(".inner")[0].childNodes[0].childNodes[0]; fitSizes = this.getFitSizes(_theCanvases.offsetWidth, _theCanvases.offsetHeight); } } return { src: imageSrc, height: fitSizes.height, width: fitSizes.width }; } }, { key: "getFitSizes", value: function(width, height, stretch) { var boxSize = this.getLightboxRect(), maxHeight = boxSize.height - 2 * this.props.imagePadding, maxWidth = boxSize.width - 2 * this.props.imagePadding; stretch || (maxHeight = Math.min(maxHeight, height), maxWidth = Math.min(maxWidth, width)); var maxRatio = maxWidth / maxHeight, srcRatio = width / height; return maxRatio > srcRatio ? { width: width * maxHeight / height, height: maxHeight } : { width: maxWidth, height: height * maxWidth / width }; } }, { key: "getMaxOffsets", value: function() { var zoomLevel = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : this.state.zoomLevel, currentImageInfo = this.getBestImageForType("mainSrc"); if (null === currentImageInfo) return { maxX: 0, minX: 0, maxY: 0, minY: 0 }; var boxSize = this.getLightboxRect(), zoomMultiplier = this.getZoomMultiplier(zoomLevel), maxX = 0; // if there is still blank space in the X dimension, don't limit except to the opposite edge maxX = zoomMultiplier * currentImageInfo.width - boxSize.width < 0 ? (boxSize.width - zoomMultiplier * currentImageInfo.width) / 2 : (zoomMultiplier * currentImageInfo.width - boxSize.width) / 2; var maxY = 0; // if there is still blank space in the Y dimension, don't limit except to the opposite edge return maxY = zoomMultiplier * currentImageInfo.height - boxSize.height < 0 ? (boxSize.height - zoomMultiplier * currentImageInfo.height) / 2 : (zoomMultiplier * currentImageInfo.height - boxSize.height) / 2, { maxX: maxX, maxY: maxY, minX: -1 * maxX, minY: -1 * maxY }; } }, { key: "getSrcTypes", value: function() { return [ { name: "mainSrc", keyEnding: "i" + this.keyCounter }, { name: "mainSrcThumbnail", keyEnding: "t" + this.keyCounter }, { name: "nextSrc", keyEnding: "i" + (this.keyCounter + 1) }, { name: "nextSrcThumbnail", keyEnding: "t" + (this.keyCounter + 1) }, { name: "prevSrc", keyEnding: "i" + (this.keyCounter - 1) }, { name: "prevSrcThumbnail", keyEnding: "t" + (this.keyCounter - 1) } ]; } }, { key: "getZoomMultiplier", value: function() { var zoomLevel = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : this.state.zoomLevel; return Math.pow(_constant.ZOOM_RATIO, zoomLevel); } }, { key: "getLightboxRect", value: function() { return this.outerEl ? this.outerEl.getBoundingClientRect() : { width: (0, _util.getWindowWidth)(), height: (0, _util.getWindowHeight)(), top: 0, right: 0, bottom: 0, left: 0 }; } }, { key: "handleKeyInput", value: function(event) { // this will prevent key up event in order to avoid that commented this //event.stopPropagation(); // Ignore key input during animations if (!this.isAnimating()) { // Allow slightly faster navigation through the images when user presses keys repeatedly if ("keyup" === event.type) return void (this.lastKeyDownTime -= this.props.keyRepeatKeyupBonus); var keyCode = event.which || event.keyCode, currentTime = new Date(); if (!(currentTime.getTime() - this.lastKeyDownTime < this.props.keyRepeatLimit && keyCode !== _constant.KEYS.ESC)) switch (this.lastKeyDownTime = currentTime.getTime(), keyCode) { // ESC key closes the lightbox case _constant.KEYS.ESC: event.preventDefault(), this.requestClose(event); break; // Left arrow key moves to previous image case _constant.KEYS.LEFT_ARROW: if (!this.props.prevSrc || this.state.zoomLevel !== _constant.MIN_ZOOM_LEVEL) return; event.preventDefault(), this.keyPressed = !0, this.requestMovePrev(event); break; // Right arrow key moves to next image case _constant.KEYS.RIGHT_ARROW: if (!this.props.nextSrc || this.state.zoomLevel !== _constant.MIN_ZOOM_LEVEL) return; event.preventDefault(), this.keyPressed = !0, this.requestMoveNext(event); } } } }, { key: "handleOuterMousewheel", value: function(event) { var _this5 = this; // Prevent scrolling of the background event.preventDefault(), event.stopPropagation(); var xThreshold = _constant.WHEEL_MOVE_X_THRESHOLD, actionDelay = 0, imageMoveDelay = 500; // Prevent rapid-fire zoom behavior if (this.clearTimeout(this.resetScrollTimeout), this.resetScrollTimeout = this.setTimeout(function() { _this5.scrollX = 0, _this5.scrollY = 0; }, 300), null === this.wheelActionTimeout && !this.isAnimating()) { if (Math.abs(event.deltaY) < Math.abs(event.deltaX)) { // handle horizontal scrolls with image moves this.scrollY = 0, this.scrollX += event.deltaX; var bigLeapX = xThreshold / 2; // If the scroll amount has accumulated sufficiently, or a large leap was taken this.scrollX >= xThreshold || event.deltaX >= bigLeapX ? (// Scroll right moves to next this.requestMoveNext(event), actionDelay = imageMoveDelay, this.scrollX = 0) : (this.scrollX <= -1 * xThreshold || event.deltaX <= -1 * bigLeapX) && (// Scroll left moves to previous this.requestMovePrev(event), actionDelay = imageMoveDelay, this.scrollX = 0); } // Allow successive actions after the set delay 0 !== actionDelay && (this.wheelActionTimeout = this.setTimeout(function() { _this5.wheelActionTimeout = null; }, actionDelay)); } } }, { key: "handleImageMouseWheel", value: function(event) { event.preventDefault(); var yThreshold = _constant.WHEEL_MOVE_Y_THRESHOLD; if (Math.abs(event.deltaY) >= Math.abs(event.deltaX)) { // If the vertical scroll amount was large enough, perform a zoom if (event.stopPropagation(), Math.abs(event.deltaY) < yThreshold) return; this.scrollX = 0, this.scrollY += event.deltaY, this.changeZoom(this.state.zoomLevel - event.deltaY, event.clientX, event.clientY); } } }, { key: "handleImageDoubleClick", value: function(event) { this.state.zoomLevel > _constant.MIN_ZOOM_LEVEL ? // A double click when zoomed in zooms all the way out this.changeZoom(_constant.MIN_ZOOM_LEVEL, event.clientX, event.clientY) : // A double click when zoomed all the way out zooms in this.changeZoom(this.state.zoomLevel + _constant.ZOOM_BUTTON_INCREMENT_SIZE, event.clientX, event.clientY); } }, { key: "shouldHandleEvent", value: function(source) { if (this.eventsSource === source) return !0; if (this.eventsSource === _constant.SOURCE_ANY) return this.eventsSource = source, !0; switch (source) { case _constant.SOURCE_MOUSE: return !1; case _constant.SOURCE_TOUCH: return this.eventsSource = _constant.SOURCE_TOUCH, this.filterPointersBySource(), !0; case _constant.SOURCE_POINTER: return this.eventsSource === _constant.SOURCE_MOUSE && (this.eventsSource = _constant.SOURCE_POINTER, this.filterPointersBySource(), !0); default: return !1; } } }, { key: "addPointer", value: function(pointer) { this.pointerList.push(pointer); } }, { key: "removePointer", value: function(pointer) { this.pointerList = this.pointerList.filter(function(_ref) { var id = _ref.id; return id !== pointer.id; }); } }, { key: "filterPointersBySource", value: function() { var _this6 = this; this.pointerList = this.pointerList.filter(function(_ref2) { var source = _ref2.source; return source === _this6.eventsSource; }); } }, { key: "handleMouseDown", value: function(event) { // remove isTargetMatchImage this.shouldHandleEvent(_constant.SOURCE_MOUSE) && (this.addPointer(LightboxReact.parseMouseEvent(event)), this.multiPointerStart(event)); } }, { key: "handleMouseMove", value: function(event) { this.shouldHandleEvent(_constant.SOURCE_MOUSE) && LightboxReact.isTargetMatchImage(event.target) && this.multiPointerMove(event, [ LightboxReact.parseMouseEvent(event) ]); } }, { key: "handleMouseUp", value: function(event) { this.shouldHandleEvent(_constant.SOURCE_MOUSE) && (this.removePointer(LightboxReact.parseMouseEvent(event)), this.multiPointerEnd(event)); } }, { key: "handlePointerEvent", value: function(event) { if (this.shouldHandleEvent(_constant.SOURCE_POINTER)) switch (event.type) { case "pointerdown": // commented this to facilitate to drag the tables after zooming this.addPointer(LightboxReact.parsePointerEvent(event)), this.multiPointerStart(event); break; case "pointermove": this.multiPointerMove(event, [ LightboxReact.parsePointerEvent(event) ]); break; case "pointerup": case "pointercancel": this.removePointer(LightboxReact.parsePointerEvent(event)), this.multiPointerEnd(event); } } }, { key: "handleTouchStart", value: function(event) { var _this7 = this; this.shouldHandleEvent(_constant.SOURCE_TOUCH) && LightboxReact.isTargetMatchImage(event.target) && ([].forEach.call(event.changedTouches, function(eventTouch) { return _this7.addPointer(LightboxReact.parseTouchPointer(eventTouch)); }), this.multiPointerStart(event)); } }, { key: "handleTouchMove", value: function(event) { event.preventDefault(), this.shouldHandleEvent(_constant.SOURCE_TOUCH) && this.multiPointerMove(event, [].map.call(event.changedTouches, function(eventTouch) { return LightboxReact.parseTouchPointer(eventTouch); })); } }, { key: "handleTouchEnd", value: function(event) { var _this8 = this; this.shouldHandleEvent(_constant.SOURCE_TOUCH) && ([].map.call(event.changedTouches, function(touch) { return _this8.removePointer(LightboxReact.parseTouchPointer(touch)); }), this.multiPointerEnd(event)); } }, { key: "decideMoveOrSwipe", value: function(pointer) { this.state.zoomLevel <= _constant.MIN_ZOOM_LEVEL ? this.handleSwipeStart(pointer) : this.handleMoveStart(pointer); } }, { key: "multiPointerStart", value: function(event) { switch (this.handleEnd(null), this.pointerList.length) { case 1: event.preventDefault(), this.decideMoveOrSwipe(this.pointerList[0]); break; case 2: event.preventDefault(), this.handlePinchStart(this.pointerList); } } }, { key: "multiPointerMove", value: function(event, pointerList) { switch (this.currentAction) { case _constant.ACTION_MOVE: event.preventDefault(), this.handleMove(pointerList[0]); break; case _constant.ACTION_SWIPE: event.preventDefault(), this.handleSwipe(pointerList[0]); break; case _constant.ACTION_PINCH: event.preventDefault(), this.handlePinch(pointerList); } } }, { key: "multiPointerEnd", value: function(event) { switch (this.currentAction !== _constant.ACTION_NONE && (this.setPreventInnerClose(), this.handleEnd(event)), this.pointerList.length) { case 0: this.eventsSource = _constant.SOURCE_ANY; break; case 1: event.preventDefault(), this.decideMoveOrSwipe(this.pointerList[0]); break; case 2: event.preventDefault(), this.handlePinchStart(this.pointerList); } } }, { key: "handleEnd", value: function(event) { switch (this.currentAction) { case _constant.ACTION_MOVE: this.handleMoveEnd(event); break; case _constant.ACTION_SWIPE: this.handleSwipeEnd(event); break; case _constant.ACTION_PINCH: this.handlePinchEnd(event); } } }, { key: "handleMoveStart", value: function(_ref3) { var clientX = _ref3.x, clientY = _ref3.y; this.props.enableZoom && (this.currentAction = _constant.ACTION_MOVE, this.moveStartX = clientX, this.moveStartY = clientY, this.moveStartOffsetX = this.state.offsetX, this.moveStartOffsetY = this.state.offsetY); } }, { key: "handleMove", value: function(_ref4) { var clientX = _ref4.x, clientY = _ref4.y, newOffsetX = this.moveStartX - clientX + this.moveStartOffsetX, newOffsetY = this.moveStartY - clientY + this.moveStartOffsetY; this.state.offsetX === newOffsetX && this.state.offsetY === newOffsetY || this.setState({ offsetX: newOffsetX, offsetY: newOffsetY }); } }, { key: "handleMoveEnd", value: function() { var _this9 = this; this.currentAction = _constant.ACTION_NONE, this.moveStartX = 0, this.moveStartY = 0, this.moveStartOffsetX = 0, this.moveStartOffsetY = 0; // Snap image back into frame if outside max offset range var maxOffsets = this.getMaxOffsets(), nextOffsetX = Math.max(maxOffsets.minX, Math.min(maxOffsets.maxX, this.state.offsetX)), nextOffsetY = Math.max(maxOffsets.minY, Math.min(maxOffsets.maxY, this.state.offsetY)); nextOffsetX === this.state.offsetX && nextOffsetY === this.state.offsetY || (this.setState({ offsetX: nextOffsetX, offsetY: nextOffsetY, shouldAnimate: !0 }), this.setTimeout(function() { _this9.setState({ shouldAnimate: !1 }); }, this.props.animationDuration)); } }, { key: "handleSwipeStart", value: function(_ref5) { var clientX = _ref5.x, clientY = _ref5.y; this.currentAction = _constant.ACTION_SWIPE, this.swipeStartX = clientX, this.swipeStartY = clientY, this.swipeEndX = clientX, this.swipeEndY = clientY; } }, { key: "handleSwipe", value: function(_ref6) { var clientX = _ref6.x, clientY = _ref6.y; this.swipeEndX = clientX, this.swipeEndY = clientY; } }, { key: "handleSwipeEnd", value: function(event) { var xDiff = this.swipeEndX - this.swipeStartX, xDiffAbs = Math.abs(xDiff), yDiffAbs = Math.abs(this.swipeEndY - this.swipeStartY); if (this.currentAction = _constant.ACTION_NONE, this.swipeStartX = 0, this.swipeStartY = 0, this.swipeEndX = 0, this.swipeEndY = 0, !(!event || this.isAnimating() || xDiffAbs < 1.5 * yDiffAbs)) { if (xDiffAbs < _constant.MIN_SWIPE_DISTANCE) { var boxRect = this.getLightboxRect(); if (xDiffAbs < boxRect.width / 4) return; } xDiff > 0 && this.props.prevSrc ? (event.preventDefault(), this.requestMovePrev()) : xDiff < 0 && this.props.nextSrc && (event.preventDefault(), this.requestMoveNext()); } } }, { key: "calculatePinchDistance", value: function() { var _ref7 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : this.pinchTouchList, _ref8 = _slicedToArray(_ref7, 2), a = _ref8[0], b = _ref8[1]; return Math.sqrt(Math.po