{"version":3,"file":"viewport.js","sources":["../src/input-manager.js","../src/plugin-manager.js","../src/plugins/plugin.js","../src/plugins/drag.js","../src/plugins/pinch.js","../src/plugins/clamp.js","../src/plugins/clamp-zoom.js","../src/plugins/decelerate.js","../node_modules/penner/penner.js","../src/ease.js","../src/plugins/bounce.js","../src/plugins/snap.js","../src/plugins/snap-zoom.js","../src/plugins/follow.js","../src/plugins/wheel.js","../src/plugins/mouse-edges.js","../src/plugins/animate.js","../src/viewport.js"],"sourcesContent":["import * as PIXI from 'pixi.js'\r\n\r\n/**\r\n * @typedef ViewportTouch\r\n * @property {number} id\r\n * @property {PIXI.Point} last\r\n*/\r\n\r\n/**\r\n * handles all input for Viewport\r\n * @private\r\n */\r\nexport class InputManager {\r\n constructor(viewport) {\r\n this.viewport = viewport\r\n\r\n /**\r\n * list of active touches on viewport\r\n * @type {ViewportTouch[]}\r\n */\r\n this.touches = []\r\n this.addListeners()\r\n }\r\n\r\n /**\r\n * add input listeners\r\n * @private\r\n */\r\n addListeners() {\r\n this.viewport.interactive = true\r\n if (!this.viewport.forceHitArea) {\r\n this.viewport.hitArea = new PIXI.Rectangle(0, 0, this.viewport.worldWidth, this.viewport.worldHeight)\r\n }\r\n this.viewport.on('pointerdown', this.down, this)\r\n this.viewport.on('pointermove', this.move, this)\r\n this.viewport.on('pointerup', this.up, this)\r\n this.viewport.on('pointerupoutside', this.up, this)\r\n this.viewport.on('pointercancel', this.up, this)\r\n this.viewport.on('pointerout', this.up, this)\r\n this.wheelFunction = (e) => this.handleWheel(e)\r\n this.viewport.options.divWheel.addEventListener('wheel', this.wheelFunction, { passive: this.viewport.options.passiveWheel })\r\n this.isMouseDown = false\r\n }\r\n\r\n /**\r\n * removes all event listeners from viewport\r\n * (useful for cleanup of wheel when removing viewport)\r\n */\r\n destroy() {\r\n this.viewport.options.divWheel.removeEventListener('wheel', this.wheelFunction)\r\n }\r\n\r\n /**\r\n * handle down events for viewport\r\n * @param {PIXI.InteractionEvent} event\r\n */\r\n down(event) {\r\n if (this.viewport.pause || !this.viewport.worldVisible) {\r\n return\r\n }\r\n if (event.data.pointerType === 'mouse') {\r\n this.isMouseDown = true\r\n }\r\n else if (!this.get(event.data.pointerId)) {\r\n this.touches.push({ id: event.data.pointerId, last: null })\r\n }\r\n if (this.count() === 1) {\r\n this.last = event.data.global.clone()\r\n\r\n // clicked event does not fire if viewport is decelerating or bouncing\r\n const decelerate = this.viewport.plugins.get('decelerate', true)\r\n const bounce = this.viewport.plugins.get('bounce', true)\r\n if ((!decelerate || !decelerate.isActive()) && (!bounce || !bounce.isActive())) {\r\n this.clickedAvailable = true\r\n }\r\n else {\r\n this.clickedAvailable = false\r\n }\r\n }\r\n else {\r\n this.clickedAvailable = false\r\n }\r\n\r\n const stop = this.viewport.plugins.down(event)\r\n if (stop && this.viewport.options.stopPropagation) {\r\n event.stopPropagation()\r\n }\r\n }\r\n\r\n /**\r\n * clears all pointer events\r\n */\r\n clear() {\r\n this.isMouseDown = false\r\n this.touches = []\r\n this.last = null\r\n }\r\n\r\n /**\r\n * @param {number} change\r\n * @returns whether change exceeds threshold\r\n */\r\n checkThreshold(change) {\r\n if (Math.abs(change) >= this.viewport.threshold) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n /**\r\n * handle move events for viewport\r\n * @param {PIXI.InteractionEvent} event\r\n */\r\n move(event) {\r\n if (this.viewport.pause || !this.viewport.worldVisible) {\r\n return\r\n }\r\n\r\n const stop = this.viewport.plugins.move(event)\r\n\r\n if (this.clickedAvailable) {\r\n const distX = event.data.global.x - this.last.x\r\n const distY = event.data.global.y - this.last.y\r\n if (this.checkThreshold(distX) || this.checkThreshold(distY)) {\r\n this.clickedAvailable = false\r\n }\r\n }\r\n\r\n if (stop && this.viewport.options.stopPropagation) {\r\n event.stopPropagation()\r\n }\r\n }\r\n\r\n /**\r\n * handle up events for viewport\r\n * @param {PIXI.InteractionEvent} event\r\n */\r\n up(event) {\r\n if (this.viewport.pause || !this.viewport.worldVisible) {\r\n return\r\n }\r\n\r\n if (event.data.pointerType === 'mouse') {\r\n this.isMouseDown = false\r\n }\r\n\r\n if (event.data.pointerType !== 'mouse') {\r\n this.remove(event.data.pointerId)\r\n }\r\n\r\n const stop = this.viewport.plugins.up(event)\r\n\r\n if (this.clickedAvailable && this.count() === 0) {\r\n this.viewport.emit('clicked', { event: event, screen: this.last, world: this.viewport.toWorld(this.last), viewport: this })\r\n this.clickedAvailable = false\r\n }\r\n\r\n if (stop && this.viewport.options.stopPropagation) {\r\n event.stopPropagation()\r\n }\r\n }\r\n\r\n /**\r\n * gets pointer position if this.interaction is set\r\n * @param {WheelEvent} event\r\n * @return {PIXI.Point}\r\n */\r\n getPointerPosition(event) {\r\n let point = new PIXI.Point()\r\n if (this.viewport.options.interaction) {\r\n this.viewport.options.interaction.mapPositionToPoint(point, event.clientX, event.clientY)\r\n }\r\n else {\r\n point.x = event.clientX\r\n point.y = event.clientY\r\n }\r\n return point\r\n }\r\n\r\n /**\r\n * handle wheel events\r\n * @param {WheelEvent} event\r\n */\r\n handleWheel(event) {\r\n if (this.viewport.pause || !this.viewport.worldVisible) {\r\n return\r\n }\r\n\r\n // only handle wheel events where the mouse is over the viewport\r\n const point = this.viewport.toLocal(this.getPointerPosition(event))\r\n if (this.viewport.left <= point.x && point.x <= this.viewport.right && this.viewport.top <= point.y && point.y <= this.viewport.bottom) {\r\n const stop = this.viewport.plugins.wheel(event)\r\n if (stop && !this.viewport.options.passiveWheel) {\r\n event.preventDefault()\r\n }\r\n }\r\n }\r\n\r\n pause() {\r\n this.touches = []\r\n this.isMouseDown = false\r\n }\r\n\r\n /**\r\n * get touch by id\r\n * @param {number} id\r\n * @return {ViewportTouch}\r\n */\r\n get(id) {\r\n for (let touch of this.touches) {\r\n if (touch.id === id) {\r\n return touch\r\n }\r\n }\r\n return null\r\n }\r\n\r\n /**\r\n * remove touch by number\r\n * @param {number} id\r\n */\r\n remove(id) {\r\n for (let i = 0; i < this.touches.length; i++) {\r\n if (this.touches[i].id === id) {\r\n this.touches.splice(i, 1)\r\n return\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @returns {number} count of mouse/touch pointers that are down on the viewport\r\n */\r\n count() {\r\n return (this.isMouseDown ? 1 : 0) + this.touches.length\r\n }\r\n}\r\n","const PLUGIN_ORDER = ['drag', 'pinch', 'wheel', 'follow', 'mouse-edges', 'decelerate', 'aniamte', 'bounce', 'snap-zoom', 'clamp-zoom', 'snap', 'clamp']\r\n\r\n/**\r\n * Use this to access current plugins or add user-defined plugins\r\n */\r\nexport class PluginManager {\r\n /**\r\n * instantiated by Viewport\r\n * @param {Viewport} viewport\r\n */\r\n constructor(viewport) {\r\n this.viewport = viewport\r\n this.list = []\r\n this.plugins = {}\r\n }\r\n\r\n /**\r\n * Inserts a named plugin or a user plugin into the viewport\r\n * default plugin order: 'drag', 'pinch', 'wheel', 'follow', 'mouse-edges', 'decelerate', 'bounce', 'snap-zoom', 'clamp-zoom', 'snap', 'clamp'\r\n * @param {string} name of plugin\r\n * @param {Plugin} plugin - instantiated Plugin class\r\n * @param {number} index to insert userPlugin (otherwise inserts it at the end)\r\n */\r\n add(name, plugin, index = PLUGIN_ORDER.length) {\r\n this.plugins[name] = plugin\r\n const current = PLUGIN_ORDER.indexOf(name)\r\n if (current !== -1) {\r\n PLUGIN_ORDER.splice(current, 1)\r\n }\r\n PLUGIN_ORDER.splice(index, 0, name)\r\n this.sort()\r\n }\r\n\r\n /**\r\n * get plugin\r\n * @param {string} name of plugin\r\n * @param {boolean} [ignorePaused] return null if plugin is paused\r\n * @return {Plugin}\r\n */\r\n get(name, ignorePaused) {\r\n if (ignorePaused) {\r\n if (typeof this.plugins[name] !== 'undefined' && this.plugins[name].paused) {\r\n return null\r\n }\r\n }\r\n return this.plugins[name]\r\n }\r\n\r\n /**\r\n * update all active plugins\r\n * @ignore\r\n * @param {number} elapsed type in milliseconds since last update\r\n */\r\n update(elapsed) {\r\n for (let plugin of this.list) {\r\n plugin.update(elapsed)\r\n }\r\n }\r\n\r\n /**\r\n * resize all active plugins\r\n * @ignore\r\n */\r\n resize() {\r\n for (let plugin of this.list) {\r\n plugin.resize()\r\n }\r\n }\r\n\r\n /**\r\n * clamps and resets bounce and decelerate (as needed) after manually moving viewport\r\n */\r\n reset() {\r\n for (let plugin of this.list) {\r\n plugin.reset()\r\n }\r\n }\r\n\r\n /**\r\n * removes installed plugin\r\n * @param {string} name of plugin (e.g., 'drag', 'pinch')\r\n */\r\n remove(name) {\r\n if (this.plugins[name]) {\r\n this.plugins[name] = null\r\n this.viewport.emit(name + '-remove')\r\n this.sort()\r\n }\r\n }\r\n\r\n /**\r\n * pause plugin\r\n * @param {string} name of plugin (e.g., 'drag', 'pinch')\r\n */\r\n pause(name) {\r\n if (this.plugins[name]) {\r\n this.plugins[name].pause()\r\n }\r\n }\r\n\r\n /**\r\n * resume plugin\r\n * @param {string} name of plugin (e.g., 'drag', 'pinch')\r\n */\r\n resume(name) {\r\n if (this.plugins[name]) {\r\n this.plugins[name].resume()\r\n }\r\n }\r\n\r\n /**\r\n * sort plugins according to PLUGIN_ORDER\r\n * @ignore\r\n */\r\n sort() {\r\n this.list = []\r\n for (let plugin of PLUGIN_ORDER) {\r\n if (this.plugins[plugin]) {\r\n this.list.push(this.plugins[plugin])\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * handle down for all plugins\r\n * @ignore\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n down(event) {\r\n let stop = false\r\n for (let plugin of this.list) {\r\n if (plugin.down(event)) {\r\n stop = true\r\n }\r\n }\r\n return stop\r\n }\r\n\r\n /**\r\n * handle move for all plugins\r\n * @ignore\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n move(event) {\r\n let stop = false\r\n for (let plugin of this.viewport.plugins.list) {\r\n if (plugin.move(event)) {\r\n stop = true\r\n }\r\n }\r\n return stop\r\n }\r\n\r\n /**\r\n * handle up for all plugins\r\n * @ignore\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n up(event) {\r\n let stop = false\r\n for (let plugin of this.list) {\r\n if (plugin.up(event)) {\r\n stop = true\r\n }\r\n }\r\n return stop\r\n }\r\n\r\n /**\r\n * handle wheel event for all plugins\r\n * @ignore\r\n * @param {WheelEvent} event\r\n * @returns {boolean}\r\n */\r\n wheel(e) {\r\n let result = false\r\n for (let plugin of this.list) {\r\n if (plugin.wheel(e)) {\r\n result = true\r\n }\r\n }\r\n return result\r\n }\r\n}\r\n","/**\r\n * derive this class to create user-defined plugins\r\n */\r\nexport class Plugin\r\n{\r\n /**\r\n * @param {Viewport} parent\r\n */\r\n constructor(parent)\r\n {\r\n this.parent = parent\r\n this.paused = false\r\n }\r\n\r\n /** called when plugin is removed */\r\n destroy() {}\r\n\r\n /**\r\n * handler for pointerdown PIXI event\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n down()\r\n {\r\n return false\r\n }\r\n\r\n /**\r\n * handler for pointermove PIXI event\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n move()\r\n {\r\n return false\r\n }\r\n\r\n /**\r\n * handler for pointerup PIXI event\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n up()\r\n {\r\n return false\r\n }\r\n\r\n /**\r\n * handler for wheel event on div\r\n * @param {WheelEvent} event\r\n * @returns {boolean}\r\n */\r\n wheel()\r\n {\r\n return false\r\n }\r\n\r\n /**\r\n * called on each tick\r\n * @param {number} elapsed time in millisecond since last update\r\n */\r\n update() { }\r\n\r\n /** called when the viewport is resized */\r\n resize() { }\r\n\r\n /** called when the viewport is manually moved */\r\n reset() { }\r\n\r\n /** pause the plugin */\r\n pause()\r\n {\r\n this.paused = true\r\n }\r\n\r\n /** un-pause the plugin */\r\n resume()\r\n {\r\n this.paused = false\r\n }\r\n}\r\n","import * as PIXI from 'pixi.js'\r\n\r\nimport { Plugin } from './plugin'\r\n\r\n/**\r\n * @typedef {object} LastDrag\r\n * @property {number} x\r\n * @property {number} y\r\n * @property {PIXI.Point} parent\r\n */\r\n\r\n/**\r\n * @typedef DragOptions\r\n * @property {string} [direction=all] direction to drag\r\n * @property {boolean} [pressDrag=true] whether click to drag is active\r\n * @property {boolean} [wheel=true] use wheel to scroll in direction (unless wheel plugin is active)\r\n * @property {number} [wheelScroll=1] number of pixels to scroll with each wheel spin\r\n * @property {boolean} [reverse] reverse the direction of the wheel scroll\r\n * @property {(boolean|string)} [clampWheel=false] clamp wheel(to avoid weird bounce with mouse wheel)\r\n * @property {string} [underflow=center] where to place world if too small for screen\r\n * @property {number} [factor=1] factor to multiply drag to increase the speed of movement\r\n * @property {string} [mouseButtons=all] changes which mouse buttons trigger drag, use: 'all', 'left', right' 'middle', or some combination, like, 'middle-right'; you may want to set viewport.options.disableOnContextMenu if you want to use right-click dragging\r\n * @property {string[]} [keyToPress=null] array containing {@link key|https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code} codes of keys that can be pressed for the drag to be triggered, e.g.: ['ShiftLeft', 'ShiftRight'}.\r\n * @property {boolean} [ignoreKeyToPressOnTouch=false] ignore keyToPress for touch events\r\n */\r\n\r\nconst dragOptions = {\r\n direction: 'all',\r\n pressDrag: true,\r\n wheel: true,\r\n wheelScroll: 1,\r\n reverse: false,\r\n clampWheel: false,\r\n underflow: 'center',\r\n factor: 1,\r\n mouseButtons: 'all',\r\n keyToPress: null,\r\n ignoreKeyToPressOnTouch: false\r\n}\r\n\r\n/**\r\n * @private\r\n */\r\nexport class Drag extends Plugin {\r\n /**\r\n * @param {Viewport} parent\r\n * @param {DragOptions} options\r\n */\r\n constructor(parent, options = {}) {\r\n super(parent)\r\n this.options = Object.assign({}, dragOptions, options)\r\n this.moved = false\r\n this.reverse = this.options.reverse ? 1 : -1\r\n this.xDirection = !this.options.direction || this.options.direction === 'all' || this.options.direction === 'x'\r\n this.yDirection = !this.options.direction || this.options.direction === 'all' || this.options.direction === 'y'\r\n this.keyIsPressed = false\r\n\r\n this.parseUnderflow()\r\n this.mouseButtons(this.options.mouseButtons)\r\n if (this.options.keyToPress) {\r\n this.handleKeyPresses(this.options.keyToPress)\r\n }\r\n }\r\n\r\n /**\r\n * Handles keypress events and set the keyIsPressed boolean accordingly\r\n * @param {array} codes - key codes that can be used to trigger drag event\r\n */\r\n handleKeyPresses(codes) {\r\n parent.addEventListener(\"keydown\", e => {\r\n if (codes.includes(e.code))\r\n this.keyIsPressed = true\r\n })\r\n\r\n parent.addEventListener(\"keyup\", e => {\r\n if (codes.includes(e.code))\r\n this.keyIsPressed = false\r\n })\r\n }\r\n\r\n /**\r\n * initialize mousebuttons array\r\n * @param {string} buttons\r\n */\r\n mouseButtons(buttons) {\r\n if (!buttons || buttons === 'all') {\r\n this.mouse = [true, true, true]\r\n }\r\n else {\r\n this.mouse = [\r\n buttons.indexOf('left') === -1 ? false : true,\r\n buttons.indexOf('middle') === -1 ? false : true,\r\n buttons.indexOf('right') === -1 ? false : true\r\n ]\r\n }\r\n }\r\n\r\n parseUnderflow() {\r\n const clamp = this.options.underflow.toLowerCase()\r\n if (clamp === 'center') {\r\n this.underflowX = 0\r\n this.underflowY = 0\r\n }\r\n else {\r\n this.underflowX = (clamp.indexOf('left') !== -1) ? -1 : (clamp.indexOf('right') !== -1) ? 1 : 0\r\n this.underflowY = (clamp.indexOf('top') !== -1) ? -1 : (clamp.indexOf('bottom') !== -1) ? 1 : 0\r\n }\r\n }\r\n\r\n /**\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n checkButtons(event) {\r\n const isMouse = event.data.pointerType === 'mouse'\r\n const count = this.parent.input.count()\r\n if ((count === 1) || (count > 1 && !this.parent.plugins.get('pinch', true))) {\r\n if (!isMouse || this.mouse[event.data.button]) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n /**\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n checkKeyPress(event) {\r\n if (!this.options.keyToPress || this.keyIsPressed || (this.options.ignoreKeyToPressOnTouch && event.data.pointerType === 'touch'))\r\n return true\r\n\r\n return false\r\n }\r\n\r\n /**\r\n * @param {PIXI.InteractionEvent} event\r\n */\r\n down(event) {\r\n if (this.paused || !this.options.pressDrag) {\r\n return\r\n }\r\n if (this.checkButtons(event) && this.checkKeyPress(event)) {\r\n this.last = { x: event.data.global.x, y: event.data.global.y }\r\n this.current = event.data.pointerId\r\n return true\r\n }\r\n else {\r\n this.last = null\r\n }\r\n }\r\n\r\n get active() {\r\n return this.moved\r\n }\r\n\r\n /**\r\n * @param {PIXI.InteractionEvent} event\r\n */\r\n move(event) {\r\n if (this.paused || !this.options.pressDrag) {\r\n return\r\n }\r\n if (this.last && this.current === event.data.pointerId) {\r\n const x = event.data.global.x\r\n const y = event.data.global.y\r\n const count = this.parent.input.count()\r\n if (count === 1 || (count > 1 && !this.parent.plugins.get('pinch', true))) {\r\n const distX = x - this.last.x\r\n const distY = y - this.last.y\r\n if (this.moved || ((this.xDirection && this.parent.input.checkThreshold(distX)) || (this.yDirection && this.parent.input.checkThreshold(distY)))) {\r\n const newPoint = { x, y }\r\n if (this.xDirection) {\r\n this.parent.x += (newPoint.x - this.last.x) * this.options.factor\r\n }\r\n if (this.yDirection) {\r\n this.parent.y += (newPoint.y - this.last.y) * this.options.factor\r\n }\r\n this.last = newPoint\r\n if (!this.moved) {\r\n this.parent.emit('drag-start', { event: event, screen: new PIXI.Point(this.last.x, this.last.y), world: this.parent.toWorld(new PIXI.Point(this.last.x, this.last.y)), viewport: this.parent })\r\n }\r\n this.moved = true\r\n this.parent.emit('moved', { viewport: this.parent, type: 'drag' })\r\n return true\r\n }\r\n }\r\n else {\r\n this.moved = false\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n up(event) {\r\n if (this.paused) {\r\n return\r\n }\r\n const touches = this.parent.input.touches\r\n if (touches.length === 1) {\r\n const pointer = touches[0]\r\n if (pointer.last) {\r\n this.last = { x: pointer.last.x, y: pointer.last.y }\r\n this.current = pointer.id\r\n }\r\n this.moved = false\r\n return true\r\n }\r\n else if (this.last) {\r\n if (this.moved) {\r\n const screen = new PIXI.Point(this.last.x, this.last.y)\r\n this.parent.emit('drag-end', { event: event, screen, world: this.parent.toWorld(screen), viewport: this.parent })\r\n this.last = null\r\n this.moved = false\r\n return true\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {WheelEvent} event\r\n * @returns {boolean}\r\n */\r\n wheel(event) {\r\n if (this.paused) {\r\n return\r\n }\r\n\r\n if (this.options.wheel) {\r\n const wheel = this.parent.plugins.get('wheel', true)\r\n if (!wheel) {\r\n if (this.xDirection) {\r\n this.parent.x += event.deltaX * this.options.wheelScroll * this.reverse\r\n }\r\n if (this.yDirection) {\r\n this.parent.y += event.deltaY * this.options.wheelScroll * this.reverse\r\n }\r\n if (this.options.clampWheel) {\r\n this.clamp()\r\n }\r\n this.parent.emit('wheel-scroll', this.parent)\r\n this.parent.emit('moved', { viewport: this.parent, type: 'wheel' })\r\n if (!this.parent.options.passiveWheel) {\r\n event.preventDefault()\r\n }\r\n return true\r\n }\r\n }\r\n }\r\n\r\n resume() {\r\n this.last = null\r\n this.paused = false\r\n }\r\n\r\n clamp() {\r\n const decelerate = this.parent.plugins.get('decelerate', true) || {}\r\n if (this.options.clampWheel !== 'y') {\r\n if (this.parent.screenWorldWidth < this.parent.screenWidth) {\r\n switch (this.underflowX) {\r\n case -1:\r\n this.parent.x = 0\r\n break\r\n case 1:\r\n this.parent.x = (this.parent.screenWidth - this.parent.screenWorldWidth)\r\n break\r\n default:\r\n this.parent.x = (this.parent.screenWidth - this.parent.screenWorldWidth) / 2\r\n }\r\n }\r\n else {\r\n if (this.parent.left < 0) {\r\n this.parent.x = 0\r\n decelerate.x = 0\r\n }\r\n else if (this.parent.right > this.parent.worldWidth) {\r\n this.parent.x = -this.parent.worldWidth * this.parent.scale.x + this.parent.screenWidth\r\n decelerate.x = 0\r\n }\r\n }\r\n }\r\n if (this.options.clampWheel !== 'x') {\r\n if (this.parent.screenWorldHeight < this.parent.screenHeight) {\r\n switch (this.underflowY) {\r\n case -1:\r\n this.parent.y = 0\r\n break\r\n case 1:\r\n this.parent.y = (this.parent.screenHeight - this.parent.screenWorldHeight)\r\n break\r\n default:\r\n this.parent.y = (this.parent.screenHeight - this.parent.screenWorldHeight) / 2\r\n }\r\n }\r\n else {\r\n if (this.parent.top < 0) {\r\n this.parent.y = 0\r\n decelerate.y = 0\r\n }\r\n if (this.parent.bottom > this.parent.worldHeight) {\r\n this.parent.y = -this.parent.worldHeight * this.parent.scale.y + this.parent.screenHeight\r\n decelerate.y = 0\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Plugin } from './plugin'\r\n\r\n/**\r\n * @typedef {object} PinchOptions\r\n * @property {boolean} [noDrag] disable two-finger dragging\r\n * @property {number} [percent=1] percent to modify pinch speed\r\n * @property {number} [factor=1] factor to multiply two-finger drag to increase the speed of movement\r\n * @property {PIXI.Point} [center] place this point at center during zoom instead of center of two fingers\r\n */\r\n\r\nconst pinchOptions = {\r\n noDrag: false,\r\n percent: 1,\r\n center: null,\r\n factor: 1,\r\n}\r\n\r\nexport class Pinch extends Plugin {\r\n /**\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {PinchOptions} [options]\r\n */\r\n constructor(parent, options = {}) {\r\n super(parent)\r\n this.options = Object.assign({}, pinchOptions, options)\r\n }\r\n\r\n down() {\r\n if (this.parent.input.count() >= 2) {\r\n this.active = true\r\n return true\r\n }\r\n }\r\n\r\n move(e) {\r\n if (this.paused || !this.active) {\r\n return\r\n }\r\n\r\n const x = e.data.global.x\r\n const y = e.data.global.y\r\n\r\n const pointers = this.parent.input.touches\r\n if (pointers.length >= 2) {\r\n const first = pointers[0]\r\n const second = pointers[1]\r\n const last = (first.last && second.last) ? Math.sqrt(Math.pow(second.last.x - first.last.x, 2) + Math.pow(second.last.y - first.last.y, 2)) : null\r\n if (first.id === e.data.pointerId) {\r\n first.last = { x, y, data: e.data }\r\n }\r\n else if (second.id === e.data.pointerId) {\r\n second.last = { x, y, data: e.data }\r\n }\r\n if (last) {\r\n let oldPoint\r\n const point = { x: first.last.x + (second.last.x - first.last.x) / 2, y: first.last.y + (second.last.y - first.last.y) / 2 }\r\n if (!this.options.center) {\r\n oldPoint = this.parent.toLocal(point)\r\n }\r\n let dist = Math.sqrt(Math.pow(second.last.x - first.last.x, 2) + Math.pow(second.last.y - first.last.y, 2))\r\n dist = dist === 0 ? dist = 0.0000000001 : dist\r\n const change = (1 - last / dist) * this.options.percent * this.parent.scale.x\r\n this.parent.scale.x += change\r\n this.parent.scale.y += change\r\n this.parent.emit('zoomed', { viewport: this.parent, type: 'pinch', center: point })\r\n const clamp = this.parent.plugins.get('clamp-zoom', true)\r\n if (clamp) {\r\n clamp.clamp()\r\n }\r\n if (this.options.center) {\r\n this.parent.moveCenter(this.options.center)\r\n }\r\n else {\r\n const newPoint = this.parent.toGlobal(oldPoint)\r\n this.parent.x += (point.x - newPoint.x) * this.options.factor\r\n this.parent.y += (point.y - newPoint.y) * this.options.factor\r\n this.parent.emit('moved', { viewport: this.parent, type: 'pinch' })\r\n }\r\n if (!this.options.noDrag && this.lastCenter) {\r\n this.parent.x += (point.x - this.lastCenter.x) * this.options.factor\r\n this.parent.y += (point.y - this.lastCenter.y) * this.options.factor\r\n this.parent.emit('moved', { viewport: this.parent, type: 'pinch' })\r\n }\r\n this.lastCenter = point\r\n this.moved = true\r\n }\r\n else {\r\n if (!this.pinching) {\r\n this.parent.emit('pinch-start', this.parent)\r\n this.pinching = true\r\n }\r\n }\r\n return true\r\n }\r\n }\r\n\r\n up() {\r\n if (this.pinching) {\r\n if (this.parent.input.touches.length <= 1) {\r\n this.active = false\r\n this.lastCenter = null\r\n this.pinching = false\r\n this.moved = false\r\n this.parent.emit('pinch-end', this.parent)\r\n return true\r\n }\r\n }\r\n }\r\n}","import { Plugin } from './plugin'\r\n\r\n/**\r\n * @typedef ClampOptions\r\n * @property {(number|boolean)} [left=false] clamp left; true = 0\r\n * @property {(number|boolean)} [right=false] clamp right; true = viewport.worldWidth\r\n * @property {(number|boolean)} [top=false] clamp top; true = 0\r\n * @property {(number|boolean)} [bottom=false] clamp bottom; true = viewport.worldHeight\r\n * @property {string} [direction] (all, x, or y) using clamps of [0, viewport.worldWidth/viewport.worldHeight]; replaces left/right/top/bottom if set\r\n * @property {string} [underflow=center] where to place world if too small for screen (e.g., top-right, center, none, bottomleft)\r\n */\r\n\r\nconst clampOptions =\r\n{\r\n left: false,\r\n right: false,\r\n top: false,\r\n bottom: false,\r\n direction: null,\r\n underflow: 'center'\r\n}\r\n\r\nexport class Clamp extends Plugin\r\n{\r\n /**\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {ClampOptions} [options]\r\n */\r\n constructor(parent, options={})\r\n {\r\n super(parent)\r\n this.options = Object.assign({}, clampOptions, options)\r\n if (this.options.direction)\r\n {\r\n this.options.left = this.options.direction === 'x' || this.options.direction === 'all' ? true : null\r\n this.options.right = this.options.direction === 'x' || this.options.direction === 'all' ? true : null\r\n this.options.top = this.options.direction === 'y' || this.options.direction === 'all' ? true : null\r\n this.options.bottom = this.options.direction === 'y' || this.options.direction === 'all' ? true : null\r\n }\r\n this.parseUnderflow()\r\n this.last = { x: null, y: null, scaleX: null, scaleY: null }\r\n this.update()\r\n }\r\n\r\n parseUnderflow()\r\n {\r\n const clamp = this.options.underflow.toLowerCase()\r\n if (clamp === 'none')\r\n {\r\n this.noUnderflow = true\r\n }\r\n else if (clamp === 'center')\r\n {\r\n this.underflowX = this.underflowY = 0\r\n this.noUnderflow = false\r\n }\r\n else\r\n {\r\n this.underflowX = (clamp.indexOf('left') !== -1) ? -1 : (clamp.indexOf('right') !== -1) ? 1 : 0\r\n this.underflowY = (clamp.indexOf('top') !== -1) ? -1 : (clamp.indexOf('bottom') !== -1) ? 1 : 0\r\n this.noUnderflow = false\r\n }\r\n }\r\n\r\n /**\r\n * handle move events\r\n * @param {PIXI.InteractionEvent} event\r\n * @returns {boolean}\r\n */\r\n move()\r\n {\r\n this.update()\r\n return false\r\n }\r\n\r\n update()\r\n {\r\n if (this.paused)\r\n {\r\n return\r\n }\r\n\r\n // only clamp on change\r\n if (this.parent.x === this.last.x && this.parent.y === this.last.y && this.parent.scale.x === this.last.scaleX && this.parent.scale.y === this.last.scaleY)\r\n {\r\n return\r\n }\r\n const original = { x: this.parent.x, y: this.parent.y }\r\n const decelerate = this.parent.plugins['decelerate'] || {}\r\n if (this.options.left !== null || this.options.right !== null)\r\n {\r\n let moved = false\r\n if (this.parent.screenWorldWidth < this.parent.screenWidth)\r\n {\r\n if (!this.noUnderflow)\r\n {\r\n switch (this.underflowX)\r\n {\r\n case -1:\r\n if (this.parent.x !== 0)\r\n {\r\n this.parent.x = 0\r\n moved = true\r\n }\r\n break\r\n case 1:\r\n if (this.parent.x !== this.parent.screenWidth - this.parent.screenWorldWidth)\r\n {\r\n this.parent.x = this.parent.screenWidth - this.parent.screenWorldWidth\r\n moved = true\r\n }\r\n break\r\n default:\r\n if (this.parent.x !== (this.parent.screenWidth - this.parent.screenWorldWidth) / 2)\r\n {\r\n this.parent.x = (this.parent.screenWidth - this.parent.screenWorldWidth) / 2\r\n moved = true\r\n }\r\n }\r\n }\r\n }\r\n else\r\n {\r\n if (this.options.left !== null)\r\n {\r\n if (this.parent.left < (this.options.left === true ? 0 : this.options.left))\r\n {\r\n this.parent.x = -(this.options.left === true ? 0 : this.options.left) * this.parent.scale.x\r\n decelerate.x = 0\r\n moved = true\r\n }\r\n }\r\n if (this.options.right !== null)\r\n {\r\n if (this.parent.right > (this.options.right === true ? this.parent.worldWidth : this.options.right))\r\n {\r\n this.parent.x = -(this.options.right === true ? this.parent.worldWidth : this.options.right) * this.parent.scale.x + this.parent.screenWidth\r\n decelerate.x = 0\r\n moved = true\r\n }\r\n }\r\n }\r\n if (moved)\r\n {\r\n this.parent.emit('moved', { viewport: this.parent, original, type: 'clamp-x' })\r\n }\r\n }\r\n if (this.options.top !== null || this.options.bottom !== null)\r\n {\r\n let moved = false\r\n if (this.parent.screenWorldHeight < this.parent.screenHeight)\r\n {\r\n if (!this.noUnderflow)\r\n {\r\n switch (this.underflowY)\r\n {\r\n case -1:\r\n if (this.parent.y !== 0)\r\n {\r\n this.parent.y = 0\r\n moved = true\r\n }\r\n break\r\n case 1:\r\n if (this.parent.y !== this.parent.screenHeight - this.parent.screenWorldHeight)\r\n {\r\n this.parent.y = (this.parent.screenHeight - this.parent.screenWorldHeight)\r\n moved = true\r\n }\r\n break\r\n default:\r\n if (this.parent.y !== (this.parent.screenHeight - this.parent.screenWorldHeight) / 2)\r\n {\r\n this.parent.y = (this.parent.screenHeight - this.parent.screenWorldHeight) / 2\r\n moved = true\r\n }\r\n }\r\n }\r\n }\r\n else\r\n {\r\n if (this.options.top !== null)\r\n {\r\n if (this.parent.top < (this.options.top === true ? 0 : this.options.top))\r\n {\r\n this.parent.y = -(this.options.top === true ? 0 : this.options.top) * this.parent.scale.y\r\n decelerate.y = 0\r\n moved = true\r\n }\r\n }\r\n if (this.options.bottom !== null)\r\n {\r\n if (this.parent.bottom > (this.options.bottom === true ? this.parent.worldHeight : this.options.bottom))\r\n {\r\n this.parent.y = -(this.options.bottom === true ? this.parent.worldHeight : this.options.bottom) * this.parent.scale.y + this.parent.screenHeight\r\n decelerate.y = 0\r\n moved = true\r\n }\r\n }\r\n }\r\n if (moved)\r\n {\r\n this.parent.emit('moved', { viewport: this.parent, original, type: 'clamp-y' })\r\n }\r\n }\r\n this.last.x = this.parent.x\r\n this.last.y = this.parent.y\r\n this.last.scaleX = this.parent.scale.x\r\n this.last.scaleY = this.parent.scale.y\r\n }\r\n\r\n reset() \r\n {\r\n this.update();\r\n }\r\n}\r\n","import { Plugin } from './plugin'\r\n\r\n/**\r\n * use either minimum width/height or minimum scale\r\n * @typedef {object} ClampZoomOptions\r\n * @property {number} [minWidth] minimum width\r\n * @property {number} [minHeight] minimum height\r\n * @property {number} [maxWidth] maximum width\r\n * @property {number} [maxHeight] maximum height\r\n * @property {number} [minScale] minimum scale\r\n * @property {number} [maxScale] minimum scale\r\n */\r\n\r\nconst clampZoomOptions = {\r\n minWidth: null,\r\n minHeight: null,\r\n maxWidth: null,\r\n maxHeight: null,\r\n minScale: null,\r\n maxScale: null\r\n}\r\n\r\nexport class ClampZoom extends Plugin\r\n{\r\n /**\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {ClampZoomOptions} [options]\r\n */\r\n constructor(parent, options={})\r\n {\r\n super(parent)\r\n this.options = Object.assign({}, clampZoomOptions, options)\r\n this.clamp()\r\n }\r\n\r\n resize()\r\n {\r\n this.clamp()\r\n }\r\n\r\n clamp()\r\n {\r\n if (this.paused)\r\n {\r\n return\r\n }\r\n\r\n if (this.options.minWidth || this.options.minHeight || this.options.maxWidth || this.options.maxHeight)\r\n {\r\n let width = this.parent.worldScreenWidth\r\n let height = this.parent.worldScreenHeight\r\n if (this.options.minWidth !== null && width < this.options.minWidth)\r\n {\r\n const original = this.parent.scale.x\r\n this.parent.fitWidth(this.options.minWidth, false, false, true)\r\n this.parent.scale.y *= this.parent.scale.x / original\r\n width = this.parent.worldScreenWidth\r\n height = this.parent.worldScreenHeight\r\n this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' })\r\n }\r\n if (this.options.maxWidth !== null && width > this.options.maxWidth)\r\n {\r\n const original = this.parent.scale.x\r\n this.parent.fitWidth(this.options.maxWidth, false, false, true)\r\n this.parent.scale.y *= this.parent.scale.x / original\r\n width = this.parent.worldScreenWidth\r\n height = this.parent.worldScreenHeight\r\n this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' })\r\n }\r\n if (this.options.minHeight !== null && height < this.options.minHeight)\r\n {\r\n const original = this.parent.scale.y\r\n this.parent.fitHeight(this.options.minHeight, false, false, true)\r\n this.parent.scale.x *= this.parent.scale.y / original\r\n width = this.parent.worldScreenWidth\r\n height = this.parent.worldScreenHeight\r\n this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' })\r\n }\r\n if (this.options.maxHeight !== null && height > this.options.maxHeight)\r\n {\r\n const original = this.parent.scale.y\r\n this.parent.fitHeight(this.options.maxHeight, false, false, true)\r\n this.parent.scale.x *= this.parent.scale.y / original\r\n this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' })\r\n }\r\n }\r\n else\r\n {\r\n let scale = this.parent.scale.x\r\n if (this.options.minScale !== null && scale < this.options.minScale)\r\n {\r\n scale = this.options.minScale\r\n }\r\n if (this.options.maxScale !== null && scale > this.options.maxScale)\r\n {\r\n scale = this.options.maxScale\r\n }\r\n if (scale !== this.parent.scale.x) {\r\n this.parent.scale.set(scale)\r\n this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' })\r\n }\r\n }\r\n }\r\n\r\n reset()\r\n {\r\n this.clamp()\r\n }\r\n}\r\n","import { Plugin } from './plugin'\r\n\r\n/**\r\n * @typedef {object} DecelerateOptions\r\n * @property {number} [friction=0.95] percent to decelerate after movement\r\n * @property {number} [bounce=0.8] percent to decelerate when past boundaries (only applicable when viewport.bounce() is active)\r\n * @property {number} [minSpeed=0.01] minimum velocity before stopping/reversing acceleration\r\n */\r\n\r\nconst decelerateOptions = {\r\n friction: 0.98,\r\n bounce: 0.8,\r\n minSpeed: 0.01\r\n}\r\n\r\n/**\r\n * Time period of decay (1 frame)\r\n */\r\nconst TP = 16\r\n\r\nexport class Decelerate extends Plugin {\r\n /**\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {DecelerateOptions} [options]\r\n */\r\n constructor(parent, options = {}) {\r\n super(parent)\r\n this.options = Object.assign({}, decelerateOptions, options)\r\n this.saved = []\r\n this.timeSinceRelease = 0\r\n this.reset()\r\n this.parent.on('moved', data => this.moved(data))\r\n }\r\n\r\n destroy() {\r\n this.parent\r\n }\r\n\r\n down() {\r\n this.saved = []\r\n this.x = this.y = false\r\n }\r\n\r\n isActive() {\r\n return this.x || this.y\r\n }\r\n\r\n move() {\r\n if (this.paused) {\r\n return\r\n }\r\n\r\n const count = this.parent.input.count()\r\n if (count === 1 || (count > 1 && !this.parent.plugins.get('pinch', true))) {\r\n this.saved.push({ x: this.parent.x, y: this.parent.y, time: performance.now() })\r\n if (this.saved.length > 60) {\r\n this.saved.splice(0, 30)\r\n }\r\n }\r\n }\r\n\r\n moved(data) {\r\n if (this.saved.length) {\r\n const last = this.saved[this.saved.length - 1]\r\n if (data.type === 'clamp-x') {\r\n if (last.x === data.original.x) {\r\n last.x = this.parent.x\r\n }\r\n }\r\n else if (data.type === 'clamp-y') {\r\n if (last.y === data.original.y) {\r\n last.y = this.parent.y\r\n }\r\n }\r\n }\r\n }\r\n\r\n up() {\r\n if (this.parent.input.count() === 0 && this.saved.length) {\r\n const now = performance.now()\r\n for (let save of this.saved) {\r\n if (save.time >= now - 100) {\r\n const time = now - save.time\r\n this.x = (this.parent.x - save.x) / time\r\n this.y = (this.parent.y - save.y) / time\r\n this.percentChangeX = this.percentChangeY = this.options.friction\r\n this.timeSinceRelease = 0\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * manually activate plugin\r\n * @param {object} options\r\n * @param {number} [options.x]\r\n * @param {number} [options.y]\r\n */\r\n activate(options) {\r\n options = options || {}\r\n if (typeof options.x !== 'undefined') {\r\n this.x = options.x\r\n this.percentChangeX = this.options.friction\r\n }\r\n if (typeof options.y !== 'undefined') {\r\n this.y = options.y\r\n this.percentChangeY = this.options.friction\r\n }\r\n }\r\n\r\n update(elapsed) {\r\n if (this.paused) {\r\n return\r\n }\r\n\r\n /*\r\n * See https://github.com/davidfig/pixi-viewport/issues/271 for math.\r\n *\r\n * The viewport velocity (this.x, this.y) decays expoenential by the the decay factor\r\n * (this.percentChangeX, this.percentChangeY) each frame. This velocity function is integrated\r\n * to calculate the displacement.\r\n */\r\n\r\n const moved = this.x || this.y\r\n\r\n const ti = this.timeSinceRelease\r\n const tf = this.timeSinceRelease + elapsed\r\n\r\n if (this.x) {\r\n const k = this.percentChangeX\r\n const lnk = Math.log(k)\r\n\r\n this.parent.x += ((this.x * TP) / lnk) * (Math.pow(k, tf / TP) - Math.pow(k, ti / TP))\r\n }\r\n if (this.y) {\r\n const k = this.percentChangeY\r\n const lnk = Math.log(k)\r\n\r\n this.parent.y += ((this.y * TP) / lnk) * (Math.pow(k, tf / TP) - Math.pow(k, ti / TP))\r\n }\r\n\r\n this.timeSinceRelease += elapsed\r\n this.x *= Math.pow(this.percentChangeX, elapsed / TP)\r\n this.y *= Math.pow(this.percentChangeY, elapsed / TP)\r\n\r\n if (Math.abs(this.x) < this.options.minSpeed) {\r\n this.x = 0\r\n }\r\n if (Math.abs(this.y) < this.options.minSpeed) {\r\n this.y = 0\r\n }\r\n\r\n if (moved) {\r\n this.parent.emit('moved', { viewport: this.parent, type: 'decelerate' })\r\n }\r\n }\r\n\r\n reset() {\r\n this.x = this.y = null\r\n }\r\n}","\n/*\n\tCopyright © 2001 Robert Penner\n\tAll rights reserved.\n\n\tRedistribution and use in source and binary forms, with or without modification, \n\tare permitted provided that the following conditions are met:\n\n\tRedistributions of source code must retain the above copyright notice, this list of \n\tconditions and the following disclaimer.\n\tRedistributions in binary form must reproduce the above copyright notice, this list \n\tof conditions and the following disclaimer in the documentation and/or other materials \n\tprovided with the distribution.\n\n\tNeither the name of the author nor the names of contributors may be used to endorse \n\tor promote products derived from this software without specific prior written permission.\n\n\tTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY \n\tEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n\tMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n\tCOPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\tEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n\tGOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n\tAND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n\tNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED \n\tOF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n(function() {\n var penner, umd;\n\n umd = function(factory) {\n if (typeof exports === 'object') {\n return module.exports = factory;\n } else if (typeof define === 'function' && define.amd) {\n return define([], factory);\n } else {\n return this.penner = factory;\n }\n };\n\n penner = {\n linear: function(t, b, c, d) {\n return c * t / d + b;\n },\n easeInQuad: function(t, b, c, d) {\n return c * (t /= d) * t + b;\n },\n easeOutQuad: function(t, b, c, d) {\n return -c * (t /= d) * (t - 2) + b;\n },\n easeInOutQuad: function(t, b, c, d) {\n if ((t /= d / 2) < 1) {\n return c / 2 * t * t + b;\n } else {\n return -c / 2 * ((--t) * (t - 2) - 1) + b;\n }\n },\n easeInCubic: function(t, b, c, d) {\n return c * (t /= d) * t * t + b;\n },\n easeOutCubic: function(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t + 1) + b;\n },\n easeInOutCubic: function(t, b, c, d) {\n if ((t /= d / 2) < 1) {\n return c / 2 * t * t * t + b;\n } else {\n return c / 2 * ((t -= 2) * t * t + 2) + b;\n }\n },\n easeInQuart: function(t, b, c, d) {\n return c * (t /= d) * t * t * t + b;\n },\n easeOutQuart: function(t, b, c, d) {\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n },\n easeInOutQuart: function(t, b, c, d) {\n if ((t /= d / 2) < 1) {\n return c / 2 * t * t * t * t + b;\n } else {\n return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n }\n },\n easeInQuint: function(t, b, c, d) {\n return c * (t /= d) * t * t * t * t + b;\n },\n easeOutQuint: function(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n },\n easeInOutQuint: function(t, b, c, d) {\n if ((t /= d / 2) < 1) {\n return c / 2 * t * t * t * t * t + b;\n } else {\n return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n }\n },\n easeInSine: function(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n },\n easeOutSine: function(t, b, c, d) {\n return c * Math.sin(t / d * (Math.PI / 2)) + b;\n },\n easeInOutSine: function(t, b, c, d) {\n return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n },\n easeInExpo: function(t, b, c, d) {\n if (t === 0) {\n return b;\n } else {\n return c * Math.pow(2, 10 * (t / d - 1)) + b;\n }\n },\n easeOutExpo: function(t, b, c, d) {\n if (t === d) {\n return b + c;\n } else {\n return c * (-Math.pow(2, -10 * t / d) + 1) + b;\n }\n },\n easeInOutExpo: function(t, b, c, d) {\n if (t === 0) {\n b;\n }\n if (t === d) {\n b + c;\n }\n if ((t /= d / 2) < 1) {\n return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n } else {\n return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n }\n },\n easeInCirc: function(t, b, c, d) {\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n },\n easeOutCirc: function(t, b, c, d) {\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n },\n easeInOutCirc: function(t, b, c, d) {\n if ((t /= d / 2) < 1) {\n return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n } else {\n return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n }\n },\n easeInElastic: function(t, b, c, d) {\n var a, p, s;\n s = 1.70158;\n p = 0;\n a = c;\n if (t === 0) {\n b;\n } else if ((t /= d) === 1) {\n b + c;\n }\n if (!p) {\n p = d * .3;\n }\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;\n },\n easeOutElastic: function(t, b, c, d) {\n var a, p, s;\n s = 1.70158;\n p = 0;\n a = c;\n if (t === 0) {\n b;\n } else if ((t /= d) === 1) {\n b + c;\n }\n if (!p) {\n p = d * .3;\n }\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;\n },\n easeInOutElastic: function(t, b, c, d) {\n var a, p, s;\n s = 1.70158;\n p = 0;\n a = c;\n if (t === 0) {\n b;\n } else if ((t /= d / 2) === 2) {\n b + c;\n }\n if (!p) {\n p = d * (.3 * 1.5);\n }\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n if (t < 1) {\n return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;\n } else {\n return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;\n }\n },\n easeInBack: function(t, b, c, d, s) {\n if (s === void 0) {\n s = 1.70158;\n }\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\n },\n easeOutBack: function(t, b, c, d, s) {\n if (s === void 0) {\n s = 1.70158;\n }\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n },\n easeInOutBack: function(t, b, c, d, s) {\n if (s === void 0) {\n s = 1.70158;\n }\n if ((t /= d / 2) < 1) {\n return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b;\n } else {\n return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;\n }\n },\n easeInBounce: function(t, b, c, d) {\n var v;\n v = penner.easeOutBounce(d - t, 0, c, d);\n return c - v + b;\n },\n easeOutBounce: function(t, b, c, d) {\n if ((t /= d) < 1 / 2.75) {\n return c * (7.5625 * t * t) + b;\n } else if (t < 2 / 2.75) {\n return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b;\n } else if (t < 2.5 / 2.75) {\n return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b;\n } else {\n return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b;\n }\n },\n easeInOutBounce: function(t, b, c, d) {\n var v;\n if (t < d / 2) {\n v = penner.easeInBounce(t * 2, 0, c, d);\n return v * .5 + b;\n } else {\n v = penner.easeOutBounce(t * 2 - d, 0, c, d);\n return v * .5 + c * .5 + b;\n }\n }\n };\n\n umd(penner);\n\n}).call(this);\n","import Penner from 'penner'\r\n\r\n/**\r\n * returns correct Penner equation using string or Function\r\n * @param {(function|string)} [ease]\r\n * @param {defaults} default penner equation to use if none is provided\r\n */\r\nexport default function ease(ease, defaults)\r\n{\r\n if (!ease)\r\n {\r\n return Penner[defaults]\r\n }\r\n else if (typeof ease === 'function')\r\n {\r\n return ease\r\n }\r\n else if (typeof ease === 'string')\r\n {\r\n return Penner[ease]\r\n }\r\n}","import * as PIXI from 'pixi.js'\r\nimport { Plugin } from './plugin'\r\nimport ease from '../ease'\r\n\r\n/**\r\n * @typedef {options} BounceOptions\r\n * @property {string} [sides=all] all, horizontal, vertical, or combination of top, bottom, right, left (e.g., 'top-bottom-right')\r\n * @property {number} [friction=0.5] friction to apply to decelerate if active\r\n * @property {number} [time=150] time in ms to finish bounce\r\n * @property {object} [bounceBox] use this bounceBox instead of (0, 0, viewport.worldWidth, viewport.worldHeight)\r\n * @property {number} [bounceBox.x=0]\r\n * @property {number} [bounceBox.y=0]\r\n * @property {number} [bounceBox.width=viewport.worldWidth]\r\n * @property {number} [bounceBox.height=viewport.worldHeight]\r\n * @property {string|function} [ease=easeInOutSine] ease function or name (see http://easings.net/ for supported names)\r\n * @property {string} [underflow=center] (top/bottom/center and left/right/center, or center) where to place world if too small for screen\r\n */\r\n\r\nconst bounceOptions = {\r\n sides: 'all',\r\n friction: 0.5,\r\n time: 150,\r\n ease: 'easeInOutSine',\r\n underflow: 'center',\r\n bounceBox: null\r\n}\r\n\r\nexport class Bounce extends Plugin {\r\n /**\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {BounceOptions} [options]\r\n * @fires bounce-start-x\r\n * @fires bounce.end-x\r\n * @fires bounce-start-y\r\n * @fires bounce-end-y\r\n */\r\n constructor(parent, options = {}) {\r\n super(parent)\r\n this.options = Object.assign({}, bounceOptions, options)\r\n this.ease = ease(this.options.ease, 'easeInOutSine')\r\n if (this.options.sides) {\r\n if (this.options.sides === 'all') {\r\n this.top = this.bottom = this.left = this.right = true\r\n }\r\n else if (this.options.sides === 'horizontal') {\r\n this.right = this.left = true\r\n }\r\n else if (this.options.sides === 'vertical') {\r\n this.top = this.bottom = true\r\n }\r\n else {\r\n this.top = this.options.sides.indexOf('top') !== -1\r\n this.bottom = this.options.sides.indexOf('bottom') !== -1\r\n this.left = this.options.sides.indexOf('left') !== -1\r\n this.right = this.options.sides.indexOf('right') !== -1\r\n }\r\n }\r\n this.parseUnderflow()\r\n this.last = {}\r\n this.reset()\r\n }\r\n\r\n parseUnderflow() {\r\n const clamp = this.options.underflow.toLowerCase()\r\n if (clamp === 'center') {\r\n this.underflowX = 0\r\n this.underflowY = 0\r\n }\r\n else {\r\n this.underflowX = (clamp.indexOf('left') !== -1) ? -1 : (clamp.indexOf('right') !== -1) ? 1 : 0\r\n this.underflowY = (clamp.indexOf('top') !== -1) ? -1 : (clamp.indexOf('bottom') !== -1) ? 1 : 0\r\n }\r\n }\r\n\r\n isActive() {\r\n return this.toX !== null || this.toY !== null\r\n }\r\n\r\n down() {\r\n this.toX = this.toY = null\r\n }\r\n\r\n up() {\r\n this.bounce()\r\n }\r\n\r\n update(elapsed) {\r\n if (this.paused) {\r\n return\r\n }\r\n\r\n this.bounce()\r\n if (this.toX) {\r\n const toX = this.toX\r\n toX.time += elapsed\r\n this.parent.emit('moved', { viewport: this.parent, type: 'bounce-x' })\r\n if (toX.time >= this.options.time) {\r\n this.parent.x = toX.end\r\n this.toX = null\r\n this.parent.emit('bounce-x-end', this.parent)\r\n }\r\n else {\r\n this.parent.x = this.ease(toX.time, toX.start, toX.delta, this.options.time)\r\n }\r\n }\r\n if (this.toY) {\r\n const toY = this.toY\r\n toY.time += elapsed\r\n this.parent.emit('moved', { viewport: this.parent, type: 'bounce-y' })\r\n if (toY.time >= this.options.time) {\r\n this.parent.y = toY.end\r\n this.toY = null\r\n this.parent.emit('bounce-y-end', this.parent)\r\n }\r\n else {\r\n this.parent.y = this.ease(toY.time, toY.start, toY.delta, this.options.time)\r\n }\r\n }\r\n }\r\n\r\n calcUnderflowX() {\r\n let x\r\n switch (this.underflowX) {\r\n case -1:\r\n x = 0\r\n break\r\n case 1:\r\n x = (this.parent.screenWidth - this.parent.screenWorldWidth)\r\n break\r\n default:\r\n x = (this.parent.screenWidth - this.parent.screenWorldWidth) / 2\r\n }\r\n return x\r\n }\r\n\r\n calcUnderflowY() {\r\n let y\r\n switch (this.underflowY) {\r\n case -1:\r\n y = 0\r\n break\r\n case 1:\r\n y = (this.parent.screenHeight - this.parent.screenWorldHeight)\r\n break\r\n default:\r\n y = (this.parent.screenHeight - this.parent.screenWorldHeight) / 2\r\n }\r\n return y\r\n }\r\n\r\n oob() {\r\n const box = this.options.bounceBox\r\n if (box) {\r\n const x1 = typeof box.x === 'undefined' ? 0 : box.x\r\n const y1 = typeof box.y === 'undefined' ? 0 : box.y\r\n const width = typeof box.width === 'undefined' ? this.parent.worldWidth : box.width\r\n const height = typeof box.height === 'undefined' ? this.parent.worldHeight : box.height\r\n return {\r\n left: this.parent.left < x1,\r\n right: this.parent.right > width,\r\n top: this.parent.top < y1,\r\n bottom: this.parent.bottom > height,\r\n topLeft: new PIXI.Point(\r\n x1 * this.parent.scale.x,\r\n y1 * this.parent.scale.y\r\n ),\r\n bottomRight: new PIXI.Point(\r\n width * this.parent.scale.x - this.parent.screenWidth,\r\n height * this.parent.scale.y - this.parent.screenHeight\r\n )\r\n }\r\n }\r\n return {\r\n left: this.parent.left < 0,\r\n right: this.parent.right > this.parent.worldWidth,\r\n top: this.parent.top < 0,\r\n bottom: this.parent.bottom > this.parent.worldHeight,\r\n topLeft: new PIXI.Point(0, 0),\r\n bottomRight: new PIXI.Point(\r\n this.parent.worldWidth * this.parent.scale.x - this.parent.screenWidth,\r\n this.parent.worldHeight * this.parent.scale.y - this.parent.screenHeight\r\n )\r\n }\r\n }\r\n\r\n bounce() {\r\n if (this.paused) {\r\n return\r\n }\r\n\r\n let oob\r\n let decelerate = this.parent.plugins.get('decelerate', true)\r\n if (decelerate && (decelerate.x || decelerate.y)) {\r\n if ((decelerate.x && decelerate.percentChangeX === decelerate.options.friction) || (decelerate.y && decelerate.percentChangeY === decelerate.options.friction)) {\r\n oob = this.oob()\r\n if ((oob.left && this.left) || (oob.right && this.right)) {\r\n decelerate.percentChangeX = this.options.friction\r\n }\r\n if ((oob.top && this.top) || (oob.bottom && this.bottom)) {\r\n decelerate.percentChangeY = this.options.friction\r\n }\r\n }\r\n }\r\n const drag = this.parent.plugins.get('drag', true) || {}\r\n const pinch = this.parent.plugins.get('pinch', true) || {}\r\n decelerate = decelerate || {}\r\n if (!drag.active && !pinch.active && ((!this.toX || !this.toY) && (!decelerate.x || !decelerate.y))) {\r\n oob = oob || this.oob()\r\n const topLeft = oob.topLeft\r\n const bottomRight = oob.bottomRight\r\n if (!this.toX && !decelerate.x) {\r\n let x = null\r\n if (oob.left && this.left) {\r\n x = (this.parent.screenWorldWidth < this.parent.screenWidth) ? this.calcUnderflowX() : -topLeft.x\r\n }\r\n else if (oob.right && this.right) {\r\n x = (this.parent.screenWorldWidth < this.parent.screenWidth) ? this.calcUnderflowX() : -bottomRight.x\r\n }\r\n if (x !== null && this.parent.x !== x) {\r\n this.toX = { time: 0, start: this.parent.x, delta: x - this.parent.x, end: x }\r\n this.parent.emit('bounce-x-start', this.parent)\r\n }\r\n }\r\n if (!this.toY && !decelerate.y) {\r\n let y = null\r\n if (oob.top && this.top) {\r\n y = (this.parent.screenWorldHeight < this.parent.screenHeight) ? this.calcUnderflowY() : -topLeft.y\r\n }\r\n else if (oob.bottom && this.bottom) {\r\n y = (this.parent.screenWorldHeight < this.parent.screenHeight) ? this.calcUnderflowY() : -bottomRight.y\r\n }\r\n if (y !== null && this.parent.y !== y) {\r\n this.toY = { time: 0, start: this.parent.y, delta: y - this.parent.y, end: y }\r\n this.parent.emit('bounce-y-start', this.parent)\r\n }\r\n }\r\n }\r\n }\r\n\r\n reset() {\r\n this.toX = this.toY = null\r\n this.bounce()\r\n }\r\n}","import { Plugin } from './plugin'\r\nimport ease from '../ease'\r\n\r\n/**\r\n * @typedef SnapOptions\r\n * @property {boolean} [topLeft] snap to the top-left of viewport instead of center\r\n * @property {number} [friction=0.8] friction/frame to apply if decelerate is active\r\n * @property {number} [time=1000]\r\n * @property {string|function} [ease=easeInOutSine] ease function or name (see http://easings.net/ for supported names)\r\n * @property {boolean} [interrupt=true] pause snapping with any user input on the viewport\r\n * @property {boolean} [removeOnComplete] removes this plugin after snapping is complete\r\n * @property {boolean} [removeOnInterrupt] removes this plugin if interrupted by any user input\r\n * @property {boolean} [forceStart] starts the snap immediately regardless of whether the viewport is at the desired location\r\n */\r\n\r\nconst snapOptions = {\r\n topLeft: false,\r\n friction: 0.8,\r\n time: 1000,\r\n ease: 'easeInOutSine',\r\n interrupt: true,\r\n removeOnComplete: false,\r\n removeOnInterrupt: false,\r\n forceStart: false\r\n}\r\n\r\nexport class Snap extends Plugin {\r\n /**\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {number} x\r\n * @param {number} y\r\n * @param {SnapOptions} [options]\r\n * @event snap-start(Viewport) emitted each time a snap animation starts\r\n * @event snap-restart(Viewport) emitted each time a snap resets because of a change in viewport size\r\n * @event snap-end(Viewport) emitted each time snap reaches its target\r\n * @event snap-remove(Viewport) emitted if snap plugin is removed\r\n */\r\n constructor(parent, x, y, options = {}) {\r\n super(parent)\r\n this.options = Object.assign({}, snapOptions, options)\r\n this.ease = ease(options.ease, 'easeInOutSine')\r\n this.x = x\r\n this.y = y\r\n if (this.options.forceStart) {\r\n this.snapStart()\r\n }\r\n }\r\n\r\n snapStart() {\r\n this.percent = 0\r\n this.snapping = { time: 0 }\r\n const current = this.options.topLeft ? this.parent.corner : this.parent.center\r\n this.deltaX = this.x - current.x\r\n this.deltaY = this.y - current.y\r\n this.startX = current.x\r\n this.startY = current.y\r\n this.parent.emit('snap-start', this.parent)\r\n }\r\n\r\n wheel() {\r\n if (this.options.removeOnInterrupt) {\r\n this.parent.plugins.remove('snap')\r\n }\r\n }\r\n\r\n down() {\r\n if (this.options.removeOnInterrupt) {\r\n this.parent.plugins.remove('snap')\r\n }\r\n else if (this.options.interrupt) {\r\n this.snapping = null\r\n }\r\n }\r\n\r\n up() {\r\n if (this.parent.input.count() === 0) {\r\n const decelerate = this.parent.plugins.get('decelerate', true)\r\n if (decelerate && (decelerate.x || decelerate.y)) {\r\n decelerate.percentChangeX = decelerate.percentChangeY = this.options.friction\r\n }\r\n }\r\n }\r\n\r\n update(elapsed) {\r\n if (this.paused) {\r\n return\r\n }\r\n if (this.options.interrupt && this.parent.input.count() !== 0) {\r\n return\r\n }\r\n if (!this.snapping) {\r\n const current = this.options.topLeft ? this.parent.corner : this.parent.center\r\n if (current.x !== this.x || current.y !== this.y) {\r\n this.snapStart()\r\n }\r\n }\r\n else {\r\n const snapping = this.snapping\r\n snapping.time += elapsed\r\n let finished, x, y\r\n if (snapping.time > this.options.time) {\r\n finished = true\r\n x = this.startX + this.deltaX\r\n y = this.startY + this.deltaY\r\n }\r\n else {\r\n const percent = this.ease(snapping.time, 0, 1, this.options.time)\r\n x = this.startX + this.deltaX * percent\r\n y = this.startY + this.deltaY * percent\r\n }\r\n if (this.options.topLeft) {\r\n this.parent.moveCorner(x, y)\r\n }\r\n else {\r\n this.parent.moveCenter(x, y)\r\n }\r\n this.parent.emit('moved', { viewport: this.parent, type: 'snap' })\r\n if (finished) {\r\n if (this.options.removeOnComplete) {\r\n this.parent.plugins.remove('snap')\r\n }\r\n this.parent.emit('snap-end', this.parent)\r\n this.snapping = null\r\n }\r\n }\r\n }\r\n}","import { Plugin } from './plugin'\r\nimport ease from '../ease'\r\n\r\n/**\r\n * @typedef {Object} SnapZoomOptions\r\n * @property {number} [width=0] the desired width to snap (to maintain aspect ratio, choose only width or height)\r\n * @property {number} [height=0] the desired height to snap (to maintain aspect ratio, choose only width or height)\r\n * @property {number} [time=1000] time for snapping in ms\r\n * @property {(string|function)} [ease=easeInOutSine] ease function or name (see http://easings.net/ for supported names)\r\n * @property {PIXI.Point} [center] place this point at center during zoom instead of center of the viewport\r\n * @property {boolean} [interrupt=true] pause snapping with any user input on the viewport\r\n * @property {boolean} [removeOnComplete] removes this plugin after snapping is complete\r\n * @property {boolean} [removeOnInterrupt] removes this plugin if interrupted by any user input\r\n * @property {boolean} [forceStart] starts the snap immediately regardless of whether the viewport is at the desired zoom\r\n * @property {boolean} [noMove] zoom but do not move\r\n */\r\n\r\nconst snapZoomOptions = {\r\n width: 0,\r\n height: 0,\r\n time: 1000,\r\n ease: 'easeInOutSine',\r\n center: null,\r\n interrupt: true,\r\n removeOnComplete: false,\r\n removeOnInterrupts: false,\r\n forceStart: false,\r\n noMove: false\r\n}\r\n\r\nexport class SnapZoom extends Plugin {\r\n /**\r\n * @param {Viewport} parent\r\n * @param {SnapZoomOptions} options\r\n * @event snap-zoom-start(Viewport) emitted each time a fit animation starts\r\n * @event snap-zoom-end(Viewport) emitted each time fit reaches its target\r\n * @event snap-zoom-end(Viewport) emitted each time fit reaches its target\r\n */\r\n constructor(parent, options = {}) {\r\n super(parent)\r\n this.options = Object.assign({}, snapZoomOptions, options)\r\n this.ease = ease(this.options.ease)\r\n if (this.options.width > 0) {\r\n this.xScale = parent.screenWidth / this.options.width\r\n }\r\n if (this.options.height > 0) {\r\n this.yScale = parent.screenHeight / this.options.height\r\n }\r\n this.xIndependent = this.xScale ? true : false\r\n this.yIndependent = this.yScale ? true : false\r\n this.xScale = this.xIndependent ? this.xScale : this.yScale\r\n this.yScale = this.yIndependent ? this.yScale : this.xScale\r\n\r\n if (this.options.time === 0) {\r\n parent.container.scale.x = this.xScale\r\n parent.container.scale.y = this.yScale\r\n if (this.options.removeOnComplete) {\r\n this.parent.plugins.remove('snap-zoom')\r\n }\r\n }\r\n else if (options.forceStart) {\r\n this.createSnapping()\r\n }\r\n }\r\n\r\n createSnapping() {\r\n const scale = this.parent.scale\r\n const startWorldScreenWidth = this.parent.worldScreenWidth\r\n const startWorldScreenHeight = this.parent.worldScreenHeight\r\n const endWorldScreenWidth = this.parent.screenWidth / this.xScale\r\n const endWorldScreenHeight = this.parent.screenHeight / this.yScale\r\n \r\n this.snapping = { \r\n time: 0, \r\n startX: startWorldScreenWidth, \r\n startY: startWorldScreenHeight, \r\n deltaX: endWorldScreenWidth - startWorldScreenWidth, \r\n deltaY: endWorldScreenHeight - startWorldScreenHeight \r\n }\r\n this.parent.emit('snap-zoom-start', this.parent)\r\n }\r\n\r\n resize() {\r\n this.snapping = null\r\n\r\n if (this.options.width > 0) {\r\n this.xScale = this.parent.screenWidth / this.options.width\r\n }\r\n if (this.options.height > 0) {\r\n this.yScale = this.parent.screenHeight / this.options.height\r\n }\r\n this.xScale = this.xIndependent ? this.xScale : this.yScale\r\n this.yScale = this.yIndependent ? this.yScale : this.xScale\r\n }\r\n\r\n wheel() {\r\n if (this.options.removeOnInterrupt) {\r\n this.parent.plugins.remove('snap-zoom')\r\n }\r\n }\r\n\r\n down() {\r\n if (this.options.removeOnInterrupt) {\r\n this.parent.plugins.remove('snap-zoom')\r\n }\r\n else if (this.options.interrupt) {\r\n this.snapping = null\r\n }\r\n }\r\n\r\n update(elapsed) {\r\n if (this.paused) {\r\n return\r\n }\r\n if (this.options.interrupt && this.parent.input.count() !== 0) {\r\n return\r\n }\r\n\r\n let oldCenter\r\n if (!this.options.center && !this.options.noMove) {\r\n oldCenter = this.parent.center\r\n }\r\n if (!this.snapping) {\r\n if (this.parent.scale.x !== this.xScale || this.parent.scale.y !== this.yScale) {\r\n this.createSnapping()\r\n }\r\n }\r\n else if (this.snapping) {\r\n const snapping = this.snapping\r\n snapping.time += elapsed\r\n if (snapping.time >= this.options.time) {\r\n this.parent.scale.set(this.xScale, this.yScale)\r\n if (this.options.removeOnComplete) {\r\n this.parent.plugins.remove('snap-zoom')\r\n }\r\n this.parent.emit('snap-zoom-end', this.parent)\r\n this.snapping = null\r\n }\r\n else {\r\n const snapping = this.snapping\r\n const worldScreenWidth = this.ease(snapping.time, snapping.startX, snapping.deltaX, this.options.time)\r\n const worldScreenHeight = this.ease(snapping.time, snapping.startY, snapping.deltaY, this.options.time)\r\n\r\n this.parent.scale.x = this.parent.screenWidth / worldScreenWidth\r\n this.parent.scale.y = this.parent.screenHeight / worldScreenHeight\r\n }\r\n const clamp = this.parent.plugins.get('clamp-zoom', true)\r\n if (clamp) {\r\n clamp.clamp()\r\n }\r\n if (!this.options.noMove) {\r\n if (!this.options.center) {\r\n this.parent.moveCenter(oldCenter)\r\n }\r\n else {\r\n this.parent.moveCenter(this.options.center)\r\n }\r\n }\r\n }\r\n }\r\n\r\n resume() {\r\n this.snapping = null\r\n super.resume()\r\n }\r\n}","import { Plugin } from './plugin'\r\n\r\n/**\r\n * @typedef {object} FollowOptions\r\n * @property {number} [speed=0] to follow in pixels/frame (0=teleport to location)\r\n * @property {number} [acceleration] set acceleration to accelerate and decelerate at this rate; speed cannot be 0 to use acceleration\r\n * @property {number} [radius] radius (in world coordinates) of center circle where movement is allowed without moving the viewport\r\n */\r\n\r\nconst followOptions = {\r\n speed: 0,\r\n acceleration: null,\r\n radius: null\r\n}\r\n\r\nexport class Follow extends Plugin\r\n{\r\n /**\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {PIXI.DisplayObject} target to follow\r\n * @param {FollowOptions} [options]\r\n */\r\n constructor(parent, target, options = {})\r\n {\r\n super(parent)\r\n this.target = target\r\n this.options = Object.assign({}, followOptions, options)\r\n this.velocity = { x: 0, y: 0 }\r\n }\r\n\r\n update(elapsed)\r\n {\r\n if (this.paused)\r\n {\r\n return\r\n }\r\n\r\n const center = this.parent.center\r\n let toX = this.target.x,\r\n toY = this.target.y\r\n if (this.options.radius)\r\n {\r\n const distance = Math.sqrt(Math.pow(this.target.y - center.y, 2) + Math.pow(this.target.x - center.x, 2))\r\n if (distance > this.options.radius)\r\n {\r\n const angle = Math.atan2(this.target.y - center.y, this.target.x - center.x)\r\n toX = this.target.x - Math.cos(angle) * this.options.radius\r\n toY = this.target.y - Math.sin(angle) * this.options.radius\r\n }\r\n else\r\n {\r\n return\r\n }\r\n }\r\n\r\n const deltaX = toX - center.x\r\n const deltaY = toY - center.y\r\n if (deltaX || deltaY)\r\n {\r\n if (this.options.speed)\r\n {\r\n if (this.options.acceleration)\r\n {\r\n const angle = Math.atan2(toY - center.y, toX - center.x)\r\n const distance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2))\r\n if (distance)\r\n {\r\n const decelerationDistance = (Math.pow(this.velocity.x, 2) + Math.pow(this.velocity.y, 2)) / (2 * this.options.acceleration)\r\n if (distance > decelerationDistance)\r\n {\r\n this.velocity = {\r\n x: Math.min(this.velocity.x + this.options.acceleration * elapsed, this.options.speed),\r\n y: Math.min(this.velocity.y + this.options.acceleration * elapsed, this.options.speed)\r\n }\r\n }\r\n else\r\n {\r\n this.velocity = {\r\n x: Math.max(this.velocity.x - this.options.acceleration * this.options.speed, 0),\r\n y: Math.max(this.velocity.y - this.options.acceleration * this.options.speed, 0)\r\n }\r\n }\r\n const changeX = Math.cos(angle) * this.velocity.x\r\n const changeY = Math.sin(angle) * this.velocity.y\r\n const x = Math.abs(changeX) > Math.abs(deltaX) ? toX : center.x + changeX\r\n const y = Math.abs(changeY) > Math.abs(deltaY) ? toY : center.y + changeY\r\n this.parent.moveCenter(x, y)\r\n this.parent.emit('moved', { viewport: this.parent, type: 'follow' })\r\n }\r\n }\r\n else\r\n {\r\n const angle = Math.atan2(toY - center.y, toX - center.x)\r\n const changeX = Math.cos(angle) * this.options.speed\r\n const changeY = Math.sin(angle) * this.options.speed\r\n const x = Math.abs(changeX) > Math.abs(deltaX) ? toX : center.x + changeX\r\n const y = Math.abs(changeY) > Math.abs(deltaY) ? toY : center.y + changeY\r\n this.parent.moveCenter(x, y)\r\n this.parent.emit('moved', { viewport: this.parent, type: 'follow' })\r\n }\r\n }\r\n else\r\n {\r\n this.parent.moveCenter(toX, toY)\r\n this.parent.emit('moved', { viewport: this.parent, type: 'follow' })\r\n }\r\n }\r\n }\r\n}","import { Plugin } from './plugin'\r\n\r\n/**\r\n * the default event listener for 'wheel' event is document.body. Use `Viewport.options.divWheel` to change this default\r\n * @typedef WheelOptions\r\n * @property {number} [percent=0.1] percent to scroll with each spin\r\n * @property {number} [smooth] smooth the zooming by providing the number of frames to zoom between wheel spins\r\n * @property {boolean} [interrupt=true] stop smoothing with any user input on the viewport\r\n * @property {boolean} [reverse] reverse the direction of the scroll\r\n * @property {PIXI.Point} [center] place this point at center during zoom instead of current mouse position\r\n * @property {number} [lineHeight=20] scaling factor for non-DOM_DELTA_PIXEL scrolling events\r\n */\r\n\r\nconst wheelOptions = {\r\n percent: 0.1,\r\n smooth: false,\r\n interrupt: true,\r\n reverse: false,\r\n center: null,\r\n lineHeight: 20\r\n}\r\n\r\nexport class Wheel extends Plugin {\r\n /**\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {WheelOptions} [options]\r\n * @event wheel({wheel: {dx, dy, dz}, event, viewport})\r\n */\r\n constructor(parent, options = {}) {\r\n super(parent)\r\n this.options = Object.assign({}, wheelOptions, options)\r\n }\r\n\r\n down() {\r\n if (this.options.interrupt) {\r\n this.smoothing = null\r\n }\r\n }\r\n\r\n update() {\r\n if (this.smoothing) {\r\n const point = this.smoothingCenter\r\n const change = this.smoothing\r\n let oldPoint\r\n if (!this.options.center) {\r\n oldPoint = this.parent.toLocal(point)\r\n }\r\n this.parent.scale.x += change.x\r\n this.parent.scale.y += change.y\r\n this.parent.emit('zoomed', { viewport: this.parent, type: 'wheel' })\r\n const clamp = this.parent.plugins.get('clamp-zoom', true)\r\n if (clamp) {\r\n clamp.clamp()\r\n }\r\n if (this.options.center) {\r\n this.parent.moveCenter(this.options.center)\r\n }\r\n else {\r\n const newPoint = this.parent.toGlobal(oldPoint)\r\n this.parent.x += point.x - newPoint.x\r\n this.parent.y += point.y - newPoint.y\r\n }\r\n this.parent.emit('moved', { viewport: this.parent, type: 'wheel' })\r\n this.smoothingCount++\r\n if (this.smoothingCount >= this.options.smooth) {\r\n this.smoothing = null\r\n }\r\n }\r\n }\r\n\r\n wheel(e) {\r\n if (this.paused) {\r\n return\r\n }\r\n\r\n let point = this.parent.input.getPointerPosition(e)\r\n const sign = this.options.reverse ? -1 : 1\r\n const step = sign * -e.deltaY * (e.deltaMode ? this.options.lineHeight : 1) / 500\r\n const change = Math.pow(2, (1 + this.options.percent) * step)\r\n if (this.options.smooth) {\r\n const original = {\r\n x: this.smoothing ? this.smoothing.x * (this.options.smooth - this.smoothingCount) : 0,\r\n y: this.smoothing ? this.smoothing.y * (this.options.smooth - this.smoothingCount) : 0\r\n }\r\n this.smoothing = {\r\n x: ((this.parent.scale.x + original.x) * change - this.parent.scale.x) / this.options.smooth,\r\n y: ((this.parent.scale.y + original.y) * change - this.parent.scale.y) / this.options.smooth\r\n }\r\n this.smoothingCount = 0\r\n this.smoothingCenter = point\r\n }\r\n else {\r\n let oldPoint\r\n if (!this.options.center) {\r\n oldPoint = this.parent.toLocal(point)\r\n }\r\n this.parent.scale.x *= change\r\n this.parent.scale.y *= change\r\n this.parent.emit('zoomed', { viewport: this.parent, type: 'wheel' })\r\n const clamp = this.parent.plugins.get('clamp-zoom', true)\r\n if (clamp) {\r\n clamp.clamp()\r\n }\r\n if (this.options.center) {\r\n this.parent.moveCenter(this.options.center)\r\n }\r\n else {\r\n const newPoint = this.parent.toGlobal(oldPoint)\r\n this.parent.x += point.x - newPoint.x\r\n this.parent.y += point.y - newPoint.y\r\n }\r\n }\r\n this.parent.emit('moved', { viewport: this.parent, type: 'wheel' })\r\n this.parent.emit('wheel', { wheel: { dx: e.deltaX, dy: e.deltaY, dz: e.deltaZ }, event: e, viewport: this.parent })\r\n if (!this.parent.options.passiveWheel) {\r\n return true\r\n }\r\n }\r\n}\r\n","import { Plugin } from './plugin'\r\n\r\n/**\r\n * @typedef MouseEdgesOptions\r\n * @property {number} [radius] distance from center of screen in screen pixels\r\n * @property {number} [distance] distance from all sides in screen pixels\r\n * @property {number} [top] alternatively, set top distance (leave unset for no top scroll)\r\n * @property {number} [bottom] alternatively, set bottom distance (leave unset for no top scroll)\r\n * @property {number} [left] alternatively, set left distance (leave unset for no top scroll)\r\n * @property {number} [right] alternatively, set right distance (leave unset for no top scroll)\r\n * @property {number} [speed=8] speed in pixels/frame to scroll viewport\r\n * @property {boolean} [reverse] reverse direction of scroll\r\n * @property {boolean} [noDecelerate] don't use decelerate plugin even if it's installed\r\n * @property {boolean} [linear] if using radius, use linear movement (+/- 1, +/- 1) instead of angled movement (Math.cos(angle from center), Math.sin(angle from center))\r\n * @property {boolean} [allowButtons] allows plugin to continue working even when there's a mousedown event\r\n */\r\n\r\nconst mouseEdgesOptions = {\r\n radius: null,\r\n distance: null,\r\n top: null,\r\n bottom: null,\r\n left: null,\r\n right: null,\r\n speed: 8,\r\n reverse: false,\r\n noDecelerate: false,\r\n linear: false,\r\n allowButtons: false\r\n}\r\n\r\nexport class MouseEdges extends Plugin {\r\n /**\r\n * Scroll viewport when mouse hovers near one of the edges.\r\n * @private\r\n * @param {Viewport} parent\r\n * @param {MouseEdgeOptions} [options]\r\n * @event mouse-edge-start(Viewport) emitted when mouse-edge starts\r\n * @event mouse-edge-end(Viewport) emitted when mouse-edge ends\r\n */\r\n constructor(parent, options = {}) {\r\n super(parent)\r\n this.options = Object.assign({}, mouseEdgesOptions, options)\r\n this.reverse = this.options.reverse ? 1 : -1\r\n this.radiusSquared = Math.pow(this.options.radius, 2)\r\n this.resize()\r\n }\r\n\r\n resize() {\r\n const distance = this.options.distance\r\n if (distance !== null) {\r\n this.left = distance\r\n this.top = distance\r\n this.right = this.parent.worldScreenWidth - distance\r\n this.bottom = this.parent.worldScreenHeight - distance\r\n }\r\n else if (!this.radius) {\r\n this.left = this.options.left\r\n this.top = this.options.top\r\n this.right = this.options.right === null ? null : this.parent.worldScreenWidth - this.options.right\r\n this.bottom = this.options.bottom === null ? null : this.parent.worldScreenHeight - this.options.bottom\r\n }\r\n }\r\n\r\n down() {\r\n if (this.paused) {\r\n return\r\n }\r\n if (!this.options.allowButtons) {\r\n this.horizontal = this.vertical = null\r\n }\r\n }\r\n\r\n move(event) {\r\n if (this.paused) {\r\n return\r\n }\r\n if ((event.data.pointerType !== 'mouse' && event.data.identifier !== 1) || (!this.options.allowButtons && event.data.buttons !== 0)) {\r\n return\r\n }\r\n const x = event.data.global.x\r\n const y = event.data.global.y\r\n\r\n if (this.radiusSquared) {\r\n const center = this.parent.toScreen(this.parent.center)\r\n const distance = Math.pow(center.x - x, 2) + Math.pow(center.y - y, 2)\r\n if (distance >= this.radiusSquared) {\r\n const angle = Math.atan2(center.y - y, center.x - x)\r\n if (this.options.linear) {\r\n this.horizontal = Math.round(Math.cos(angle)) * this.options.speed * this.reverse * (60 / 1000)\r\n this.vertical = Math.round(Math.sin(angle)) * this.options.speed * this.reverse * (60 / 1000)\r\n }\r\n else {\r\n this.horizontal = Math.cos(angle) * this.options.speed * this.reverse * (60 / 1000)\r\n this.vertical = Math.sin(angle) * this.options.speed * this.reverse * (60 / 1000)\r\n }\r\n }\r\n else {\r\n if (this.horizontal) {\r\n this.decelerateHorizontal()\r\n }\r\n if (this.vertical) {\r\n this.decelerateVertical()\r\n }\r\n this.horizontal = this.vertical = 0\r\n }\r\n }\r\n else {\r\n if (this.left !== null && x < this.left) {\r\n this.horizontal = 1 * this.reverse * this.options.speed * (60 / 1000)\r\n }\r\n else if (this.right !== null && x > this.right) {\r\n this.horizontal = -1 * this.reverse * this.options.speed * (60 / 1000)\r\n }\r\n else {\r\n this.decelerateHorizontal()\r\n this.horizontal = 0\r\n }\r\n if (this.top !== null && y < this.top) {\r\n this.vertical = 1 * this.reverse * this.options.speed * (60 / 1000)\r\n }\r\n else if (this.bottom !== null && y > this.bottom) {\r\n this.vertical = -1 * this.reverse * this.options.speed * (60 / 1000)\r\n }\r\n else {\r\n this.decelerateVertical()\r\n this.vertical = 0\r\n }\r\n }\r\n }\r\n\r\n decelerateHorizontal() {\r\n const decelerate = this.parent.plugins.get('decelerate', true)\r\n if (this.horizontal && decelerate && !this.options.noDecelerate) {\r\n decelerate.activate({ x: (this.horizontal * this.options.speed * this.reverse) / (1000 / 60) })\r\n }\r\n }\r\n\r\n decelerateVertical() {\r\n const decelerate = this.parent.plugins.get('decelerate', true)\r\n if (this.vertical && decelerate && !this.options.noDecelerate) {\r\n decelerate.activate({ y: (this.vertical * this.options.speed * this.reverse) / (1000 / 60) })\r\n }\r\n }\r\n\r\n up() {\r\n if (this.paused) {\r\n return\r\n }\r\n if (this.horizontal) {\r\n this.decelerateHorizontal()\r\n }\r\n if (this.vertical) {\r\n this.decelerateVertical()\r\n }\r\n this.horizontal = this.vertical = null\r\n }\r\n\r\n update() {\r\n if (this.paused) {\r\n return\r\n }\r\n\r\n if (this.horizontal || this.vertical) {\r\n const center = this.parent.center\r\n if (this.horizontal) {\r\n center.x += this.horizontal * this.options.speed\r\n }\r\n if (this.vertical) {\r\n center.y += this.vertical * this.options.speed\r\n }\r\n this.parent.moveCenter(center)\r\n this.parent.emit('moved', { viewport: this.parent, type: 'mouse-edges' })\r\n }\r\n }\r\n}","import * as PIXI from 'pixi.js'\nimport { Plugin } from './plugin'\nimport ease from '../ease'\n\n/**\n * To set the zoom level, use: (1) scale, (2) scaleX and scaleY, or (3) width and/or height\n * @typedef {options} AnimateOptions\n * @property {number} [time=1000] to animate\n * @property {PIXI.Point} [position=viewport.center] position to move viewport\n * @property {number} [width] desired viewport width in world pixels (use instead of scale; aspect ratio is maintained if height is not provided)\n * @property {number} [height] desired viewport height in world pixels (use instead of scale; aspect ratio is maintained if width is not provided)\n * @property {number} [scale] scale to change zoom (scale.x = scale.y)\n * @property {number} [scaleX] independently change zoom in x-direction\n * @property {number} [scaleY] independently change zoom in y-direction\n * @property {(function|string)} [ease=linear] easing function to use\n * @property {function} [callbackOnComplete]\n * @property {boolean} [removeOnInterrupt] removes this plugin if interrupted by any user input\n */\n\nconst animateOptions = {\n removeOnInterrupt: false,\n ease: 'linear',\n time: 1000\n}\n\nexport class Animate extends Plugin\n{\n /**\n * @private\n * @param {Viewport} parent\n * @param {AnimateOptions} [options]\n * @fires animate-end\n */\n constructor(parent, options={})\n {\n super(parent)\n this.options = Object.assign({}, animateOptions, options)\n this.options.ease = ease(this.options.ease)\n this.setupPosition()\n this.setupZoom()\n }\n\n setupPosition()\n {\n if (typeof this.options.position !== 'undefined')\n {\n this.startX = this.parent.center.x\n this.startY = this.parent.center.y\n this.deltaX = this.options.position.x - this.parent.center.x\n this.deltaY = this.options.position.y - this.parent.center.y\n this.keepCenter = false\n }\n else\n {\n this.keepCenter = true\n }\n }\n\n setupZoom()\n {\n this.width = null\n this.height = null\n if (typeof this.options.scale !== 'undefined')\n {\n this.width = this.parent.screenWidth / this.options.scale\n }\n else if (typeof this.options.scaleX !== 'undefined' || typeof this.options.scaleY !== 'undefined')\n {\n if (typeof this.options.scaleX !== 'undefined')\n {\n // screenSizeInWorldPixels = screenWidth / scale\n this.width = this.parent.screenWidth / this.options.scaleX\n }\n if (typeof this.options.scaleY !== 'undefined')\n {\n this.height = this.parent.screenHeight / this.options.scaleY\n }\n }\n else\n {\n if (typeof this.options.width !== 'undefined')\n {\n this.width = this.options.width\n }\n if (typeof this.options.height !== 'undefined')\n {\n this.height = this.options.height\n }\n }\n if (typeof this.width !== null)\n {\n this.startWidth = this.parent.screenWidthInWorldPixels\n this.deltaWidth = this.width - this.startWidth\n }\n if (typeof this.height !== null)\n {\n this.startHeight = this.parent.screenHeightInWorldPixels\n this.deltaHeight = this.height - this.startHeight\n }\n this.time = 0\n }\n\n down()\n {\n if (this.options.removeOnInterrupt)\n {\n this.parent.plugins.remove('animate')\n }\n }\n\n complete()\n {\n this.parent.plugins.remove('animate')\n if (this.width !== null)\n {\n this.parent.fitWidth(this.width, this.keepCenter, this.height === null)\n }\n if (this.height !== null)\n {\n this.parent.fitHeight(this.height, this.keepCenter, this.width === null)\n }\n if (!this.keepCenter)\n {\n this.parent.moveCenter(this.options.position.x, this.options.position.y)\n }\n this.parent.emit('animate-end', this.parent)\n if (this.options.callbackOnComplete)\n {\n this.options.callbackOnComplete(this.parent)\n }\n }\n\n update(elapsed)\n {\n if (this.paused)\n {\n return\n }\n this.time += elapsed\n if (this.time >= this.options.time)\n {\n this.complete()\n }\n else\n {\n const originalZoom = new PIXI.Point(this.parent.scale.x, this.parent.scale.y)\n const percent = this.options.ease(this.time, 0, 1, this.options.time)\n if (this.width !== null)\n {\n this.parent.fitWidth(this.startWidth + this.deltaWidth * percent, this.keepCenter, this.height === null)\n }\n if (this.height !== null)\n {\n this.parent.fitHeight(this.startHeight + this.deltaHeight * percent, this.keepCenter, this.width === null)\n }\n if (this.width === null)\n {\n this.parent.scale.x = this.parent.scale.y\n }\n else if (this.height === null)\n {\n this.parent.scale.y = this.parent.scale.x\n }\n if (!this.keepCenter)\n {\n const original = new PIXI.Point(this.parent.x, this.parent.y)\n this.parent.moveCenter(this.startX + this.deltaX * percent, this.startY + this.deltaY * percent)\n this.parent.emit('moved', { viewport: this.parent, original, type: 'animate'})\n }\n if (this.width || this.height)\n {\n this.parent.emit('zoomed', { viewport: this.parent, original: originalZoom, type: 'animate' })\n }\n if (!this.keepCenter)\n {\n }\n }\n }\n}","import * as PIXI from 'pixi.js'\r\n\r\nimport { InputManager } from './input-manager'\r\nimport { PluginManager } from './plugin-manager'\r\nimport { Drag } from './plugins/drag'\r\nimport { Pinch } from './plugins/pinch'\r\nimport { Clamp } from './plugins/clamp'\r\nimport { ClampZoom } from './plugins/clamp-zoom'\r\nimport { Decelerate } from './plugins/decelerate'\r\nimport { Bounce } from './plugins/bounce'\r\nimport { Snap } from './plugins/snap'\r\nimport { SnapZoom } from './plugins/snap-zoom'\r\nimport { Follow } from './plugins/follow'\r\nimport { Wheel } from './plugins/wheel'\r\nimport { MouseEdges } from './plugins/mouse-edges'\r\nimport { Animate } from './plugins/animate'\r\nexport { Plugin } from './plugins/plugin'\r\n\r\n/**\r\n * @typedef {object} ViewportOptions\r\n * @property {number} [screenWidth=window.innerWidth]\r\n * @property {number} [screenHeight=window.innerHeight]\r\n * @property {number} [worldWidth=this.width]\r\n * @property {number} [worldHeight=this.height]\r\n * @property {number} [threshold=5] number of pixels to move to trigger an input event (e.g., drag, pinch) or disable a clicked event\r\n * @property {boolean} [passiveWheel=true] whether the 'wheel' event is set to passive (note: if false, e.preventDefault() will be called when wheel is used over the viewport)\r\n * @property {boolean} [stopPropagation=false] whether to stopPropagation of events that impact the viewport (except wheel events, see options.passiveWheel)\r\n * @property {HitArea} [forceHitArea] change the default hitArea from world size to a new value\r\n * @property {boolean} [noTicker] set this if you want to manually call update() function on each frame\r\n * @property {PIXI.Ticker} [ticker=PIXI.Ticker.shared] use this PIXI.ticker for updates\r\n * @property {PIXI.InteractionManager} [interaction=null] InteractionManager, available from instantiated WebGLRenderer/CanvasRenderer.plugins.interaction - used to calculate pointer postion relative to canvas location on screen\r\n * @property {HTMLElement} [divWheel=document.body] div to attach the wheel event\r\n * @property {boolean} [disableOnContextMenu] remove oncontextmenu=() => {} from the divWheel element\r\n */\r\n\r\nconst viewportOptions = {\r\n screenWidth: window.innerWidth,\r\n screenHeight: window.innerHeight,\r\n worldWidth: null,\r\n worldHeight: null,\r\n threshold: 5,\r\n passiveWheel: true,\r\n stopPropagation: false,\r\n forceHitArea: null,\r\n noTicker: false,\r\n interaction: null,\r\n disableOnContextMenu: false\r\n}\r\n\r\n/**\r\n * Main class to use when creating a Viewport\r\n */\r\nexport class Viewport extends PIXI.Container {\r\n /**\r\n * @param {ViewportOptions} [options]\r\n * @fires clicked\r\n * @fires drag-start\r\n * @fires drag-end\r\n * @fires drag-remove\r\n * @fires pinch-start\r\n * @fires pinch-end\r\n * @fires pinch-remove\r\n * @fires snap-start\r\n * @fires snap-end\r\n * @fires snap-remove\r\n * @fires snap-zoom-start\r\n * @fires snap-zoom-end\r\n * @fires snap-zoom-remove\r\n * @fires bounce-x-start\r\n * @fires bounce-x-end\r\n * @fires bounce-y-start\r\n * @fires bounce-y-end\r\n * @fires bounce-remove\r\n * @fires wheel\r\n * @fires wheel-remove\r\n * @fires wheel-scroll\r\n * @fires wheel-scroll-remove\r\n * @fires mouse-edge-start\r\n * @fires mouse-edge-end\r\n * @fires mouse-edge-remove\r\n * @fires moved\r\n * @fires moved-end\r\n * @fires zoomed\r\n * @fires zoomed-end\r\n * @fires frame-end\r\n */\r\n constructor(options = {}) {\r\n super()\r\n this.options = Object.assign({}, viewportOptions, options)\r\n\r\n // needed to pull this out of viewportOptions because of pixi.js v4 support (which changed from PIXI.ticker.shared to PIXI.Ticker.shared...sigh)\r\n if (options.ticker) {\r\n this.options.ticker = options.ticker\r\n }\r\n else {\r\n // to avoid Rollup transforming our import, save pixi namespace in a variable\r\n // from here: https://github.com/pixijs/pixi.js/issues/5757\r\n let ticker\r\n const pixiNS = PIXI\r\n if (parseInt(/^(\\d+)\\./.exec(PIXI.VERSION)[1]) < 5) {\r\n ticker = pixiNS.ticker.shared\r\n }\r\n else {\r\n ticker = pixiNS.Ticker.shared\r\n }\r\n this.options.ticker = options.ticker || ticker\r\n }\r\n\r\n /** @type {number} */\r\n this.screenWidth = this.options.screenWidth\r\n\r\n /** @type {number} */\r\n this.screenHeight = this.options.screenHeight\r\n\r\n this._worldWidth = this.options.worldWidth\r\n this._worldHeight = this.options.worldHeight\r\n this.forceHitArea = this.options.forceHitArea\r\n\r\n /**\r\n * number of pixels to move to trigger an input event (e.g., drag, pinch) or disable a clicked event\r\n * @type {number}\r\n */\r\n this.threshold = this.options.threshold\r\n\r\n this.options.divWheel = this.options.divWheel || document.body\r\n\r\n if (this.options.disableOnContextMenu) {\r\n this.options.divWheel.oncontextmenu = e => e.preventDefault()\r\n }\r\n\r\n if (!this.options.noTicker) {\r\n this.tickerFunction = () => this.update(this.options.ticker.elapsedMS)\r\n this.options.ticker.add(this.tickerFunction)\r\n }\r\n\r\n this.input = new InputManager(this)\r\n\r\n /**\r\n * Use this to add user plugins or access existing plugins (e.g., to pause, resume, or remove them)\r\n * @type {PluginManager}\r\n */\r\n this.plugins = new PluginManager(this)\r\n }\r\n\r\n /**\r\n * overrides PIXI.Container's destroy to also remove the 'wheel' and PIXI.Ticker listeners\r\n * @param {(object|boolean)} [options] - Options parameter. A boolean will act as if all options have been set to that value\r\n * @param {boolean} [options.children=false] - if set to true, all the children will have their destroy method called as well. 'options' will be passed on to those calls.\r\n * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true. Should it destroy the texture of the child sprite\r\n * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true. Should it destroy the base texture of the child sprite */\r\n destroy(options) {\r\n if (!this.options.noTicker) {\r\n this.options.ticker.remove(this.tickerFunction)\r\n }\r\n this.input.destroy()\r\n super.destroy(options)\r\n }\r\n\r\n /**\r\n * update viewport on each frame\r\n * by default, you do not need to call this unless you set options.noTicker=true\r\n * @param {number} elapsed time in milliseconds since last update\r\n */\r\n update(elapsed) {\r\n if (!this.pause) {\r\n this.plugins.update(elapsed)\r\n\r\n if (this.lastViewport) {\r\n // check for moved-end event\r\n if (this.lastViewport.x !== this.x || this.lastViewport.y !== this.y) {\r\n this.moving = true\r\n }\r\n else {\r\n if (this.moving) {\r\n this.emit('moved-end', this)\r\n this.moving = false\r\n }\r\n }\r\n // check for zoomed-end event\r\n if (this.lastViewport.scaleX !== this.scale.x || this.lastViewport.scaleY !== this.scale.y) {\r\n this.zooming = true\r\n }\r\n else {\r\n if (this.zooming) {\r\n this.emit('zoomed-end', this)\r\n this.zooming = false\r\n }\r\n }\r\n }\r\n\r\n if (!this.forceHitArea) {\r\n this._hitAreaDefault = new PIXI.Rectangle(this.left, this.top, this.worldScreenWidth, this.worldScreenHeight)\r\n this.hitArea = this._hitAreaDefault\r\n }\r\n\r\n this._dirty = this._dirty || !this.lastViewport ||\r\n this.lastViewport.x !== this.x || this.lastViewport.y !== this.y ||\r\n this.lastViewport.scaleX !== this.scale.x || this.lastViewport.scaleY !== this.scale.y\r\n\r\n this.lastViewport = {\r\n x: this.x,\r\n y: this.y,\r\n scaleX: this.scale.x,\r\n scaleY: this.scale.y\r\n }\r\n this.emit('frame-end', this)\r\n }\r\n }\r\n\r\n /**\r\n * use this to set screen and world sizes--needed for pinch/wheel/clamp/bounce\r\n * @param {number} [screenWidth=window.innerWidth]\r\n * @param {number} [screenHeight=window.innerHeight]\r\n * @param {number} [worldWidth]\r\n * @param {number} [worldHeight]\r\n */\r\n resize(screenWidth = window.innerWidth, screenHeight = window.innerHeight, worldWidth, worldHeight) {\r\n this.screenWidth = screenWidth\r\n this.screenHeight = screenHeight\r\n if (typeof worldWidth !== 'undefined') {\r\n this._worldWidth = worldWidth\r\n }\r\n if (typeof worldHeight !== 'undefined') {\r\n this._worldHeight = worldHeight\r\n }\r\n this.plugins.resize()\r\n this.dirty = true\r\n }\r\n\r\n /**\r\n * world width in pixels\r\n * @type {number}\r\n */\r\n get worldWidth() {\r\n if (this._worldWidth) {\r\n return this._worldWidth\r\n }\r\n else {\r\n return this.width / this.scale.x\r\n }\r\n }\r\n set worldWidth(value) {\r\n this._worldWidth = value\r\n this.plugins.resize()\r\n }\r\n\r\n /**\r\n * world height in pixels\r\n * @type {number}\r\n */\r\n get worldHeight() {\r\n if (this._worldHeight) {\r\n return this._worldHeight\r\n }\r\n else {\r\n return this.height / this.scale.y\r\n }\r\n }\r\n set worldHeight(value) {\r\n this._worldHeight = value\r\n this.plugins.resize()\r\n }\r\n\r\n /**\r\n * get visible bounds of viewport\r\n * @returns {PIXI.Rectangle}\r\n */\r\n getVisibleBounds() {\r\n return new PIXI.Rectangle(this.left, this.top, this.worldScreenWidth, this.worldScreenHeight)\r\n }\r\n\r\n /**\r\n * change coordinates from screen to world\r\n * @param {(number|PIXI.Point)} x or point\r\n * @param {number} [y]\r\n * @return {PIXI.Point}\r\n */\r\n toWorld(x, y) {\r\n if (arguments.length === 2) {\r\n return this.toLocal(new PIXI.Point(x, y))\r\n }\r\n else {\r\n return this.toLocal(x)\r\n }\r\n }\r\n\r\n /**\r\n * change coordinates from world to screen\r\n * @param {(number|PIXI.Point)} x or point\r\n * @param {number} [y]\r\n * @return {PIXI.Point}\r\n */\r\n toScreen(x, y) {\r\n if (arguments.length === 2) {\r\n return this.toGlobal(new PIXI.Point(x, y))\r\n }\r\n else {\r\n return this.toGlobal(x)\r\n }\r\n }\r\n\r\n /**\r\n * screen width in world coordinates\r\n * @type {number}\r\n */\r\n get worldScreenWidth() {\r\n return this.screenWidth / this.scale.x\r\n }\r\n\r\n /**\r\n * screen height in world coordinates\r\n * @type {number}\r\n */\r\n get worldScreenHeight() {\r\n return this.screenHeight / this.scale.y\r\n }\r\n\r\n /**\r\n * world width in screen coordinates\r\n * @type {number}\r\n */\r\n get screenWorldWidth() {\r\n return this.worldWidth * this.scale.x\r\n }\r\n\r\n /**\r\n * world height in screen coordinates\r\n * @type {number}\r\n */\r\n get screenWorldHeight() {\r\n return this.worldHeight * this.scale.y\r\n }\r\n\r\n /**\r\n * center of screen in world coordinates\r\n * @type {PIXI.Point}\r\n */\r\n get center() {\r\n return new PIXI.Point(this.worldScreenWidth / 2 - this.x / this.scale.x, this.worldScreenHeight / 2 - this.y / this.scale.y)\r\n }\r\n set center(value) {\r\n this.moveCenter(value)\r\n }\r\n\r\n /**\r\n * move center of viewport to point\r\n * @param {(number|PIXI.Point)} x or point\r\n * @param {number} [y]\r\n * @return {Viewport} this\r\n */\r\n moveCenter() {\r\n let x, y\r\n if (!isNaN(arguments[0])) {\r\n x = arguments[0]\r\n y = arguments[1]\r\n }\r\n else {\r\n x = arguments[0].x\r\n y = arguments[0].y\r\n }\r\n this.position.set((this.worldScreenWidth / 2 - x) * this.scale.x, (this.worldScreenHeight / 2 - y) * this.scale.y)\r\n this.plugins.reset()\r\n this.dirty = true\r\n return this\r\n }\r\n\r\n /**\r\n * top-left corner of Viewport\r\n * @type {PIXI.Point}\r\n */\r\n get corner() {\r\n return new PIXI.Point(-this.x / this.scale.x, -this.y / this.scale.y)\r\n }\r\n set corner(value) {\r\n this.moveCorner(value)\r\n }\r\n\r\n /**\r\n * move viewport's top-left corner; also clamps and resets decelerate and bounce (as needed)\r\n * @param {(number|PIXI.Point)} x or point\r\n * @param {number} [y]\r\n * @return {Viewport} this\r\n */\r\n moveCorner(x, y) {\r\n if (arguments.length === 1) {\r\n this.position.set(-x.x * this.scale.x, -x.y * this.scale.y)\r\n }\r\n else {\r\n this.position.set(-x * this.scale.x, -y * this.scale.y)\r\n }\r\n this.plugins.reset()\r\n return this\r\n }\r\n\r\n /**\r\n * get how many world pixels fit in screen's width\r\n * @type {number}\r\n */\r\n get screenWidthInWorldPixels() {\r\n return this.screenWidth / this.scale.x\r\n }\r\n\r\n /**\r\n * get how many world pixels fit on screen's height\r\n * @type {number}\r\n */\r\n get screenHeightInWorldPixels() {\r\n return this.screenHeight / this.scale.y\r\n }\r\n\r\n /**\r\n * find the scale value that fits a world width on the screen\r\n * does not change the viewport (use fit... to change)\r\n * @param {number} width in world pixels\r\n * @returns {number} scale\r\n */\r\n findFitWidth(width) {\r\n return this.screenWidth / width\r\n }\r\n\r\n /**\r\n * finds the scale value that fits a world height on the screens\r\n * does not change the viewport (use fit... to change)\r\n * @param {number} height in world pixels\r\n * @returns {number} scale\r\n */\r\n findFitHeight(height) {\r\n return this.screenHeight / height\r\n }\r\n\r\n /**\r\n * finds the scale value that fits the smaller of a world width and world height on the screen\r\n * does not change the viewport (use fit... to change)\r\n * @param {number} width in world pixels\r\n * @param {number} height in world pixels\r\n * @returns {number} scale\r\n */\r\n findFit(width, height) {\r\n const scaleX = this.screenWidth / width\r\n const scaleY = this.screenHeight / height\r\n return Math.min(scaleX, scaleY)\r\n }\r\n\r\n /**\r\n * finds the scale value that fits the larger of a world width and world height on the screen\r\n * does not change the viewport (use fit... to change)\r\n * @param {number} width in world pixels\r\n * @param {number} height in world pixels\r\n * @returns {number} scale\r\n */\r\n findCover(width, height) {\r\n const scaleX = this.screenWidth / width\r\n const scaleY = this.screenHeight / height\r\n return Math.max(scaleX, scaleY)\r\n }\r\n\r\n /**\r\n * change zoom so the width fits in the viewport\r\n * @param {number} [width=this.worldWidth] in world coordinates\r\n * @param {boolean} [center] maintain the same center\r\n * @param {boolean} [scaleY=true] whether to set scaleY=scaleX\r\n * @param {boolean} [noClamp] whether to disable clamp-zoom\r\n * @returns {Viewport} this\r\n */\r\n fitWidth(width, center, scaleY = true, noClamp) {\r\n let save\r\n if (center) {\r\n save = this.center\r\n }\r\n this.scale.x = this.screenWidth / width\r\n\r\n if (scaleY) {\r\n this.scale.y = this.scale.x\r\n }\r\n\r\n const clampZoom = this.plugins.get('clamp-zoom', true)\r\n if (!noClamp && clampZoom) {\r\n clampZoom.clamp()\r\n }\r\n\r\n if (center) {\r\n this.moveCenter(save)\r\n }\r\n return this\r\n }\r\n\r\n /**\r\n * change zoom so the height fits in the viewport\r\n * @param {number} [height=this.worldHeight] in world coordinates\r\n * @param {boolean} [center] maintain the same center of the screen after zoom\r\n * @param {boolean} [scaleX=true] whether to set scaleX = scaleY\r\n * @param {boolean} [noClamp] whether to disable clamp-zoom\r\n * @returns {Viewport} this\r\n */\r\n fitHeight(height, center, scaleX = true, noClamp) {\r\n let save\r\n if (center) {\r\n save = this.center\r\n }\r\n this.scale.y = this.screenHeight / height\r\n\r\n if (scaleX) {\r\n this.scale.x = this.scale.y\r\n }\r\n\r\n const clampZoom = this.plugins.get('clamp-zoom', true)\r\n if (!noClamp && clampZoom) {\r\n clampZoom.clamp()\r\n }\r\n\r\n if (center) {\r\n this.moveCenter(save)\r\n }\r\n return this\r\n }\r\n\r\n /**\r\n * change zoom so it fits the entire world in the viewport\r\n * @param {boolean} center maintain the same center of the screen after zoom\r\n * @returns {Viewport} this\r\n */\r\n fitWorld(center) {\r\n let save\r\n if (center) {\r\n save = this.center\r\n }\r\n this.scale.x = this.screenWidth / this.worldWidth\r\n this.scale.y = this.screenHeight / this.worldHeight\r\n if (this.scale.x < this.scale.y) {\r\n this.scale.y = this.scale.x\r\n }\r\n else {\r\n this.scale.x = this.scale.y\r\n }\r\n\r\n const clampZoom = this.plugins.get('clamp-zoom', true)\r\n if (clampZoom) {\r\n clampZoom.clamp()\r\n }\r\n\r\n if (center) {\r\n this.moveCenter(save)\r\n }\r\n return this\r\n }\r\n\r\n /**\r\n * change zoom so it fits the size or the entire world in the viewport\r\n * @param {boolean} [center] maintain the same center of the screen after zoom\r\n * @param {number} [width=this.worldWidth] desired width\r\n * @param {number} [height=this.worldHeight] desired height\r\n * @returns {Viewport} this\r\n */\r\n fit(center, width = this.worldWidth, height = this.worldHeight) {\r\n let save\r\n if (center) {\r\n save = this.center\r\n }\r\n this.scale.x = this.screenWidth / width\r\n this.scale.y = this.screenHeight / height\r\n if (this.scale.x < this.scale.y) {\r\n this.scale.y = this.scale.x\r\n }\r\n else {\r\n this.scale.x = this.scale.y\r\n }\r\n const clampZoom = this.plugins.get('clamp-zoom', true)\r\n if (clampZoom) {\r\n clampZoom.clamp()\r\n }\r\n if (center) {\r\n this.moveCenter(save)\r\n }\r\n return this\r\n }\r\n\r\n set visible(value) {\r\n if (!value) {\r\n this.input.clear()\r\n }\r\n super.visible = value\r\n }\r\n\r\n /**\r\n * zoom viewport to specific value\r\n * @param {number} scale value (e.g., 1 would be 100%, 0.25 would be 25%)\r\n * @param {boolean} [center] maintain the same center of the screen after zoom\r\n * @return {Viewport} this\r\n */\r\n setZoom(scale, center) {\r\n let save\r\n if (center) {\r\n save = this.center\r\n }\r\n this.scale.set(scale)\r\n const clampZoom = this.plugins.get('clamp-zoom', true)\r\n if (clampZoom) {\r\n clampZoom.clamp()\r\n }\r\n if (center) {\r\n this.moveCenter(save)\r\n }\r\n return this\r\n }\r\n\r\n /**\r\n * zoom viewport by a certain percent (in both x and y direction)\r\n * @param {number} percent change (e.g., 0.25 would increase a starting scale of 1.0 to 1.25)\r\n * @param {boolean} [center] maintain the same center of the screen after zoom\r\n * @return {Viewport} this\r\n */\r\n zoomPercent(percent, center) {\r\n return this.setZoom(this.scale.x + this.scale.x * percent, center)\r\n }\r\n\r\n /**\r\n * zoom viewport by increasing/decreasing width by a certain number of pixels\r\n * @param {number} change in pixels\r\n * @param {boolean} [center] maintain the same center of the screen after zoom\r\n * @return {Viewport} this\r\n */\r\n zoom(change, center) {\r\n this.fitWidth(change + this.worldScreenWidth, center)\r\n return this\r\n }\r\n\r\n /**\r\n * changes scale of viewport and maintains center of viewport\r\n * @type {number}\r\n */\r\n set scaled(scale) {\r\n this.setZoom(scale, true)\r\n }\r\n get scaled() {\r\n return this.scale.x\r\n }\r\n\r\n /**\r\n * @param {SnapZoomOptions} options\r\n */\r\n snapZoom(options) {\r\n this.plugins.add('snap-zoom', new SnapZoom(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * is container out of world bounds\r\n * @returns {OutOfBounds}\r\n */\r\n OOB() {\r\n return {\r\n left: this.left < 0,\r\n right: this.right > this.worldWidth,\r\n top: this.top < 0,\r\n bottom: this.bottom > this._worldHeight,\r\n cornerPoint: new PIXI.Point(\r\n this.worldWidth * this.scale.x - this.screenWidth,\r\n this.worldHeight * this.scale.y - this.screenHeight\r\n )\r\n }\r\n }\r\n\r\n /**\r\n * world coordinates of the right edge of the screen\r\n * @type {number}\r\n */\r\n get right() {\r\n return -this.x / this.scale.x + this.worldScreenWidth\r\n }\r\n set right(value) {\r\n this.x = -value * this.scale.x + this.screenWidth\r\n this.plugins.reset()\r\n }\r\n\r\n /**\r\n * world coordinates of the left edge of the screen\r\n * @type { number }\r\n */\r\n get left() {\r\n return -this.x / this.scale.x\r\n }\r\n set left(value) {\r\n this.x = -value * this.scale.x\r\n this.plugins.reset()\r\n }\r\n\r\n /**\r\n * world coordinates of the top edge of the screen\r\n * @type {number}\r\n */\r\n get top() {\r\n return -this.y / this.scale.y\r\n }\r\n set top(value) {\r\n this.y = -value * this.scale.y\r\n this.plugins.reset()\r\n }\r\n\r\n /**\r\n * world coordinates of the bottom edge of the screen\r\n * @type {number}\r\n */\r\n get bottom() {\r\n return -this.y / this.scale.y + this.worldScreenHeight\r\n }\r\n set bottom(value) {\r\n this.y = -value * this.scale.y + this.screenHeight\r\n this.plugins.reset()\r\n }\r\n\r\n /**\r\n * determines whether the viewport is dirty (i.e., needs to be renderered to the screen because of a change)\r\n * @type {boolean}\r\n */\r\n get dirty() {\r\n return this._dirty\r\n }\r\n set dirty(value) {\r\n this._dirty = value\r\n }\r\n\r\n /**\r\n * permanently changes the Viewport's hitArea\r\n * NOTE: if not set then hitArea = PIXI.Rectangle(Viewport.left, Viewport.top, Viewport.worldScreenWidth, Viewport.worldScreenHeight)\r\n * @returns {HitArea}\r\n */\r\n get forceHitArea() {\r\n return this._forceHitArea\r\n }\r\n set forceHitArea(value) {\r\n if (value) {\r\n this._forceHitArea = value\r\n this.hitArea = value\r\n }\r\n else {\r\n this._forceHitArea = null\r\n this.hitArea = new PIXI.Rectangle(0, 0, this.worldWidth, this.worldHeight)\r\n }\r\n }\r\n\r\n /**\r\n * enable one-finger touch to drag\r\n * NOTE: if you expect users to use right-click dragging, you should enable viewport.options.disableOnContextMenu to avoid the context menu popping up on each right-click drag\r\n * @param {DragOptions} [options]\r\n * @returns {Viewport} this\r\n */\r\n drag(options) {\r\n this.plugins.add('drag', new Drag(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * clamp to world boundaries or other provided boundaries\r\n * NOTES:\r\n * clamp is disabled if called with no options; use { direction: 'all' } for all edge clamping\r\n * screenWidth, screenHeight, worldWidth, and worldHeight needs to be set for this to work properly\r\n * @param {ClampOptions} [options]\r\n * @returns {Viewport} this\r\n */\r\n clamp(options) {\r\n this.plugins.add('clamp', new Clamp(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * decelerate after a move\r\n * NOTE: this fires 'moved' event during deceleration\r\n * @param {DecelerateOptions} [options]\r\n * @return {Viewport} this\r\n */\r\n decelerate(options) {\r\n this.plugins.add('decelerate', new Decelerate(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * bounce on borders\r\n * NOTES:\r\n * screenWidth, screenHeight, worldWidth, and worldHeight needs to be set for this to work properly\r\n * fires 'moved', 'bounce-x-start', 'bounce-y-start', 'bounce-x-end', and 'bounce-y-end' events\r\n * @param {object} [options]\r\n * @param {string} [options.sides=all] all, horizontal, vertical, or combination of top, bottom, right, left (e.g., 'top-bottom-right')\r\n * @param {number} [options.friction=0.5] friction to apply to decelerate if active\r\n * @param {number} [options.time=150] time in ms to finish bounce\r\n * @param {object} [options.bounceBox] use this bounceBox instead of (0, 0, viewport.worldWidth, viewport.worldHeight)\r\n * @param {number} [options.bounceBox.x=0]\r\n * @param {number} [options.bounceBox.y=0]\r\n * @param {number} [options.bounceBox.width=viewport.worldWidth]\r\n * @param {number} [options.bounceBox.height=viewport.worldHeight]\r\n * @param {string|function} [options.ease=easeInOutSine] ease function or name (see http://easings.net/ for supported names)\r\n * @param {string} [options.underflow=center] (top/bottom/center and left/right/center, or center) where to place world if too small for screen\r\n * @return {Viewport} this\r\n */\r\n bounce(options) {\r\n this.plugins.add('bounce', new Bounce(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * enable pinch to zoom and two-finger touch to drag\r\n * @param {PinchOptions} [options]\r\n * @return {Viewport} this\r\n */\r\n pinch(options) {\r\n this.plugins.add('pinch', new Pinch(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * snap to a point\r\n * @param {number} x\r\n * @param {number} y\r\n * @param {SnapOptions} [options]\r\n * @return {Viewport} this\r\n */\r\n snap(x, y, options) {\r\n this.plugins.add('snap', new Snap(this, x, y, options))\r\n return this\r\n }\r\n\r\n /**\r\n * follow a target\r\n * NOTES:\r\n * uses the (x, y) as the center to follow; for PIXI.Sprite to work properly, use sprite.anchor.set(0.5)\r\n * options.acceleration is not perfect as it doesn't know the velocity of the target\r\n * it adds acceleration to the start of movement and deceleration to the end of movement when the target is stopped\r\n * fires 'moved' event\r\n * @param {PIXI.DisplayObject} target to follow\r\n * @param {FollowOptions} [options]\r\n * @returns {Viewport} this\r\n */\r\n follow(target, options) {\r\n this.plugins.add('follow', new Follow(this, target, options))\r\n return this\r\n }\r\n\r\n /**\r\n * zoom using mouse wheel\r\n * @param {WheelOptions} [options]\r\n * @return {Viewport} this\r\n */\r\n wheel(options) {\r\n this.plugins.add('wheel', new Wheel(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * animate the position and/or scale of the viewport\r\n * @param {AnimateOptions} options\r\n * @returns {Viewport} this\r\n */\r\n animate(options) {\r\n this.plugins.add('animate', new Animate(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * enable clamping of zoom to constraints\r\n * @description\r\n * The minWidth/Height settings are how small the world can get (as it would appear on the screen)\r\n * before clamping. The maxWidth/maxHeight is how larger the world can scale (as it would appear on\r\n * the screen) before clamping.\r\n *\r\n * For example, if you have a world size of 1000 x 1000 and a screen size of 100 x 100, if you set\r\n * minWidth/Height = 100 then the world will not be able to zoom smaller than the screen size (ie,\r\n * zooming out so it appears smaller than the screen). Similarly, if you set maxWidth/Height = 100\r\n * the world will not be able to zoom larger than the screen size (ie, zooming in so it appears\r\n * larger than the screen).\r\n * @param {ClampZoomOptions} [options]\r\n * @return {Viewport} this\r\n */\r\n clampZoom(options) {\r\n this.plugins.add('clamp-zoom', new ClampZoom(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * Scroll viewport when mouse hovers near one of the edges or radius-distance from center of screen.\r\n * NOTE: fires 'moved' event\r\n * @param {MouseEdgesOptions} [options]\r\n */\r\n mouseEdges(options) {\r\n this.plugins.add('mouse-edges', new MouseEdges(this, options))\r\n return this\r\n }\r\n\r\n /**\r\n * pause viewport (including animation updates such as decelerate)\r\n * @type {boolean}\r\n */\r\n get pause() {\r\n return this._pause\r\n }\r\n set pause(value) {\r\n this._pause = value\r\n this.lastViewport = null\r\n this.moving = false\r\n this.zooming = false\r\n if (value) {\r\n this.input.pause()\r\n }\r\n }\r\n\r\n /**\r\n * move the viewport so the bounding box is visible\r\n * @param {number} x - left\r\n * @param {number} y - top\r\n * @param {number} width\r\n * @param {number} height\r\n * @param {boolean} [resizeToFit] resize the viewport so the box fits within the viewport\r\n */\r\n ensureVisible(x, y, width, height, resizeToFit) {\r\n if (resizeToFit && (width > this.worldScreenWidth || height > this.worldScreenHeight)) {\r\n this.fit(true, width, height)\r\n this.emit('zoomed', { viewport: this, type: 'ensureVisible' })\r\n }\r\n let moved = false\r\n if (x < this.left) {\r\n this.left = x\r\n moved = true\r\n }\r\n else if (x + width > this.right) {\r\n this.right = x + width\r\n moved = true\r\n }\r\n if (y < this.top) {\r\n this.top = y\r\n moved = true\r\n }\r\n else if (y + height > this.bottom) {\r\n this.bottom = y + height\r\n moved = true\r\n }\r\n if (moved) {\r\n this.emit('moved', { viewport: this, type: 'ensureVisible' })\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * fires after a mouse or touch click\r\n * @event Viewport#clicked\r\n * @type {object}\r\n * @property {PIXI.Point} screen\r\n * @property {PIXI.Point} world\r\n * @property {Viewport} viewport\r\n */\r\n\r\n/**\r\n * fires when a drag starts\r\n * @event Viewport#drag-start\r\n * @type {object}\r\n * @property {PIXI.Point} screen\r\n * @property {PIXI.Point} world\r\n * @property {Viewport} viewport\r\n */\r\n\r\n/**\r\n * fires when a drag ends\r\n * @event Viewport#drag-end\r\n * @type {object}\r\n * @property {PIXI.Point} screen\r\n * @property {PIXI.Point} world\r\n * @property {Viewport} viewport\r\n */\r\n\r\n/**\r\n * fires when a pinch starts\r\n * @event Viewport#pinch-start\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a pinch end\r\n * @event Viewport#pinch-end\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a snap starts\r\n * @event Viewport#snap-start\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a snap ends\r\n * @event Viewport#snap-end\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a snap-zoom starts\r\n * @event Viewport#snap-zoom-start\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a snap-zoom ends\r\n * @event Viewport#snap-zoom-end\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a bounce starts in the x direction\r\n * @event Viewport#bounce-x-start\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a bounce ends in the x direction\r\n * @event Viewport#bounce-x-end\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a bounce starts in the y direction\r\n * @event Viewport#bounce-y-start\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a bounce ends in the y direction\r\n * @event Viewport#bounce-y-end\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when for a mouse wheel event\r\n * @event Viewport#wheel\r\n * @type {object}\r\n * @property {object} wheel\r\n * @property {number} wheel.dx\r\n * @property {number} wheel.dy\r\n * @property {number} wheel.dz\r\n * @property {Viewport} viewport\r\n */\r\n\r\n/**\r\n * fires when a wheel-scroll occurs\r\n * @event Viewport#wheel-scroll\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when a mouse-edge starts to scroll\r\n * @event Viewport#mouse-edge-start\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when the mouse-edge scrolling ends\r\n * @event Viewport#mouse-edge-end\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when viewport moves through UI interaction, deceleration, ensureVisible, or follow\r\n * @event Viewport#moved\r\n * @type {object}\r\n * @property {Viewport} viewport\r\n * @property {string} type (drag, snap, pinch, follow, bounce-x, bounce-y, clamp-x, clamp-y, decelerate, mouse-edges, wheel, ensureVisible)\r\n */\r\n\r\n/**\r\n * fires when viewport moves through UI interaction, deceleration, ensureVisible, or follow\r\n * @event Viewport#zoomed\r\n * @type {object}\r\n * @property {Viewport} viewport\r\n * @property {string} type (drag-zoom, pinch, wheel, clamp-zoom, ensureVisible)\r\n */\r\n\r\n/**\r\n * fires when viewport stops moving\r\n * @event Viewport#moved-end\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n * fires when viewport stops zooming\r\n * @event Viewport#zoomed-end\r\n * @type {Viewport}\r\n */\r\n\r\n/**\r\n* fires at the end of an update frame\r\n* @event Viewport#frame-end\r\n* @type {Viewport}\r\n*/\r\n\r\n/** @typedef HitArea {(PIXI.Rectangle | PIXI.Circle | PIXI.Ellipse | PIXI.Polygon | PIXI.RoundedRectangle)} */\r\n\r\n/**\r\n * @typedef {Object} OutOfBounds\r\n * @private\r\n * @property {boolean} left\r\n * @property {boolean} right\r\n * @property {boolean} top\r\n * @property {boolean} bottom\r\n * @property {PIXI.Point} cornerPoint\r\n */\r\n\r\n/**\r\n * @typedef {Object} LastViewport\r\n * @private\r\n * @property {number} x\r\n * @property {number} y\r\n * @property {number} scaleX\r\n * @property {number} scaleY\r\n */"],"names":["InputManager","[object Object]","viewport","this","touches","addListeners","interactive","forceHitArea","hitArea","PIXI.Rectangle","worldWidth","worldHeight","on","down","move","up","wheelFunction","e","handleWheel","options","divWheel","addEventListener","passive","passiveWheel","isMouseDown","removeEventListener","event","pause","worldVisible","data","pointerType","get","pointerId","push","id","last","count","global","clone","decelerate","plugins","bounce","isActive","clickedAvailable","stopPropagation","change","Math","abs","threshold","stop","distX","x","distY","y","checkThreshold","remove","emit","screen","world","toWorld","point","PIXI.Point","interaction","mapPositionToPoint","clientX","clientY","toLocal","getPointerPosition","left","right","top","bottom","wheel","preventDefault","touch","i","length","splice","PLUGIN_ORDER","PluginManager","list","name","plugin","index","current","indexOf","sort","ignorePaused","paused","elapsed","update","resize","reset","resume","result","Plugin","parent","dragOptions","direction","pressDrag","wheelScroll","reverse","clampWheel","underflow","factor","mouseButtons","keyToPress","ignoreKeyToPressOnTouch","Drag","super","Object","assign","moved","xDirection","yDirection","keyIsPressed","parseUnderflow","handleKeyPresses","codes","includes","code","buttons","mouse","clamp","toLowerCase","underflowX","underflowY","isMouse","input","button","checkButtons","checkKeyPress","active","newPoint","type","pointer","deltaX","deltaY","screenWorldWidth","screenWidth","scale","screenWorldHeight","screenHeight","pinchOptions","noDrag","percent","center","Pinch","pointers","first","second","sqrt","pow","oldPoint","dist","moveCenter","toGlobal","lastCenter","pinching","clampOptions","Clamp","scaleX","scaleY","noUnderflow","original","clampZoomOptions","minWidth","minHeight","maxWidth","maxHeight","minScale","maxScale","ClampZoom","width","worldScreenWidth","height","worldScreenHeight","fitWidth","fitHeight","set","decelerateOptions","friction","minSpeed","TP","Decelerate","saved","timeSinceRelease","time","performance","now","save","percentChangeX","percentChangeY","ti","tf","k","lnk","log","penner","factory","module","umd","linear","t","b","c","d","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInSine","cos","PI","easeOutSine","sin","easeInOutSine","easeInExpo","easeOutExpo","easeInOutExpo","easeInCirc","easeOutCirc","easeInOutCirc","easeInElastic","a","p","s","asin","easeOutElastic","easeInOutElastic","easeInBack","easeOutBack","easeInOutBack","easeInBounce","easeOutBounce","easeInOutBounce","call","ease","defaults","Penner","bounceOptions","sides","bounceBox","Bounce","toX","toY","end","start","delta","box","x1","y1","topLeft","bottomRight","oob","drag","pinch","calcUnderflowX","calcUnderflowY","snapOptions","interrupt","removeOnComplete","removeOnInterrupt","forceStart","Snap","snapStart","snapping","corner","startX","startY","finished","moveCorner","snapZoomOptions","removeOnInterrupts","noMove","SnapZoom","xScale","yScale","xIndependent","yIndependent","container","createSnapping","startWorldScreenWidth","startWorldScreenHeight","endWorldScreenWidth","endWorldScreenHeight","oldCenter","followOptions","speed","acceleration","radius","Follow","target","velocity","angle","atan2","distance","decelerationDistance","min","max","changeX","changeY","wheelOptions","smooth","lineHeight","Wheel","smoothing","smoothingCenter","smoothingCount","step","deltaMode","dx","dy","dz","deltaZ","mouseEdgesOptions","noDecelerate","allowButtons","MouseEdges","radiusSquared","horizontal","vertical","identifier","toScreen","round","decelerateHorizontal","decelerateVertical","activate","animateOptions","Animate","setupPosition","setupZoom","position","keepCenter","startWidth","screenWidthInWorldPixels","deltaWidth","startHeight","screenHeightInWorldPixels","deltaHeight","callbackOnComplete","complete","originalZoom","viewportOptions","window","innerWidth","innerHeight","noTicker","disableOnContextMenu","Viewport","PIXI.Container","ticker","pixiNS","PIXI","parseInt","exec","PIXI.VERSION","shared","Ticker","_worldWidth","_worldHeight","document","body","oncontextmenu","tickerFunction","elapsedMS","add","destroy","lastViewport","moving","zooming","_hitAreaDefault","_dirty","dirty","value","arguments","isNaN","noClamp","clampZoom","visible","clear","setZoom","scaled","cornerPoint","_forceHitArea","_pause","resizeToFit","fit"],"mappings":"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"}