{"version":3,"file":null,"sources":["../src/util/_dom.js","../src/util/_image.js","../src/util/_trans.js","../src/util/_math.js","../src/util/_helpers.js","../src/EventHandler.js","../src/Target.js","../src/Overlay.js","../src/_options.js","../src/Zooming.js","../src/main.js"],"sourcesContent":["export const body = document.body\nexport const docElm = document.documentElement\nexport const isString = checkType('string')\nexport const isLink = checkTag('A')\nexport const webkitPrefix = 'WebkitAppearance' in docElm.style\n ? '-webkit-'\n : ''\n\nexport function checkType (typeName) {\n return function (el) {\n return typeof el === typeName\n }\n}\n\nexport function checkTag (tagName) {\n return function (el) {\n return el.tagName === tagName\n }\n}\n\nexport function getParents (el, match) {\n let parents = []\n\n for (; el && el !== document; el = el.parentNode) {\n if (match) {\n if (match(el)) {\n parents.push(el)\n }\n } else {\n parents.push(el)\n }\n }\n\n return parents\n}\n","import { checkTag, isLink } from './_dom'\n\nexport function isNotImage () {\n return checkTag('IMG') === false\n}\n\nexport function loadImage (src, cb) {\n if (!src) return\n\n const img = new Image()\n img.onload = function () {\n if (cb) cb(img)\n }\n \n img.src = src\n}\n\nexport function checkOriginalImage (el, cb) {\n let srcOriginal = null\n\n if (el.hasAttribute('data-original')) {\n srcOriginal = el.getAttribute('data-original')\n } else if (isLink(el.parentNode)) {\n srcOriginal = el.parentNode.getAttribute('href')\n }\n\n cb(srcOriginal)\n}\n","const trans = sniffTransition(document.createElement('div'))\nexport const transformCssProp = trans.transformCssProp\nexport const transEndEvent = trans.transEndEvent\n\nexport function checkTrans (styles) {\n const transitionProp = trans.transitionProp\n const transformProp = trans.transformProp\n\n let value\n if (styles.transition) {\n value = styles.transition\n delete styles.transition\n styles[transitionProp] = value\n }\n if (styles.transform) {\n value = styles.transform\n delete styles.transform\n styles[transformProp] = value\n }\n}\n\nexport function sniffTransition (el) {\n let ret = {}\n const trans = ['webkitTransition', 'transition', 'mozTransition']\n const tform = ['webkitTransform', 'transform', 'mozTransform']\n const end = {\n 'transition' : 'transitionend',\n 'mozTransition' : 'transitionend',\n 'webkitTransition' : 'webkitTransitionEnd'\n }\n\n trans.some(prop => {\n if (el.style[prop] !== undefined) {\n ret.transitionProp = prop\n ret.transEndEvent = end[prop]\n return true\n }\n })\n\n tform.some(prop => {\n if (el.style[prop] !== undefined) {\n ret.transformProp = prop\n ret.transformCssProp = prop.replace(/(.*)Transform/, '-$1-transform')\n return true\n }\n })\n\n return ret\n}\n","function divide (denominator) {\n return (numerator) => {\n return numerator / denominator\n }\n}\n\nexport const half = divide(2)\n","import { docElm, webkitPrefix, getParents } from './_dom'\nimport { checkTrans } from './_trans'\nimport { half } from './_math'\n\nexport const cursor = {\n default: 'auto',\n zoomIn: `${webkitPrefix}zoom-in`,\n zoomOut: `${webkitPrefix}zoom-out`,\n grab: `${webkitPrefix}grab`,\n move: 'move'\n}\n\nexport function toggleListener (el, type, handler, add) {\n if (add) {\n el.addEventListener(type, handler[type], { passive: false })\n } else {\n el.removeEventListener(type, handler[type], { passive: false })\n }\n}\n\nexport function getWindowCenter () {\n const windowWidth = Math.min(docElm.clientWidth, window.innerWidth)\n const windowHeight = Math.min(docElm.clientHeight, window.innerHeight)\n\n return {\n x: half(windowWidth),\n y: half(windowHeight)\n }\n}\n\nexport function toggleGrabListeners (el, handler, add) {\n ['mousedown', 'mousemove', 'mouseup','touchstart', 'touchmove', 'touchend']\n .forEach(type => {\n toggleListener(el, type, handler, add)\n })\n}\n\nexport function setStyle (el, styles, remember) {\n checkTrans(styles)\n\n let s = el.style\n let original = {}\n\n for (let key in styles) {\n if (remember) original[key] = s[key] || ''\n s[key] = styles[key]\n }\n\n return original\n}\n\nexport function bindAll (_this, that) {\n const methods = (\n Object.getOwnPropertyNames(\n Object.getPrototypeOf(_this)\n )\n )\n\n methods.forEach(method => {\n _this[method] = _this[method].bind(that)\n })\n}\n\nexport const overflowHiddenParents = {\n\n // Map from Element to its overflow:hidden parents\n map: new Map(),\n\n // Map from parent to its original style\n style: new Map(),\n\n disable: disableOverflowHiddenParents,\n enable: enableOverflowHiddenParents\n}\n\nfunction isOverflowHidden (el) {\n return getComputedStyle(el).overflow === 'hidden'\n}\n\nfunction getOverflowHiddenParents (el) {\n if (overflowHiddenParents.map.has(el)) {\n return overflowHiddenParents.map.get(el)\n } else {\n const parents = getParents(el.parentNode, isOverflowHidden)\n overflowHiddenParents.map.set(el, parents)\n return parents\n }\n}\n\nfunction disableOverflowHiddenParents (el) {\n getOverflowHiddenParents(el).forEach(parent => {\n if (overflowHiddenParents.style.has(parent)) {\n setStyle(parent, {\n overflow: 'visible'\n })\n } else {\n overflowHiddenParents.style.set(parent, setStyle(parent, {\n overflow: 'visible'\n }, true))\n }\n })\n}\n\nfunction enableOverflowHiddenParents (el) {\n if (overflowHiddenParents.map.has(el)) {\n overflowHiddenParents.map.get(el).forEach(parent => {\n setStyle(parent, overflowHiddenParents.style.get(parent))\n })\n }\n}\n","import { docElm, body } from './util/_dom'\nimport { bindAll } from './util/_helpers'\n\nconst PRESS_DELAY = 200\nconst MULTITOUCH_SCALE_FACTOR = 2\n\nexport default class EventHandler {\n\n constructor (instance) {\n bindAll(this, instance)\n }\n\n click (e) {\n e.preventDefault()\n\n if (this.shown) {\n if (this.released) this.close()\n else this.release()\n } else {\n this.open(e.currentTarget)\n }\n }\n\n scroll () {\n const scrollTop = window.pageYOffset ||\n (docElm || body.parentNode || body).scrollTop\n\n if (this.lastScrollPosition === null) {\n this.lastScrollPosition = scrollTop\n }\n\n const deltaY = this.lastScrollPosition - scrollTop\n\n if (Math.abs(deltaY) >= this.options.scrollThreshold) {\n this.lastScrollPosition = null\n this.close()\n }\n }\n\n keydown (e) {\n if (isEscape(e)) {\n if (this.released) this.close()\n else this.release(() => this.close())\n }\n }\n\n mousedown (e) {\n if (isNotLeftButton(e)) return\n e.preventDefault()\n\n this.pressTimer = setTimeout(() => {\n this.grab(e.clientX, e.clientY)\n }, PRESS_DELAY)\n }\n\n mousemove (e) {\n if (this.released) return\n this.move(e.clientX, e.clientY)\n }\n\n mouseup (e) {\n if (isNotLeftButton(e)) return\n clearTimeout(this.pressTimer)\n\n if (this.released) this.close()\n else this.release()\n }\n\n touchstart (e) {\n e.preventDefault()\n\n this.pressTimer = setTimeout(() => {\n processTouches(e.touches, this.options.scaleExtra,\n (x, y, scaleExtra) => {\n this.grab(x, y, scaleExtra)\n })\n }, PRESS_DELAY)\n }\n\n touchmove (e) {\n if (this.released) return\n\n processTouches(e.touches, this.options.scaleExtra,\n (x, y, scaleExtra) => {\n this.move(x, y, scaleExtra)\n })\n }\n\n touchend (e) {\n if (isTouching(e)) return\n clearTimeout(this.pressTimer)\n\n if (this.released) this.close()\n else this.release()\n }\n}\n\nfunction isNotLeftButton (event) {\n return event.button !== 0\n}\n\nfunction isEscape (event) {\n const code = event.key || event.code\n return code === 'Escape' || event.keyCode === 27\n}\n\nfunction isTouching (event) {\n return event.targetTouches.length > 0\n}\n\nfunction processTouches (touches, currScaleExtra, cb) {\n const total = touches.length\n const firstTouch = touches[0]\n const multitouch = total > 1\n\n let scaleExtra = currScaleExtra\n let i = touches.length\n let [xs, ys] = [0, 0]\n\n // keep track of the min and max of touch positions\n let min = { x: firstTouch.clientX, y: firstTouch.clientY }\n let max = { x: firstTouch.clientX, y: firstTouch.clientY }\n\n while (i--) {\n const t = touches[i]\n const [x, y] = [t.clientX, t.clientY]\n xs += x\n ys += y\n\n if (!multitouch) continue\n\n if (x < min.x) {\n min.x = x\n } else if (x > max.x) {\n max.x = x\n }\n\n if (y < min.y) {\n min.y = y\n } else if (y > max.y) {\n max.y = y\n }\n }\n\n if (multitouch) {\n // change scaleExtra dynamically\n const [distX, distY] = [max.x - min.x, max.y - min.y]\n\n if (distX > distY) {\n scaleExtra = (distX / window.innerWidth) * MULTITOUCH_SCALE_FACTOR\n } else {\n scaleExtra = (distY / window.innerHeight) * MULTITOUCH_SCALE_FACTOR\n }\n }\n\n cb(xs / total, ys / total, scaleExtra)\n}\n","import { cursor, setStyle, getWindowCenter, overflowHiddenParents } from './util/_helpers'\nimport { transformCssProp } from './util/_trans'\nimport { half } from './util/_math'\n\nexport default class Target {\n\n constructor (el, instance) {\n this.el = el\n this.instance = instance\n this.translate = null\n this.scale = null\n this.srcThumbnail = this.el.getAttribute('src')\n this.style = {\n open: null,\n close: null\n }\n }\n\n zoomIn () {\n const options = this.instance.options\n const rect = this.el.getBoundingClientRect()\n\n // Remove overflow:hidden from target's parent nodes if any. It prevents\n // parent nodes from hiding the target after zooming in\n overflowHiddenParents.disable(this.el)\n\n this.translate = calculateTranslate(rect)\n this.scale = calculateScale(rect, options.scaleBase, options.customSize)\n\n // force layout update\n this.el.offsetWidth\n\n this.style.open = {\n position: 'relative',\n zIndex: 999,\n cursor: options.enableGrab\n ? cursor.grab\n : cursor.zoomOut,\n transition: `${transformCssProp}\n ${options.transitionDuration}s\n ${options.transitionTimingFunction}`,\n transform: `translate(${this.translate.x}px, ${this.translate.y}px)\n scale(${this.scale.x},${this.scale.y})`,\n width: `${rect.width}px`,\n height: `${rect.height}px`\n }\n\n // trigger transition\n this.style.close = setStyle(this.el, this.style.open, true)\n }\n\n zoomOut () {\n // Restore overflow:hidden to target's parent nodes if any\n overflowHiddenParents.enable(this.el)\n\n // force layout update\n this.el.offsetWidth\n\n setStyle(this.el, { transform: 'none' })\n }\n\n grab (x, y, scaleExtra) {\n const windowCenter = getWindowCenter()\n const [dx, dy] = [windowCenter.x - x, windowCenter.y - y]\n\n setStyle(this.el, {\n cursor: cursor.move,\n transform: `translate(\n ${this.translate.x + dx}px, ${this.translate.y + dy}px)\n scale(${this.scale.x + scaleExtra},${this.scale.y + scaleExtra})`\n })\n }\n\n move (x, y, scaleExtra) {\n const windowCenter = getWindowCenter()\n const [dx, dy] = [windowCenter.x - x, windowCenter.y - y]\n\n setStyle(this.el, {\n transition: transformCssProp,\n transform: `translate(\n ${this.translate.x + dx}px, ${this.translate.y + dy}px)\n scale(${this.scale.x + scaleExtra},${this.scale.y + scaleExtra})`\n })\n }\n\n restoreCloseStyle () {\n setStyle(this.el, this.style.close)\n }\n\n restoreOpenStyle () {\n setStyle(this.el, this.style.open)\n }\n\n upgradeSource (srcOriginal) {\n if (!srcOriginal) return\n\n const parentNode = this.el.parentNode\n const temp = this.el.cloneNode(false)\n\n // force compute the hi-res image in DOM to prevent\n // image flickering while updating src\n temp.setAttribute('src', srcOriginal)\n temp.style.position = 'fixed'\n temp.style.visibility = 'hidden'\n parentNode.appendChild(temp)\n\n setTimeout(() => {\n this.el.setAttribute('src', srcOriginal)\n parentNode.removeChild(temp)\n }, 100)\n }\n\n downgradeSource (srcOriginal) {\n if (!srcOriginal) return\n\n this.el.setAttribute('src', this.srcThumbnail)\n }\n}\n\nfunction calculateTranslate (rect) {\n const windowCenter = getWindowCenter()\n const targetCenter = {\n x: rect.left + half(rect.width),\n y: rect.top + half(rect.height)\n }\n\n // The vector to translate image to the window center\n return {\n x: windowCenter.x - targetCenter.x,\n y: windowCenter.y - targetCenter.y\n }\n}\n\nfunction calculateScale (rect, scaleBase, customSize) {\n if (customSize) {\n return {\n x: customSize.width / rect.width,\n y: customSize.height / rect.height\n }\n } else {\n const targetHalfWidth = half(rect.width)\n const targetHalfHeight = half(rect.height)\n const windowCenter = getWindowCenter()\n\n // The distance between target edge and window edge\n const targetEdgeToWindowEdge = {\n x: windowCenter.x - targetHalfWidth,\n y: windowCenter.y - targetHalfHeight\n }\n\n const scaleHorizontally = targetEdgeToWindowEdge.x / targetHalfWidth\n const scaleVertically = targetEdgeToWindowEdge.y / targetHalfHeight\n\n // The additional scale is based on the smaller value of\n // scaling horizontally and scaling vertically\n const scale = scaleBase + Math.min(scaleHorizontally, scaleVertically)\n\n return {\n x: scale,\n y: scale\n }\n }\n}\n","import { setStyle } from './util/_helpers'\n\nexport default class Overlay {\n\n constructor (el, instance) {\n this.el = el\n this.instance = instance\n this.parent = document.body\n }\n\n init (options) {\n setStyle(this.el, {\n zIndex: 998,\n backgroundColor: options.bgColor,\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n opacity: 0,\n transition: `opacity\n ${options.transitionDuration}s\n ${options.transitionTimingFunction}`\n })\n\n this.el.addEventListener('click', () => this.instance.close())\n }\n\n updateStyle (options) {\n setStyle(this.el, {\n backgroundColor: options.bgColor,\n transition: `opacity\n ${options.transitionDuration}s\n ${options.transitionTimingFunction}`\n })\n }\n\n insert () {\n this.parent.appendChild(this.el)\n }\n\n remove () {\n this.parent.removeChild(this.el)\n }\n\n show () {\n setTimeout(() => this.el.style.opacity = this.instance.options.bgOpacity, 30)\n }\n\n hide () {\n this.el.style.opacity = 0\n }\n}\n","/**\n * A list of options.\n *\n * @type {Object}\n * @example\n * // Default options\n * var options = {\n * defaultZoomable: 'img[data-action=\"zoom\"]',\n * enableGrab: true,\n * preloadImage: true,\n * transitionDuration: 0.4,\n * transitionTimingFunction: 'cubic-bezier(0.4, 0, 0, 1)',\n * bgColor: 'rgb(255, 255, 255)',\n * bgOpacity: 1,\n * scaleBase: 1.0,\n * scaleExtra: 0.5,\n * scrollThreshold: 40,\n * customSize: null,\n * onOpen: null,\n * onClose: null,\n * onRelease: null,\n * onBeforeOpen: null,\n * onBeforeClose: null,\n * onBeforeGrab: null,\n * onBeforeMove: null,\n * onBeforeRelease: null\n * }\n */\nconst OPTIONS = {\n /**\n * Zoomable elements by default. It can be a css selector or an element.\n * @type {string|Element}\n */\n defaultZoomable: 'img[data-action=\"zoom\"]',\n\n /**\n * To be able to grab and drag the image for extra zoom-in.\n * @type {boolean}\n */\n enableGrab: true,\n\n /**\n * Preload images with attribute \"data-original\".\n * @type {boolean}\n */\n preloadImage: true,\n\n /**\n * Transition duration in seconds.\n * @type {number}\n */\n transitionDuration: 0.4,\n\n /**\n * Transition timing function.\n * @type {string}\n */\n transitionTimingFunction: 'cubic-bezier(0.4, 0, 0, 1)',\n\n /**\n * Overlay background color.\n * @type {string}\n */\n bgColor: 'rgb(255, 255, 255)',\n\n /**\n * Overlay background opacity.\n * @type {number}\n */\n bgOpacity: 1,\n\n /**\n * The base scale factor for zooming. By default scale to fit the window.\n * @type {number}\n */\n scaleBase: 1.0,\n\n /**\n * The extra scale factor when grabbing the image.\n * @type {number}\n */\n scaleExtra: 0.5,\n\n /**\n * How much scrolling it takes before closing out.\n * @type {number}\n */\n scrollThreshold: 40,\n\n /**\n * Scale (zoom in) to given width and height. Ignore scaleBase if set.\n * @type {Object}\n * @example\n * customSize: { width: 800, height: 400 }\n */\n customSize: null,\n\n /**\n * A callback function that will be called when a target is opened and\n * transition has ended. It will get the target element as the argument.\n * @type {Function}\n */\n onOpen: null,\n\n /**\n * Same as above, except fired when closed.\n * @type {Function}\n */\n onClose: null,\n\n /**\n * Same as above, except fired when released.\n * @type {Function}\n */\n onRelease: null,\n\n /**\n * A callback function that will be called before open.\n * @type {Function}\n */\n onBeforeOpen: null,\n\n /**\n * A callback function that will be called before close.\n * @type {Function}\n */\n onBeforeClose: null,\n\n /**\n * A callback function that will be called before grab.\n * @type {Function}\n */\n onBeforeGrab: null,\n\n /**\n * A callback function that will be called before move.\n * @type {Function}\n */\n onBeforeMove: null,\n\n /**\n * A callback function that will be called before release.\n * @type {Function}\n */\n onBeforeRelease: null\n}\n\nexport default OPTIONS\n","import { isNotImage, loadImage, checkOriginalImage } from './util/_image'\nimport { cursor, toggleGrabListeners } from './util/_helpers'\nimport { transEndEvent } from './util/_trans'\nimport { isString } from './util/_dom'\n\nimport EventHandler from './EventHandler'\nimport Overlay from './Overlay'\nimport Target from './Target'\n\nimport DEFAULT_OPTIONS from './_options'\n\n/**\n * Zooming instance.\n */\nexport default class Zooming {\n\n /**\n * @param {Object} [options] Update default options if provided.\n */\n constructor (options) {\n\n // elements\n this.target = null\n this.overlay = new Overlay(document.createElement('div'), this)\n this.eventHandler = new EventHandler(this)\n this.body = document.body\n\n // state\n this.shown = false // target is open\n this.lock = false // target is in transform\n this.released = true // mouse/finger is not pressing down\n this.lastScrollPosition = null\n this.pressTimer = null\n\n // init\n this.options = Object.assign({}, DEFAULT_OPTIONS)\n this.config(options)\n this.listen(this.options.defaultZoomable)\n this.overlay.init(this.options)\n }\n\n /**\n * Make element(s) zoomable.\n * @param {string|Element} el A css selector or an Element.\n * @return {this}\n */\n listen (el) {\n if (isString(el)) {\n let els = document.querySelectorAll(el), i = els.length\n\n while (i--) {\n this.listen(els[i])\n }\n\n return this\n }\n\n if (isNotImage(el)) return\n\n el.style.cursor = cursor.zoomIn\n el.addEventListener('click', this.eventHandler.click, { passive: false })\n\n if (this.options.preloadImage) {\n checkOriginalImage(el, loadImage)\n }\n\n return this\n }\n\n /**\n * Update options.\n * @param {Object} options An Object that contains this.options.\n * @return {this}\n */\n config (options) {\n if (!options) return this.options\n\n Object.assign(this.options, options)\n this.overlay.updateStyle(this.options)\n\n return this\n }\n\n /**\n * Open (zoom in) the Element.\n * @param {Element} el The Element to open.\n * @param {Function} [cb=this.options.onOpen] A callback function that will\n * be called when a target is opened and transition has ended. It will get\n * the target element as the argument.\n * @return {this}\n */\n open (el, cb = this.options.onOpen) {\n if (this.shown || this.lock) return\n\n const target = isString(el)\n ? document.querySelector(el)\n : el\n\n if (isNotImage(target)) return\n\n // onBeforeOpen event\n if (this.options.onBeforeOpen) this.options.onBeforeOpen(target)\n\n if (!this.options.preloadImage) {\n checkOriginalImage(target, loadImage)\n }\n\n this.target = new Target(target, this)\n\n this.shown = true\n this.lock = true\n\n this.target.zoomIn()\n this.overlay.insert()\n this.overlay.show()\n\n document.addEventListener('scroll', this.eventHandler.scroll)\n document.addEventListener('keydown', this.eventHandler.keydown)\n\n const onEnd = () => {\n target.removeEventListener(transEndEvent, onEnd)\n\n this.lock = false\n\n checkOriginalImage(target, srcOriginal => this.target.upgradeSource(srcOriginal))\n\n if (this.options.enableGrab) {\n toggleGrabListeners(document, this.eventHandler, true)\n }\n\n if (cb) cb(target)\n }\n\n target.addEventListener(transEndEvent, onEnd)\n\n return this\n }\n\n /**\n * Close (zoom out) the Element currently opened.\n * @param {Function} [cb=this.options.onClose] A callback function that will\n * be called when a target is closed and transition has ended. It will get\n * the target element as the argument.\n * @return {this}\n */\n close (cb = this.options.onClose) {\n if (!this.shown || this.lock) return\n\n const target = this.target.el\n\n // onBeforeClose event\n if (this.options.onBeforeClose) this.options.onBeforeClose(target)\n\n this.lock = true\n\n this.body.style.cursor = cursor.default\n this.overlay.hide()\n this.target.zoomOut()\n\n document.removeEventListener('scroll', this.eventHandler.scroll)\n document.removeEventListener('keydown', this.eventHandler.keydown)\n\n const onEnd = () => {\n target.removeEventListener(transEndEvent, onEnd)\n\n this.shown = false\n this.lock = false\n\n checkOriginalImage(target, srcOriginal => this.target.downgradeSource(srcOriginal))\n\n if (this.options.enableGrab) {\n toggleGrabListeners(document, this.eventHandler, false)\n }\n\n this.target.restoreCloseStyle()\n this.overlay.remove()\n\n if (cb) cb(target)\n }\n\n target.addEventListener(transEndEvent, onEnd)\n\n return this\n }\n\n /**\n * Grab the Element currently opened given a position and apply extra zoom-in.\n * @param {number} x The X-axis of where the press happened.\n * @param {number} y The Y-axis of where the press happened.\n * @param {number} scaleExtra Extra zoom-in to apply.\n * @param {Function} [cb=this.options.scaleExtra] A callback function that\n * will be called when a target is grabbed and transition has ended. It\n * will get the target element as the argument.\n * @return {this}\n */\n grab (x, y, scaleExtra = this.options.scaleExtra, cb) {\n if (!this.shown || this.lock) return\n\n const target = this.target.el\n\n // onBeforeGrab event\n if (this.options.onBeforeGrab) this.options.onBeforeGrab(target)\n\n this.released = false\n this.target.grab(x, y, scaleExtra)\n\n const onEnd = () => {\n target.removeEventListener(transEndEvent, onEnd)\n if (cb) cb(target)\n }\n\n target.addEventListener(transEndEvent, onEnd)\n }\n\n /**\n * Move the Element currently grabbed given a position and apply extra zoom-in.\n * @param {number} x The X-axis of where the press happened.\n * @param {number} y The Y-axis of where the press happened.\n * @param {number} scaleExtra Extra zoom-in to apply.\n * @param {Function} [cb=this.options.scaleExtra] A callback function that\n * will be called when a target is moved and transition has ended. It will\n * get the target element as the argument.\n * @return {this}\n */\n move (x, y, scaleExtra = this.options.scaleExtra, cb) {\n if (!this.shown || this.lock) return\n\n const target = this.target.el\n\n // onBeforeMove event\n if (this.options.onBeforeMove) this.options.onBeforeMove(target)\n\n this.released = false\n\n this.target.move(x, y, scaleExtra)\n this.body.style.cursor = cursor.move\n\n const onEnd = () => {\n target.removeEventListener(transEndEvent, onEnd)\n if (cb) cb(target)\n }\n\n target.addEventListener(transEndEvent, onEnd)\n }\n\n /**\n * Release the Element currently grabbed.\n * @param {Function} [cb=this.options.onRelease] A callback function that\n * will be called when a target is released and transition has ended. It\n * will get the target element as the argument.\n * @return {this}\n */\n release (cb = this.options.onRelease) {\n if (!this.shown || this.lock) return\n\n const target = this.target.el\n\n // onBeforeRelease event\n if (this.options.onBeforeRelease) this.options.onBeforeRelease(target)\n\n this.lock = true\n\n this.target.restoreOpenStyle()\n this.body.style.cursor = cursor.default\n\n const onEnd = () => {\n target.removeEventListener(transEndEvent, onEnd)\n\n this.lock = false\n this.released = true\n\n if (cb) cb(target)\n }\n\n target.addEventListener(transEndEvent, onEnd)\n\n return this\n }\n}\n","import Zooming from './Zooming'\n\ndocument.addEventListener('DOMContentLoaded', () => {\n new Zooming()\n})\n\nexport default Zooming\n"],"names":["checkType","typeName","el","checkTag","tagName","getParents","match","parents","document","parentNode","push","isNotImage","loadImage","src","cb","img","Image","onload","checkOriginalImage","srcOriginal","hasAttribute","getAttribute","isLink","checkTrans","styles","transitionProp","trans","transformProp","value","transition","transform","sniffTransition","ret","tform","end","some","undefined","style","prop","transEndEvent","transformCssProp","replace","divide","denominator","numerator","toggleListener","type","handler","add","addEventListener","passive","removeEventListener","getWindowCenter","windowWidth","Math","min","docElm","clientWidth","window","innerWidth","windowHeight","clientHeight","innerHeight","half","toggleGrabListeners","forEach","setStyle","remember","s","original","key","bindAll","_this","that","methods","Object","getOwnPropertyNames","getPrototypeOf","method","bind","isOverflowHidden","getComputedStyle","overflow","getOverflowHiddenParents","overflowHiddenParents","map","has","get","set","disableOverflowHiddenParents","parent","enableOverflowHiddenParents","isNotLeftButton","event","button","isEscape","code","keyCode","isTouching","targetTouches","length","processTouches","touches","currScaleExtra","total","firstTouch","multitouch","scaleExtra","i","xs","ys","x","clientX","y","clientY","max","t","distX","distY","MULTITOUCH_SCALE_FACTOR","calculateTranslate","rect","windowCenter","targetCenter","left","width","top","height","calculateScale","scaleBase","customSize","targetHalfWidth","targetHalfHeight","targetEdgeToWindowEdge","scaleHorizontally","scaleVertically","scale","body","documentElement","isString","webkitPrefix","createElement","cursor","Map","PRESS_DELAY","EventHandler","instance","this","e","preventDefault","shown","released","close","release","open","currentTarget","scrollTop","pageYOffset","lastScrollPosition","deltaY","abs","options","scrollThreshold","pressTimer","setTimeout","grab","move","_this3","Overlay","bgColor","transitionDuration","transitionTimingFunction","appendChild","removeChild","_this2","opacity","bgOpacity","Target","translate","srcThumbnail","getBoundingClientRect","disable","offsetWidth","enableGrab","zoomOut","enable","dx","dy","temp","cloneNode","setAttribute","position","visibility","OPTIONS","Zooming","target","overlay","eventHandler","lock","babelHelpers.extends","DEFAULT_OPTIONS","config","listen","defaultZoomable","init","els","querySelectorAll","zoomIn","click","preloadImage","updateStyle","onOpen","querySelector","onBeforeOpen","insert","show","scroll","keydown","onEnd","upgradeSource","onClose","onBeforeClose","default","hide","downgradeSource","restoreCloseStyle","remove","onBeforeGrab","onBeforeMove","onRelease","onBeforeRelease","restoreOpenStyle"],"mappings":"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"}