UNPKG

129 kBJavaScriptView Raw
1/*
2Copyright (c) NAVER Corp.
3name: @egjs/axes
4license: MIT
5author: NAVER Corp.
6repository: https://github.com/naver/egjs-axes
7version: 3.8.3
8*/
9'use strict';
10
11var getAgent = require('@egjs/agent');
12var Component = require('@egjs/component');
13var core = require('@cfcs/core');
14
15/*! *****************************************************************************
16Copyright (c) Microsoft Corporation. All rights reserved.
17Licensed under the Apache License, Version 2.0 (the "License"); you may not use
18this file except in compliance with the License. You may obtain a copy of the
19License at http://www.apache.org/licenses/LICENSE-2.0
20
21THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
23WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
24MERCHANTABLITY OR NON-INFRINGEMENT.
25
26See the Apache Version 2.0 License for specific language governing permissions
27and limitations under the License.
28***************************************************************************** */
29
30/* global Reflect, Promise */
31var extendStatics = function (d, b) {
32 extendStatics = Object.setPrototypeOf || {
33 __proto__: []
34 } instanceof Array && function (d, b) {
35 d.__proto__ = b;
36 } || function (d, b) {
37 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
38 };
39
40 return extendStatics(d, b);
41};
42
43function __extends(d, b) {
44 extendStatics(d, b);
45
46 function __() {
47 this.constructor = d;
48 }
49
50 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
51}
52var __assign = function () {
53 __assign = Object.assign || function __assign(t) {
54 for (var s, i = 1, n = arguments.length; i < n; i++) {
55 s = arguments[i];
56
57 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
58 }
59
60 return t;
61 };
62
63 return __assign.apply(this, arguments);
64};
65function __decorate(decorators, target, key, desc) {
66 var c = arguments.length,
67 r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
68 d;
69 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
70 return c > 3 && r && Object.defineProperty(target, key, r), r;
71}
72
73/*
74 * Copyright (c) 2015 NAVER Corp.
75 * egjs projects are licensed under the MIT license
76 */
77
78/* eslint-disable no-new-func, no-nested-ternary */
79var win;
80
81if (typeof window === "undefined") {
82 // window is undefined in node.js
83 win = {
84 navigator: {
85 userAgent: ""
86 }
87 };
88} else {
89 win = window;
90}
91
92/*
93 * Copyright (c) 2015 NAVER Corp.
94 * egjs projects are licensed under the MIT license
95 */
96var DIRECTION_NONE = 1;
97var DIRECTION_LEFT = 2;
98var DIRECTION_RIGHT = 4;
99var DIRECTION_HORIZONTAL = 2 | 4;
100var DIRECTION_UP = 8;
101var DIRECTION_DOWN = 16;
102var DIRECTION_VERTICAL = 8 | 16;
103var DIRECTION_ALL = 2 | 4 | 8 | 16;
104var MOUSE_LEFT = "left";
105var MOUSE_RIGHT = "right";
106var MOUSE_MIDDLE = "middle";
107var ANY = "any";
108var NONE = "none";
109var SHIFT = "shift";
110var CTRL = "ctrl";
111var ALT = "alt";
112var META = "meta";
113var VELOCITY_INTERVAL = 16;
114var AXES_METHODS = ["connect", "disconnect", "get", "setTo", "setBy", "setOptions", "setAxis", "stopAnimation", "updateAnimation", "isBounceArea"];
115var AXES_EVENTS = ["hold", "release", "change", "animationStart", "animationEnd", "finish"];
116var IOS_EDGE_THRESHOLD = 30;
117var IS_IOS_SAFARI = "ontouchstart" in win && getAgent().browser.name === "safari";
118var TRANSFORM = function () {
119 if (typeof document === "undefined") {
120 return "";
121 }
122
123 var bodyStyle = (document.head || document.getElementsByTagName("head")[0]).style;
124 var target = ["transform", "webkitTransform", "msTransform", "mozTransform"];
125
126 for (var i = 0, len = target.length; i < len; i++) {
127 if (target[i] in bodyStyle) {
128 return target[i];
129 }
130 }
131
132 return "";
133}();
134var PREVENT_DRAG_CSSPROPS = {
135 "user-select": "none",
136 "-webkit-user-drag": "none"
137};
138
139var toArray = function (nodes) {
140 // const el = Array.prototype.slice.call(nodes);
141 // for IE8
142 var el = [];
143
144 for (var i = 0, len = nodes.length; i < len; i++) {
145 el.push(nodes[i]);
146 }
147
148 return el;
149};
150var $ = function (param, multi) {
151 if (multi === void 0) {
152 multi = false;
153 }
154
155 var el;
156
157 if (typeof param === "string") {
158 // String (HTML, Selector)
159 // check if string is HTML tag format
160 var match = param.match(/^<([a-z]+)\s*([^>]*)>/); // creating element
161
162 if (match) {
163 // HTML
164 var dummy = document.createElement("div");
165 dummy.innerHTML = param;
166 el = toArray(dummy.childNodes);
167 } else {
168 // Selector
169 el = toArray(document.querySelectorAll(param));
170 }
171
172 if (!multi) {
173 el = el.length >= 1 ? el[0] : undefined;
174 }
175 } else if (param === win) {
176 // window
177 el = param;
178 } else if ("value" in param || "current" in param) {
179 el = param.value || param.current;
180 } else if (param.nodeName && (param.nodeType === 1 || param.nodeType === 9)) {
181 // HTMLElement, Document
182 el = param;
183 } else if ("jQuery" in win && param instanceof jQuery || param.constructor.prototype.jquery) {
184 // jQuery
185 el = multi ? param.toArray() : param.get(0);
186 } else if (Array.isArray(param)) {
187 el = param.map(function (v) {
188 return $(v);
189 });
190
191 if (!multi) {
192 el = el.length >= 1 ? el[0] : undefined;
193 }
194 }
195
196 return el;
197};
198var raf = win.requestAnimationFrame || win.webkitRequestAnimationFrame;
199var caf = win.cancelAnimationFrame || win.webkitCancelAnimationFrame;
200
201if (raf && !caf) {
202 var keyInfo_1 = {};
203 var oldraf_1 = raf;
204
205 raf = function (callback) {
206 var wrapCallback = function (timestamp) {
207 if (keyInfo_1[key]) {
208 callback(timestamp);
209 }
210 };
211
212 var key = oldraf_1(wrapCallback);
213 keyInfo_1[key] = true;
214 return key;
215 };
216
217 caf = function (key) {
218 delete keyInfo_1[key];
219 };
220} else if (!(raf && caf)) {
221 raf = function (callback) {
222 return win.setTimeout(function () {
223 callback(win.performance && win.performance.now && win.performance.now() || new Date().getTime());
224 }, 16);
225 };
226
227 caf = win.clearTimeout;
228}
229/**
230 * A polyfill for the window.requestAnimationFrame() method.
231 * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
232 * @private
233 */
234
235
236var requestAnimationFrame = function (fp) {
237 return raf(fp);
238};
239/**
240 * A polyfill for the window.cancelAnimationFrame() method. It cancels an animation executed through a call to the requestAnimationFrame() method.
241 * @param {Number} key − The ID value returned through a call to the requestAnimationFrame() method. <ko>requestAnimationFrame() 메서드가 반환한 아이디 값</ko>
242 * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame
243 * @private
244 */
245
246var cancelAnimationFrame = function (key) {
247 caf(key);
248};
249var map = function (obj, callback) {
250 var tranformed = {};
251
252 for (var k in obj) {
253 if (k) {
254 tranformed[k] = callback(obj[k], k);
255 }
256 }
257
258 return tranformed;
259};
260var filter = function (obj, callback) {
261 var filtered = {};
262
263 for (var k in obj) {
264 if (k && callback(obj[k], k)) {
265 filtered[k] = obj[k];
266 }
267 }
268
269 return filtered;
270};
271var every = function (obj, callback) {
272 for (var k in obj) {
273 if (k && !callback(obj[k], k)) {
274 return false;
275 }
276 }
277
278 return true;
279};
280var equal = function (target, base) {
281 return every(target, function (v, k) {
282 return v === base[k];
283 });
284};
285var roundNumFunc = {};
286var roundNumber = function (num, roundUnit) {
287 // Cache for performance
288 if (!roundNumFunc[roundUnit]) {
289 roundNumFunc[roundUnit] = getRoundFunc(roundUnit);
290 }
291
292 return roundNumFunc[roundUnit](num);
293};
294var roundNumbers = function (num, roundUnit) {
295 if (!num || !roundUnit) {
296 return num;
297 }
298
299 return map(num, function (value, key) {
300 return roundNumber(value, typeof roundUnit === "number" ? roundUnit : roundUnit[key]);
301 });
302};
303var getDecimalPlace = function (val) {
304 if (!isFinite(val)) {
305 return 0;
306 }
307
308 var v = "".concat(val);
309
310 if (v.indexOf("e") >= 0) {
311 // Exponential Format
312 // 1e-10, 1e-12
313 var p = 0;
314 var e = 1;
315
316 while (Math.round(val * e) / e !== val) {
317 e *= 10;
318 p++;
319 }
320
321 return p;
322 } // In general, following has performance benefit.
323 // https://jsperf.com/precision-calculation
324
325
326 return v.indexOf(".") >= 0 ? v.length - v.indexOf(".") - 1 : 0;
327};
328var inversePow = function (n) {
329 // replace Math.pow(10, -n) to solve floating point issue.
330 // eg. Math.pow(10, -4) => 0.00009999999999999999
331 return 1 / Math.pow(10, n);
332};
333var getRoundFunc = function (v) {
334 var p = v < 1 ? Math.pow(10, getDecimalPlace(v)) : 1;
335 return function (n) {
336 if (v === 0) {
337 return 0;
338 }
339
340 return Math.round(Math.round(n / v) * v * p) / p;
341 };
342};
343var getAngle = function (posX, posY) {
344 return Math.atan2(posY, posX) * 180 / Math.PI;
345};
346var isCssPropsFromAxes = function (originalCssProps) {
347 var same = true;
348 Object.keys(PREVENT_DRAG_CSSPROPS).forEach(function (prop) {
349 if (!originalCssProps || originalCssProps[prop] !== PREVENT_DRAG_CSSPROPS[prop]) {
350 same = false;
351 }
352 });
353 return same;
354};
355var getDirection = function (useHorizontal, useVertical) {
356 if (useHorizontal && useVertical) {
357 return DIRECTION_ALL;
358 } else if (useHorizontal) {
359 return DIRECTION_HORIZONTAL;
360 } else if (useVertical) {
361 return DIRECTION_VERTICAL;
362 } else {
363 return DIRECTION_NONE;
364 }
365};
366var useDirection = function (checkType, direction, userDirection) {
367 if (userDirection) {
368 return !!(direction === DIRECTION_ALL || direction & checkType && userDirection & checkType);
369 } else {
370 return !!(direction & checkType);
371 }
372};
373var setCssProps = function (element, option, direction) {
374 var _a;
375
376 var touchActionMap = (_a = {}, _a[DIRECTION_NONE] = "auto", _a[DIRECTION_ALL] = "none", _a[DIRECTION_VERTICAL] = "pan-x", _a[DIRECTION_HORIZONTAL] = "pan-y", _a);
377 var oldCssProps = {};
378
379 if (element && element.style) {
380 var touchAction = option.touchAction ? option.touchAction : touchActionMap[direction];
381
382 var newCssProps_1 = __assign(__assign({}, PREVENT_DRAG_CSSPROPS), {
383 "touch-action": element.style["touch-action"] === "none" ? "none" : touchAction
384 });
385
386 Object.keys(newCssProps_1).forEach(function (prop) {
387 oldCssProps[prop] = element.style[prop];
388 element.style[prop] = newCssProps_1[prop];
389 });
390 }
391
392 return oldCssProps;
393};
394var revertCssProps = function (element, originalCssProps) {
395 if (element && element.style && originalCssProps) {
396 Object.keys(originalCssProps).forEach(function (prop) {
397 element.style[prop] = originalCssProps[prop];
398 });
399 }
400
401 return;
402};
403
404var EventManager =
405/*#__PURE__*/
406function () {
407 function EventManager(_axes) {
408 this._axes = _axes;
409 }
410 /**
411 * This event is fired when a user holds an element on the screen of the device.
412 * @ko 사용자가 기기의 화면에 손을 대고 있을 때 발생하는 이벤트
413 * @event Axes#hold
414 * @type {object}
415 * @property {Object.<string, number>} pos coordinate <ko>좌표 정보</ko>
416 * @property {Object} input The instance of inputType where the event occurred<ko>이벤트가 발생한 inputType 인스턴스</ko>
417 * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko>
418 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
419 *
420 * @example
421 * ```js
422 * const axes = new eg.Axes({
423 * "x": {
424 * range: [0, 100]
425 * },
426 * "zoom": {
427 * range: [50, 30]
428 * }
429 * }).on("hold", function(event) {
430 * // event.pos
431 * // event.input
432 * // event.inputEvent
433 * // isTrusted
434 * });
435 * ```
436 */
437
438
439 var __proto = EventManager.prototype;
440
441 __proto.hold = function (pos, option) {
442 var roundPos = this._getRoundPos(pos).roundPos;
443
444 this._axes.trigger(new Component.ComponentEvent("hold", {
445 pos: roundPos,
446 input: option.input || null,
447 inputEvent: option.event || null,
448 isTrusted: true
449 }));
450 };
451 /**
452 * Specifies the coordinates to move after the 'change' event. It works when the holding value of the change event is true.
453 * @ko 'change' 이벤트 이후 이동할 좌표를 지정한다. change이벤트의 holding 값이 true일 경우에 동작한다
454 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko>
455 * @example
456 * ```js
457 * const axes = new eg.Axes({
458 * "x": {
459 * range: [0, 100]
460 * },
461 * "zoom": {
462 * range: [50, 30]
463 * }
464 * }).on("change", function(event) {
465 * event.holding && event.set({x: 10});
466 * });
467 * ```
468 */
469
470 /** Specifies the animation coordinates to move after the 'release' or 'animationStart' events.
471 * @ko 'release' 또는 'animationStart' 이벤트 이후 이동할 좌표를 지정한다.
472 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko>
473 * @param {Number} [duration=0] Duration of the animation (unit: ms) <ko>애니메이션 진행 시간(단위: ms)</ko>
474 * @example
475 * ```js
476 * const axes = new eg.Axes({
477 * "x": {
478 * range: [0, 100]
479 * },
480 * "zoom": {
481 * range: [50, 30]
482 * }
483 * }).on("animationStart", function(event) {
484 * event.setTo({x: 10}, 2000);
485 * });
486 * ```
487 */
488
489 /**
490 * This event is fired when a user release an element on the screen of the device.
491 * @ko 사용자가 기기의 화면에서 손을 뗐을 때 발생하는 이벤트
492 * @event Axes#release
493 * @type {object}
494 * @property {Object.<string, number>} depaPos The coordinates when releasing an element<ko>손을 뗐을 때의 좌표 </ko>
495 * @property {Object.<string, number>} destPos The coordinates to move to after releasing an element<ko>손을 뗀 뒤에 이동할 좌표</ko>
496 * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko>
497 * @property {Object.<string, number>} bounceRatio If the coordinates at the time of release are in the bounce area, the current bounce value divided by the maximum bounce value <ko>손을 뗐을 때의 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치.</ko>
498 * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko>
499 * @property {Object} input The instance of inputType where the event occurred<ko>이벤트가 발생한 inputType 인스턴스</ko>
500 * @property {setTo} setTo Specifies the animation coordinates to move after the event <ko>이벤트 이후 이동할 애니메이션 좌표를 지정한다</ko>
501 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
502 *
503 * @example
504 * ```js
505 * const axes = new eg.Axes({
506 * "x": {
507 * range: [0, 100]
508 * },
509 * "zoom": {
510 * range: [50, 30]
511 * }
512 * }).on("release", function(event) {
513 * // event.depaPos
514 * // event.destPos
515 * // event.delta
516 * // event.input
517 * // event.inputEvent
518 * // event.setTo
519 * // event.isTrusted
520 *
521 * // if you want to change the animation coordinates to move after the 'release' event.
522 * event.setTo({x: 10}, 2000);
523 * });
524 * ```
525 */
526
527
528 __proto.triggerRelease = function (param) {
529 var _a = this._getRoundPos(param.destPos, param.depaPos),
530 roundPos = _a.roundPos,
531 roundDepa = _a.roundDepa;
532
533 param.destPos = roundPos;
534 param.depaPos = roundDepa;
535 param.setTo = this._createUserControll(param.destPos, param.duration);
536
537 this._axes.trigger(new Component.ComponentEvent("release", __assign(__assign({}, param), {
538 bounceRatio: this._getBounceRatio(roundPos)
539 })));
540 };
541 /**
542 * This event is fired when coordinate changes.
543 * @ko 좌표가 변경됐을 때 발생하는 이벤트
544 * @event Axes#change
545 * @type {object}
546 * @property {Object.<string, number>} pos The coordinate <ko>좌표</ko>
547 * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko>
548 * @property {Object.<string, number>} bounceRatio If the current coordinates are in the bounce area, the current bounce value divided by the maximum bounce value <ko>현재 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치.</ko>
549 * @property {Boolean} holding Indicates whether a user holds an element on the screen of the device.<ko>사용자가 기기의 화면을 누르고 있는지 여부</ko>
550 * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.<ko>이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko>
551 * @property {Object} inputEvent The event object received from inputType. If the value is changed by animation, it returns 'null'.<ko>inputType으로 부터 받은 이벤트 객체. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko>
552 * @property {set} set Specifies the coordinates to move after the event. It works when the holding value is true <ko>이벤트 이후 이동할 좌표를 지정한다. holding 값이 true일 경우에 동작한다.</ko>
553 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
554 *
555 * @example
556 * ```js
557 * const axes = new eg.Axes({
558 * "x": {
559 * range: [0, 100]
560 * },
561 * "zoom": {
562 * range: [50, 30]
563 * }
564 * }).on("change", function(event) {
565 * // event.pos
566 * // event.delta
567 * // event.input
568 * // event.inputEvent
569 * // event.holding
570 * // event.set
571 * // event.isTrusted
572 *
573 * // if you want to change the coordinates to move after the 'change' event.
574 * // it works when the holding value of the change event is true.
575 * event.holding && event.set({x: 10});
576 * });
577 * ```
578 */
579
580
581 __proto.triggerChange = function (pos, depaPos, option, holding) {
582 var _this = this;
583
584 if (holding === void 0) {
585 holding = false;
586 }
587
588 var animationManager = this.animationManager;
589 var axisManager = animationManager.axisManager;
590 var eventInfo = animationManager.getEventInfo();
591
592 var _a = this._getRoundPos(pos, depaPos),
593 roundPos = _a.roundPos,
594 roundDepa = _a.roundDepa;
595
596 var moveTo = axisManager.moveTo(roundPos, roundDepa);
597 var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.event) || null;
598 var param = {
599 pos: moveTo.pos,
600 delta: moveTo.delta,
601 bounceRatio: this._getBounceRatio(moveTo.pos),
602 holding: holding,
603 inputEvent: inputEvent,
604 isTrusted: !!inputEvent,
605 input: (option === null || option === void 0 ? void 0 : option.input) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.input) || null,
606 set: inputEvent ? this._createUserControll(moveTo.pos) : function () {} // eslint-disable-line @typescript-eslint/no-empty-function
607
608 };
609 var event = new Component.ComponentEvent("change", param);
610
611 this._axes.trigger(event);
612
613 Object.keys(moveTo.pos).forEach(function (axis) {
614 var p = moveTo.pos[axis];
615 core.getObserver(_this._axes, axis, p).current = p;
616 });
617
618 if (inputEvent) {
619 axisManager.set(param.set().destPos);
620 }
621
622 return !event.isCanceled();
623 };
624 /**
625 * This event is fired when animation starts.
626 * @ko 에니메이션이 시작할 때 발생한다.
627 * @event Axes#animationStart
628 * @type {object}
629 * @property {Object.<string, number>} depaPos The coordinates when animation starts<ko>애니메이션이 시작 되었을 때의 좌표 </ko>
630 * @property {Object.<string, number>} destPos The coordinates to move to. If you change this value, you can run the animation<ko>이동할 좌표. 이값을 변경하여 애니메이션을 동작시킬수 있다</ko>
631 * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko>
632 * @property {Number} duration Duration of the animation (unit: ms). If you change this value, you can control the animation duration time.<ko>애니메이션 진행 시간(단위: ms). 이값을 변경하여 애니메이션의 이동시간을 조절할 수 있다.</ko>
633 * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.<ko>이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko>
634 * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko>
635 * @property {setTo} setTo Specifies the animation coordinates to move after the event <ko>이벤트 이후 이동할 애니메이션 좌표를 지정한다</ko>
636 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
637 *
638 * @example
639 * ```js
640 * const axes = new eg.Axes({
641 * "x": {
642 * range: [0, 100]
643 * },
644 * "zoom": {
645 * range: [50, 30]
646 * }
647 * }).on("release", function(event) {
648 * // event.depaPos
649 * // event.destPos
650 * // event.delta
651 * // event.input
652 * // event.inputEvent
653 * // event.setTo
654 * // event.isTrusted
655 *
656 * // if you want to change the animation coordinates to move after the 'animationStart' event.
657 * event.setTo({x: 10}, 2000);
658 * });
659 * ```
660 */
661
662
663 __proto.triggerAnimationStart = function (param) {
664 var _a = this._getRoundPos(param.destPos, param.depaPos),
665 roundPos = _a.roundPos,
666 roundDepa = _a.roundDepa;
667
668 param.destPos = roundPos;
669 param.depaPos = roundDepa;
670 param.setTo = this._createUserControll(param.destPos, param.duration);
671 var event = new Component.ComponentEvent("animationStart", param);
672
673 this._axes.trigger(event);
674
675 return !event.isCanceled();
676 };
677 /**
678 * This event is fired when animation ends.
679 * @ko 에니메이션이 끝났을 때 발생한다.
680 * @event Axes#animationEnd
681 * @type {object}
682 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
683 *
684 * @example
685 * ```js
686 * const axes = new eg.Axes({
687 * "x": {
688 * range: [0, 100]
689 * },
690 * "zoom": {
691 * range: [50, 30]
692 * }
693 * }).on("animationEnd", function(event) {
694 * // event.isTrusted
695 * });
696 * ```
697 */
698
699
700 __proto.triggerAnimationEnd = function (isTrusted) {
701 if (isTrusted === void 0) {
702 isTrusted = false;
703 }
704
705 this._axes.trigger(new Component.ComponentEvent("animationEnd", {
706 isTrusted: isTrusted
707 }));
708 };
709 /**
710 * This event is fired when all actions have been completed.
711 * @ko 에니메이션이 끝났을 때 발생한다.
712 * @event Axes#finish
713 * @type {object}
714 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
715 *
716 * @example
717 * ```js
718 * const axes = new eg.Axes({
719 * "x": {
720 * range: [0, 100]
721 * },
722 * "zoom": {
723 * range: [50, 30]
724 * }
725 * }).on("finish", function(event) {
726 * // event.isTrusted
727 * });
728 * ```
729 */
730
731
732 __proto.triggerFinish = function (isTrusted) {
733 if (isTrusted === void 0) {
734 isTrusted = false;
735 }
736
737 this._axes.trigger(new Component.ComponentEvent("finish", {
738 isTrusted: isTrusted
739 }));
740 };
741
742 __proto.setAnimationManager = function (animationManager) {
743 this.animationManager = animationManager;
744 };
745
746 __proto.destroy = function () {
747 this._axes.off();
748 };
749
750 __proto._createUserControll = function (pos, duration) {
751 if (duration === void 0) {
752 duration = 0;
753 } // to controll
754
755
756 var userControl = {
757 destPos: __assign({}, pos),
758 duration: duration
759 };
760 return function (toPos, userDuration) {
761 if (toPos) {
762 userControl.destPos = __assign({}, toPos);
763 }
764
765 if (userDuration !== undefined) {
766 userControl.duration = userDuration;
767 }
768
769 return userControl;
770 };
771 };
772
773 __proto._getRoundPos = function (pos, depaPos) {
774 // round value if round exist
775 var roundUnit = this._axes.options.round; // if (round == null) {
776 // return {pos, depaPos}; // undefined, undefined
777 // }
778
779 return {
780 roundPos: roundNumbers(pos, roundUnit),
781 roundDepa: roundNumbers(depaPos, roundUnit)
782 };
783 };
784
785 __proto._getBounceRatio = function (pos) {
786 return this._axes.axisManager.map(pos, function (v, opt) {
787 if (v < opt.range[0] && opt.bounce[0] !== 0) {
788 return (opt.range[0] - v) / opt.bounce[0];
789 } else if (v > opt.range[1] && opt.bounce[1] !== 0) {
790 return (v - opt.range[1]) / opt.bounce[1];
791 } else {
792 return 0;
793 }
794 });
795 };
796
797 return EventManager;
798}();
799
800var InterruptManager =
801/*#__PURE__*/
802function () {
803 function InterruptManager(_options) {
804 this._options = _options;
805 this._prevented = false; // check whether the animation event was prevented
806 }
807
808 var __proto = InterruptManager.prototype;
809
810 __proto.isInterrupting = function () {
811 // when interruptable is 'true', return value is always 'true'.
812 return this._options.interruptable || this._prevented;
813 };
814
815 __proto.isInterrupted = function () {
816 return !this._options.interruptable && this._prevented;
817 };
818
819 __proto.setInterrupt = function (prevented) {
820 if (!this._options.interruptable) {
821 this._prevented = prevented;
822 }
823 };
824
825 return InterruptManager;
826}();
827
828/*
829 * Copyright (c) 2015 NAVER Corp.
830 * egjs projects are licensed under the MIT license
831 */
832var getInsidePosition = function (destPos, range, circular, bounce) {
833 var toDestPos = destPos;
834 var targetRange = [circular[0] ? range[0] : bounce ? range[0] - bounce[0] : range[0], circular[1] ? range[1] : bounce ? range[1] + bounce[1] : range[1]];
835 toDestPos = Math.max(targetRange[0], toDestPos);
836 toDestPos = Math.min(targetRange[1], toDestPos);
837 return toDestPos;
838}; // determine outside
839
840var isOutside = function (pos, range) {
841 return pos < range[0] || pos > range[1];
842}; // determine whether position has reached the maximum moveable area
843
844var isEndofBounce = function (pos, range, bounce, circular) {
845 return !circular[0] && pos === range[0] - bounce[0] || !circular[1] && pos === range[1] + bounce[1];
846};
847var getDuration = function (distance, deceleration) {
848 var duration = Math.sqrt(distance / deceleration * 2); // when duration is under 100, then value is zero
849
850 return duration < 100 ? 0 : duration;
851};
852var isCircularable = function (destPos, range, circular) {
853 return circular[1] && destPos > range[1] || circular[0] && destPos < range[0];
854};
855var getCirculatedPos = function (pos, range, circular) {
856 var toPos = pos;
857 var min = range[0];
858 var max = range[1];
859 var length = max - min;
860
861 if (circular[1] && pos > max) {
862 // right
863 toPos = (toPos - max) % length + min;
864 }
865
866 if (circular[0] && pos < min) {
867 // left
868 toPos = (toPos - min) % length + max;
869 }
870
871 return toPos;
872};
873
874var AxisManager =
875/*#__PURE__*/
876function () {
877 function AxisManager(_axis) {
878 var _this = this;
879
880 this._axis = _axis;
881
882 this._complementOptions();
883
884 this._pos = Object.keys(this._axis).reduce(function (pos, v) {
885 pos[v] = _this._axis[v].startPos;
886 return pos;
887 }, {});
888 }
889
890 var __proto = AxisManager.prototype;
891
892 __proto.getDelta = function (depaPos, destPos) {
893 var fullDepaPos = this.get(depaPos);
894 return map(this.get(destPos), function (v, k) {
895 return v - fullDepaPos[k];
896 });
897 };
898
899 __proto.get = function (axes) {
900 var _this = this;
901
902 if (axes && Array.isArray(axes)) {
903 return axes.reduce(function (acc, v) {
904 if (v && v in _this._pos) {
905 acc[v] = _this._pos[v];
906 }
907
908 return acc;
909 }, {});
910 } else {
911 return __assign(__assign({}, this._pos), axes || {});
912 }
913 };
914
915 __proto.moveTo = function (pos, depaPos) {
916 if (depaPos === void 0) {
917 depaPos = this._pos;
918 }
919
920 var delta = map(this._pos, function (v, key) {
921 return key in pos && key in depaPos ? pos[key] - depaPos[key] : 0;
922 });
923 this.set(this.map(pos, function (v, opt) {
924 return opt ? getCirculatedPos(v, opt.range, opt.circular) : 0;
925 }));
926 return {
927 pos: __assign({}, this._pos),
928 delta: delta
929 };
930 };
931
932 __proto.set = function (pos) {
933 for (var k in pos) {
934 if (k && k in this._pos) {
935 this._pos[k] = pos[k];
936 }
937 }
938 };
939
940 __proto.every = function (pos, callback) {
941 var axisOptions = this._axis;
942 return every(pos, function (value, key) {
943 return callback(value, axisOptions[key], key);
944 });
945 };
946
947 __proto.filter = function (pos, callback) {
948 var axisOptions = this._axis;
949 return filter(pos, function (value, key) {
950 return callback(value, axisOptions[key], key);
951 });
952 };
953
954 __proto.map = function (pos, callback) {
955 var axisOptions = this._axis;
956 return map(pos, function (value, key) {
957 return callback(value, axisOptions[key], key);
958 });
959 };
960
961 __proto.isOutside = function (axes) {
962 return !this.every(axes ? this.get(axes) : this._pos, function (v, opt) {
963 return !isOutside(v, opt.range);
964 });
965 };
966
967 __proto.getAxisOptions = function (key) {
968 return this._axis[key];
969 };
970
971 __proto.setAxis = function (axis) {
972 var _this = this;
973
974 Object.keys(axis).forEach(function (key) {
975 if (!_this._axis[key]) {
976 throw new Error("Axis ".concat(key, " does not exist in Axes instance"));
977 }
978
979 _this._axis[key] = __assign(__assign({}, _this._axis[key]), axis[key]);
980 });
981
982 this._complementOptions();
983 };
984 /**
985 * set up 'css' expression
986 * @private
987 */
988
989
990 __proto._complementOptions = function () {
991 var _this = this;
992
993 Object.keys(this._axis).forEach(function (axis) {
994 _this._axis[axis] = __assign({
995 range: [0, 100],
996 startPos: _this._axis[axis].range[0],
997 bounce: [0, 0],
998 circular: [false, false]
999 }, _this._axis[axis]);
1000 ["bounce", "circular"].forEach(function (v) {
1001 var axisOption = _this._axis;
1002 var key = axisOption[axis][v];
1003
1004 if (/string|number|boolean/.test(typeof key)) {
1005 axisOption[axis][v] = [key, key];
1006 }
1007 });
1008 });
1009 };
1010
1011 return AxisManager;
1012}();
1013
1014var SUPPORT_TOUCH = ("ontouchstart" in win);
1015var SUPPORT_POINTER = ("PointerEvent" in win);
1016var SUPPORT_MSPOINTER = ("MSPointerEvent" in win);
1017var SUPPORT_POINTER_EVENTS = SUPPORT_POINTER || SUPPORT_MSPOINTER;
1018var isValidKey = function (event, inputKey) {
1019 if (!inputKey || inputKey.indexOf(ANY) > -1 || inputKey.indexOf(NONE) > -1 && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey || inputKey.indexOf(SHIFT) > -1 && event.shiftKey || inputKey.indexOf(CTRL) > -1 && event.ctrlKey || inputKey.indexOf(ALT) > -1 && event.altKey || inputKey.indexOf(META) > -1 && event.metaKey) {
1020 return true;
1021 }
1022
1023 return false;
1024};
1025
1026var EventInput =
1027/*#__PURE__*/
1028function () {
1029 function EventInput() {
1030 var _this = this;
1031
1032 this._stopContextMenu = function (event) {
1033 event.preventDefault();
1034 win.removeEventListener("contextmenu", _this._stopContextMenu);
1035 };
1036 }
1037
1038 var __proto = EventInput.prototype;
1039
1040 __proto.extendEvent = function (event) {
1041 var _a;
1042
1043 var prevEvent = this.prevEvent;
1044
1045 var center = this._getCenter(event);
1046
1047 var movement = prevEvent ? this._getMovement(event) : {
1048 x: 0,
1049 y: 0
1050 };
1051 var scale = prevEvent ? this._getScale(event) : 1;
1052 var angle = prevEvent ? getAngle(center.x - prevEvent.center.x, center.y - prevEvent.center.y) : 0;
1053 var deltaX = prevEvent ? prevEvent.deltaX + movement.x : movement.x;
1054 var deltaY = prevEvent ? prevEvent.deltaY + movement.y : movement.y;
1055 var offsetX = movement.x;
1056 var offsetY = movement.y;
1057 var latestInterval = this._latestInterval;
1058 var timeStamp = Date.now();
1059 var deltaTime = latestInterval ? timeStamp - latestInterval.timestamp : 0;
1060 var velocityX = prevEvent ? prevEvent.velocityX : 0;
1061 var velocityY = prevEvent ? prevEvent.velocityY : 0;
1062
1063 if (!latestInterval || deltaTime >= VELOCITY_INTERVAL) {
1064 if (latestInterval) {
1065 _a = [(deltaX - latestInterval.deltaX) / deltaTime, (deltaY - latestInterval.deltaY) / deltaTime], velocityX = _a[0], velocityY = _a[1];
1066 }
1067
1068 this._latestInterval = {
1069 timestamp: timeStamp,
1070 deltaX: deltaX,
1071 deltaY: deltaY
1072 };
1073 }
1074
1075 return {
1076 srcEvent: event,
1077 scale: scale,
1078 angle: angle,
1079 center: center,
1080 deltaX: deltaX,
1081 deltaY: deltaY,
1082 offsetX: offsetX,
1083 offsetY: offsetY,
1084 velocityX: velocityX,
1085 velocityY: velocityY,
1086 preventSystemEvent: true
1087 };
1088 };
1089
1090 __proto._getDistance = function (start, end) {
1091 var x = end.clientX - start.clientX;
1092 var y = end.clientY - start.clientY;
1093 return Math.sqrt(x * x + y * y);
1094 };
1095
1096 __proto._getButton = function (event) {
1097 var buttonCodeMap = {
1098 1: MOUSE_LEFT,
1099 2: MOUSE_RIGHT,
1100 4: MOUSE_MIDDLE
1101 };
1102 var button = this._isTouchEvent(event) ? MOUSE_LEFT : buttonCodeMap[event.buttons];
1103 return button ? button : null;
1104 };
1105
1106 __proto._isTouchEvent = function (event) {
1107 return event.type && event.type.indexOf("touch") > -1;
1108 };
1109
1110 __proto._isValidButton = function (button, inputButton) {
1111 return inputButton.indexOf(button) > -1;
1112 };
1113
1114 __proto._isValidEvent = function (event, inputKey, inputButton) {
1115 return (!inputKey || isValidKey(event, inputKey)) && (!inputButton || this._isValidButton(this._getButton(event), inputButton));
1116 };
1117
1118 __proto._preventMouseButton = function (event, button) {
1119 if (button === MOUSE_RIGHT) {
1120 win.addEventListener("contextmenu", this._stopContextMenu);
1121 } else if (button === MOUSE_MIDDLE) {
1122 event.preventDefault();
1123 }
1124 };
1125
1126 return EventInput;
1127}();
1128
1129var MouseEventInput =
1130/*#__PURE__*/
1131function (_super) {
1132 __extends(MouseEventInput, _super);
1133
1134 function MouseEventInput() {
1135 var _this = _super !== null && _super.apply(this, arguments) || this;
1136
1137 _this.start = ["mousedown"];
1138 _this.move = ["mousemove"];
1139 _this.end = ["mouseup"];
1140 return _this;
1141 }
1142
1143 var __proto = MouseEventInput.prototype;
1144
1145 __proto.onEventStart = function (event, inputKey, inputButton) {
1146 var button = this._getButton(event);
1147
1148 if (!this._isValidEvent(event, inputKey, inputButton)) {
1149 return null;
1150 }
1151
1152 this._preventMouseButton(event, button);
1153
1154 return this.extendEvent(event);
1155 };
1156
1157 __proto.onEventMove = function (event, inputKey, inputButton) {
1158 if (!this._isValidEvent(event, inputKey, inputButton)) {
1159 return null;
1160 }
1161
1162 return this.extendEvent(event);
1163 };
1164
1165 __proto.onEventEnd = function () {
1166 return;
1167 };
1168
1169 __proto.onRelease = function () {
1170 this.prevEvent = null;
1171 return;
1172 };
1173
1174 __proto.getTouches = function (event, inputButton) {
1175 if (inputButton) {
1176 var buttonCodeMap = {
1177 1: MOUSE_LEFT,
1178 2: MOUSE_MIDDLE,
1179 3: MOUSE_RIGHT
1180 };
1181 return this._isValidButton(buttonCodeMap[event.which], inputButton) && this.end.indexOf(event.type) === -1 ? 1 : 0;
1182 }
1183
1184 return 0;
1185 };
1186
1187 __proto._getScale = function () {
1188 return 1;
1189 };
1190
1191 __proto._getCenter = function (event) {
1192 return {
1193 x: event.clientX,
1194 y: event.clientY
1195 };
1196 };
1197
1198 __proto._getMovement = function (event) {
1199 var prev = this.prevEvent.srcEvent;
1200 return {
1201 x: event.clientX - prev.clientX,
1202 y: event.clientY - prev.clientY
1203 };
1204 };
1205
1206 return MouseEventInput;
1207}(EventInput);
1208
1209var TouchEventInput =
1210/*#__PURE__*/
1211function (_super) {
1212 __extends(TouchEventInput, _super);
1213
1214 function TouchEventInput() {
1215 var _this = _super !== null && _super.apply(this, arguments) || this;
1216
1217 _this.start = ["touchstart"];
1218 _this.move = ["touchmove"];
1219 _this.end = ["touchend", "touchcancel"];
1220 return _this;
1221 }
1222
1223 var __proto = TouchEventInput.prototype;
1224
1225 __proto.onEventStart = function (event, inputKey) {
1226 this._baseTouches = event.touches;
1227
1228 if (!this._isValidEvent(event, inputKey)) {
1229 return null;
1230 }
1231
1232 return this.extendEvent(event);
1233 };
1234
1235 __proto.onEventMove = function (event, inputKey) {
1236 if (!this._isValidEvent(event, inputKey)) {
1237 return null;
1238 }
1239
1240 return this.extendEvent(event);
1241 };
1242
1243 __proto.onEventEnd = function (event) {
1244 this._baseTouches = event.touches;
1245 return;
1246 };
1247
1248 __proto.onRelease = function () {
1249 this.prevEvent = null;
1250 this._baseTouches = null;
1251 return;
1252 };
1253
1254 __proto.getTouches = function (event) {
1255 return event.touches.length;
1256 };
1257
1258 __proto._getScale = function (event) {
1259 if (event.touches.length !== 2 || this._baseTouches.length < 2) {
1260 return null; // TODO: consider calculating non-pinch gesture scale
1261 }
1262
1263 return this._getDistance(event.touches[0], event.touches[1]) / this._getDistance(this._baseTouches[0], this._baseTouches[1]);
1264 };
1265
1266 __proto._getCenter = function (event) {
1267 return {
1268 x: event.touches[0].clientX,
1269 y: event.touches[0].clientY
1270 };
1271 };
1272
1273 __proto._getMovement = function (event) {
1274 var prev = this.prevEvent.srcEvent;
1275
1276 if (event.touches[0].identifier !== prev.touches[0].identifier) {
1277 return {
1278 x: 0,
1279 y: 0
1280 };
1281 }
1282
1283 return {
1284 x: event.touches[0].clientX - prev.touches[0].clientX,
1285 y: event.touches[0].clientY - prev.touches[0].clientY
1286 };
1287 };
1288
1289 return TouchEventInput;
1290}(EventInput);
1291
1292var PointerEventInput =
1293/*#__PURE__*/
1294function (_super) {
1295 __extends(PointerEventInput, _super);
1296
1297 function PointerEventInput() {
1298 var _this = _super !== null && _super.apply(this, arguments) || this;
1299
1300 _this.start = SUPPORT_POINTER ? ["pointerdown"] : ["MSPointerDown"];
1301 _this.move = SUPPORT_POINTER ? ["pointermove"] : ["MSPointerMove"];
1302 _this.end = SUPPORT_POINTER ? ["pointerup", "pointercancel"] : ["MSPointerUp", "MSPointerCancel"]; // store first, recent inputs for each event id
1303
1304 _this._firstInputs = [];
1305 _this._recentInputs = [];
1306 return _this;
1307 }
1308
1309 var __proto = PointerEventInput.prototype;
1310
1311 __proto.onEventStart = function (event, inputKey, inputButton) {
1312 var button = this._getButton(event);
1313
1314 if (!this._isValidEvent(event, inputKey, inputButton)) {
1315 return null;
1316 }
1317
1318 this._preventMouseButton(event, button);
1319
1320 this._updatePointerEvent(event);
1321
1322 return this.extendEvent(event);
1323 };
1324
1325 __proto.onEventMove = function (event, inputKey, inputButton) {
1326 if (!this._isValidEvent(event, inputKey, inputButton)) {
1327 return null;
1328 }
1329
1330 this._updatePointerEvent(event);
1331
1332 return this.extendEvent(event);
1333 };
1334
1335 __proto.onEventEnd = function (event) {
1336 this._removePointerEvent(event);
1337 };
1338
1339 __proto.onRelease = function () {
1340 this.prevEvent = null;
1341 this._firstInputs = [];
1342 this._recentInputs = [];
1343 return;
1344 };
1345
1346 __proto.getTouches = function () {
1347 return this._recentInputs.length;
1348 };
1349
1350 __proto._getScale = function () {
1351 if (this._recentInputs.length !== 2) {
1352 return null; // TODO: consider calculating non-pinch gesture scale
1353 }
1354
1355 return this._getDistance(this._recentInputs[0], this._recentInputs[1]) / this._getDistance(this._firstInputs[0], this._firstInputs[1]);
1356 };
1357
1358 __proto._getCenter = function (event) {
1359 return {
1360 x: event.clientX,
1361 y: event.clientY
1362 };
1363 };
1364
1365 __proto._getMovement = function (event) {
1366 var prev = this.prevEvent.srcEvent;
1367
1368 if (event.pointerId !== prev.pointerId) {
1369 return {
1370 x: 0,
1371 y: 0
1372 };
1373 }
1374
1375 return {
1376 x: event.clientX - prev.clientX,
1377 y: event.clientY - prev.clientY
1378 };
1379 };
1380
1381 __proto._updatePointerEvent = function (event) {
1382 var _this = this;
1383
1384 var addFlag = false;
1385
1386 this._recentInputs.forEach(function (e, i) {
1387 if (e.pointerId === event.pointerId) {
1388 addFlag = true;
1389 _this._recentInputs[i] = event;
1390 }
1391 });
1392
1393 if (!addFlag) {
1394 this._firstInputs.push(event);
1395
1396 this._recentInputs.push(event);
1397 }
1398 };
1399
1400 __proto._removePointerEvent = function (event) {
1401 this._firstInputs = this._firstInputs.filter(function (x) {
1402 return x.pointerId !== event.pointerId;
1403 });
1404 this._recentInputs = this._recentInputs.filter(function (x) {
1405 return x.pointerId !== event.pointerId;
1406 });
1407 };
1408
1409 return PointerEventInput;
1410}(EventInput);
1411
1412var TouchMouseEventInput =
1413/*#__PURE__*/
1414function (_super) {
1415 __extends(TouchMouseEventInput, _super);
1416
1417 function TouchMouseEventInput() {
1418 var _this = _super !== null && _super.apply(this, arguments) || this;
1419
1420 _this.start = ["mousedown", "touchstart"];
1421 _this.move = ["mousemove", "touchmove"];
1422 _this.end = ["mouseup", "touchend", "touchcancel"];
1423 return _this;
1424 }
1425
1426 var __proto = TouchMouseEventInput.prototype;
1427
1428 __proto.onEventStart = function (event, inputKey, inputButton) {
1429 var button = this._getButton(event);
1430
1431 if (this._isTouchEvent(event)) {
1432 this._baseTouches = event.touches;
1433 }
1434
1435 if (!this._isValidEvent(event, inputKey, inputButton)) {
1436 return null;
1437 }
1438
1439 this._preventMouseButton(event, button);
1440
1441 return this.extendEvent(event);
1442 };
1443
1444 __proto.onEventMove = function (event, inputKey, inputButton) {
1445 if (!this._isValidEvent(event, inputKey, inputButton)) {
1446 return null;
1447 }
1448
1449 return this.extendEvent(event);
1450 };
1451
1452 __proto.onEventEnd = function (event) {
1453 if (this._isTouchEvent(event)) {
1454 this._baseTouches = event.touches;
1455 }
1456
1457 return;
1458 };
1459
1460 __proto.onRelease = function () {
1461 this.prevEvent = null;
1462 this._baseTouches = null;
1463 return;
1464 };
1465
1466 __proto.getTouches = function (event) {
1467 return this._isTouchEvent(event) ? event.touches.length : 0;
1468 };
1469
1470 __proto._getScale = function (event) {
1471 if (this._isTouchEvent(event)) {
1472 if (event.touches.length !== 2 || this._baseTouches.length < 2) {
1473 return 1; // TODO: consider calculating non-pinch gesture scale
1474 }
1475
1476 return this._getDistance(event.touches[0], event.touches[1]) / this._getDistance(this._baseTouches[0], this._baseTouches[1]);
1477 }
1478
1479 return this.prevEvent.scale;
1480 };
1481
1482 __proto._getCenter = function (event) {
1483 if (this._isTouchEvent(event)) {
1484 return {
1485 x: event.touches[0].clientX,
1486 y: event.touches[0].clientY
1487 };
1488 }
1489
1490 return {
1491 x: event.clientX,
1492 y: event.clientY
1493 };
1494 };
1495
1496 __proto._getMovement = function (event) {
1497 var _this = this;
1498
1499 var prev = this.prevEvent.srcEvent;
1500
1501 var _a = [event, prev].map(function (e) {
1502 if (_this._isTouchEvent(e)) {
1503 return {
1504 id: e.touches[0].identifier,
1505 x: e.touches[0].clientX,
1506 y: e.touches[0].clientY
1507 };
1508 }
1509
1510 return {
1511 id: null,
1512 x: e.clientX,
1513 y: e.clientY
1514 };
1515 }),
1516 nextSpot = _a[0],
1517 prevSpot = _a[1];
1518
1519 return nextSpot.id === prevSpot.id ? {
1520 x: nextSpot.x - prevSpot.x,
1521 y: nextSpot.y - prevSpot.y
1522 } : {
1523 x: 0,
1524 y: 0
1525 };
1526 };
1527
1528 return TouchMouseEventInput;
1529}(EventInput);
1530
1531var toAxis = function (source, offset) {
1532 return offset.reduce(function (acc, v, i) {
1533 if (source[i]) {
1534 acc[source[i]] = v;
1535 }
1536
1537 return acc;
1538 }, {});
1539};
1540var convertInputType = function (inputType) {
1541 if (inputType === void 0) {
1542 inputType = [];
1543 }
1544
1545 var hasTouch = false;
1546 var hasMouse = false;
1547 var hasPointer = false;
1548 inputType.forEach(function (v) {
1549 switch (v) {
1550 case "mouse":
1551 hasMouse = true;
1552 break;
1553
1554 case "touch":
1555 hasTouch = SUPPORT_TOUCH;
1556 break;
1557
1558 case "pointer":
1559 hasPointer = SUPPORT_POINTER_EVENTS;
1560 // no default
1561 }
1562 });
1563
1564 if (hasPointer) {
1565 return new PointerEventInput();
1566 } else if (hasTouch && hasMouse) {
1567 return new TouchMouseEventInput();
1568 } else if (hasTouch) {
1569 return new TouchEventInput();
1570 } else if (hasMouse) {
1571 return new MouseEventInput();
1572 }
1573
1574 return null;
1575};
1576function getAddEventOptions(eventName) {
1577 // The passive default value of the touch event is true.
1578 // If not a touch event, return false to support ie11
1579 return eventName.indexOf("touch") > -1 ? {
1580 passive: false
1581 } : false;
1582}
1583
1584var InputObserver =
1585/*#__PURE__*/
1586function () {
1587 function InputObserver(_a) {
1588 var options = _a.options,
1589 interruptManager = _a.interruptManager,
1590 eventManager = _a.eventManager,
1591 axisManager = _a.axisManager,
1592 animationManager = _a.animationManager;
1593 this._isOutside = false;
1594 this._moveDistance = null;
1595 this._isStopped = false;
1596 this.options = options;
1597 this._interruptManager = interruptManager;
1598 this._eventManager = eventManager;
1599 this._axisManager = axisManager;
1600 this._animationManager = animationManager;
1601 }
1602
1603 var __proto = InputObserver.prototype;
1604
1605 __proto.get = function (input) {
1606 return this._axisManager.get(input.axes);
1607 };
1608
1609 __proto.hold = function (input, event) {
1610 if (this._interruptManager.isInterrupted() || !input.axes.length) {
1611 return;
1612 }
1613
1614 var changeOption = {
1615 input: input,
1616 event: event
1617 };
1618 this._isStopped = false;
1619
1620 this._interruptManager.setInterrupt(true);
1621
1622 this._animationManager.stopAnimation(changeOption);
1623
1624 if (!this._moveDistance) {
1625 this._eventManager.hold(this._axisManager.get(), changeOption);
1626 }
1627
1628 this._isOutside = this._axisManager.isOutside(input.axes);
1629 this._moveDistance = this._axisManager.get(input.axes);
1630 };
1631
1632 __proto.change = function (input, event, offset, useAnimation) {
1633 if (this._isStopped || !this._interruptManager.isInterrupting() || this._axisManager.every(offset, function (v) {
1634 return v === 0;
1635 })) {
1636 return;
1637 }
1638
1639 var nativeEvent = event.srcEvent ? event.srcEvent : event;
1640
1641 if (nativeEvent.__childrenAxesAlreadyChanged) {
1642 return;
1643 }
1644
1645 var depaPos = this._moveDistance || this._axisManager.get(input.axes);
1646
1647 var destPos; // for outside logic
1648
1649 destPos = map(depaPos, function (v, k) {
1650 return v + (offset[k] || 0);
1651 });
1652
1653 if (this._moveDistance) {
1654 this._moveDistance = this._axisManager.map(destPos, function (v, _a) {
1655 var circular = _a.circular,
1656 range = _a.range;
1657 return circular && (circular[0] || circular[1]) ? getCirculatedPos(v, range, circular) : v;
1658 });
1659 } // from outside to inside
1660
1661
1662 if (this._isOutside && this._axisManager.every(depaPos, function (v, opt) {
1663 return !isOutside(v, opt.range);
1664 })) {
1665 this._isOutside = false;
1666 }
1667
1668 depaPos = this._atOutside(depaPos);
1669 destPos = this._atOutside(destPos);
1670
1671 if (!this.options.nested || !this._isEndofAxis(offset, depaPos, destPos)) {
1672 nativeEvent.__childrenAxesAlreadyChanged = true;
1673 }
1674
1675 var changeOption = {
1676 input: input,
1677 event: event
1678 };
1679
1680 if (useAnimation) {
1681 var duration = this._animationManager.getDuration(destPos, depaPos);
1682
1683 this._animationManager.animateTo(destPos, duration, changeOption);
1684 } else {
1685 var isCanceled = !this._eventManager.triggerChange(destPos, depaPos, changeOption, true);
1686
1687 if (isCanceled) {
1688 this._isStopped = true;
1689 this._moveDistance = null;
1690
1691 this._animationManager.finish(false);
1692 }
1693 }
1694 };
1695
1696 __proto.release = function (input, event, velocity, inputDuration) {
1697 if (this._isStopped || !this._interruptManager.isInterrupting() || !this._moveDistance) {
1698 return;
1699 }
1700
1701 var nativeEvent = event.srcEvent ? event.srcEvent : event;
1702
1703 if (nativeEvent.__childrenAxesAlreadyReleased) {
1704 velocity = velocity.map(function () {
1705 return 0;
1706 });
1707 }
1708
1709 var pos = this._axisManager.get(input.axes);
1710
1711 var depaPos = this._axisManager.get();
1712
1713 var displacement = this._animationManager.getDisplacement(velocity);
1714
1715 var offset = toAxis(input.axes, displacement);
1716
1717 var destPos = this._axisManager.get(this._axisManager.map(offset, function (v, opt, k) {
1718 if (opt.circular && (opt.circular[0] || opt.circular[1])) {
1719 return pos[k] + v;
1720 } else {
1721 return getInsidePosition(pos[k] + v, opt.range, opt.circular, opt.bounce);
1722 }
1723 }));
1724
1725 nativeEvent.__childrenAxesAlreadyReleased = true;
1726
1727 var duration = this._animationManager.getDuration(destPos, pos, inputDuration);
1728
1729 if (duration === 0) {
1730 destPos = __assign({}, depaPos);
1731 } // prepare params
1732
1733
1734 var param = {
1735 depaPos: depaPos,
1736 destPos: destPos,
1737 duration: duration,
1738 delta: this._axisManager.getDelta(depaPos, destPos),
1739 inputEvent: event,
1740 input: input,
1741 isTrusted: true
1742 };
1743
1744 this._eventManager.triggerRelease(param);
1745
1746 this._moveDistance = null; // to contol
1747
1748 var userWish = this._animationManager.getUserControl(param);
1749
1750 var isEqual = equal(userWish.destPos, depaPos);
1751 var changeOption = {
1752 input: input,
1753 event: event
1754 };
1755
1756 if (isEqual || userWish.duration === 0) {
1757 if (!isEqual) {
1758 this._eventManager.triggerChange(userWish.destPos, depaPos, changeOption, true);
1759 }
1760
1761 this._interruptManager.setInterrupt(false);
1762
1763 if (this._axisManager.isOutside()) {
1764 this._animationManager.restore(changeOption);
1765 } else {
1766 this._eventManager.triggerFinish(true);
1767 }
1768 } else {
1769 this._animationManager.animateTo(userWish.destPos, userWish.duration, changeOption);
1770 }
1771 }; // when move pointer is held in outside
1772
1773
1774 __proto._atOutside = function (pos) {
1775 var _this = this;
1776
1777 if (this._isOutside) {
1778 return this._axisManager.map(pos, function (v, opt) {
1779 var tn = opt.range[0] - opt.bounce[0];
1780 var tx = opt.range[1] + opt.bounce[1];
1781 return v > tx ? tx : v < tn ? tn : v;
1782 });
1783 } else {
1784 return this._axisManager.map(pos, function (v, opt) {
1785 var min = opt.range[0];
1786 var max = opt.range[1];
1787 var out = opt.bounce;
1788 var circular = opt.circular;
1789
1790 if (circular[0] && v < min || circular[1] && v > max) {
1791 return v;
1792 } else if (v < min) {
1793 // left
1794 return min - _this._animationManager.interpolate(min - v, out[0]);
1795 } else if (v > max) {
1796 // right
1797 return max + _this._animationManager.interpolate(v - max, out[1]);
1798 }
1799
1800 return v;
1801 });
1802 }
1803 };
1804
1805 __proto._isEndofAxis = function (offset, depaPos, destPos) {
1806 return this._axisManager.every(depaPos, function (value, option, key) {
1807 return offset[key] === 0 || depaPos[key] === destPos[key] && isEndofBounce(value, option.range, option.bounce, option.circular);
1808 });
1809 };
1810
1811 return InputObserver;
1812}();
1813
1814var clamp = function (value, min, max) {
1815 return Math.max(Math.min(value, max), min);
1816};
1817
1818var AnimationManager =
1819/*#__PURE__*/
1820function () {
1821 function AnimationManager(_a) {
1822 var options = _a.options,
1823 interruptManager = _a.interruptManager,
1824 eventManager = _a.eventManager,
1825 axisManager = _a.axisManager;
1826 this._options = options;
1827 this.interruptManager = interruptManager;
1828 this.eventManager = eventManager;
1829 this.axisManager = axisManager;
1830 this.animationEnd = this.animationEnd.bind(this);
1831 }
1832
1833 var __proto = AnimationManager.prototype;
1834
1835 __proto.getDuration = function (depaPos, destPos, wishDuration) {
1836 var _this = this;
1837
1838 var duration;
1839
1840 if (typeof wishDuration !== "undefined") {
1841 duration = wishDuration;
1842 } else {
1843 var durations_1 = map(destPos, function (v, k) {
1844 return getDuration(Math.abs(v - depaPos[k]), _this._options.deceleration);
1845 });
1846 duration = Object.keys(durations_1).reduce(function (max, v) {
1847 return Math.max(max, durations_1[v]);
1848 }, -Infinity);
1849 }
1850
1851 return clamp(duration, this._options.minimumDuration, this._options.maximumDuration);
1852 };
1853
1854 __proto.getDisplacement = function (velocity) {
1855 var totalVelocity = Math.pow(velocity.reduce(function (total, v) {
1856 return total + v * v;
1857 }, 0), 1 / velocity.length);
1858 var duration = Math.abs(totalVelocity / -this._options.deceleration);
1859 return velocity.map(function (v) {
1860 return v / 2 * duration;
1861 });
1862 };
1863
1864 __proto.stopAnimation = function (option) {
1865 if (this._animateParam) {
1866 var orgPos_1 = this.axisManager.get();
1867 var pos = this.axisManager.map(orgPos_1, function (v, opt) {
1868 return getCirculatedPos(v, opt.range, opt.circular);
1869 });
1870
1871 if (!every(pos, function (v, k) {
1872 return orgPos_1[k] === v;
1873 })) {
1874 this.eventManager.triggerChange(pos, orgPos_1, option, !!option);
1875 }
1876
1877 this._animateParam = null;
1878
1879 if (this._raf) {
1880 cancelAnimationFrame(this._raf);
1881 }
1882
1883 this._raf = null;
1884 this.eventManager.triggerAnimationEnd(!!(option === null || option === void 0 ? void 0 : option.event));
1885 }
1886 };
1887
1888 __proto.getEventInfo = function () {
1889 if (this._animateParam && this._animateParam.input && this._animateParam.inputEvent) {
1890 return {
1891 input: this._animateParam.input,
1892 event: this._animateParam.inputEvent
1893 };
1894 } else {
1895 return null;
1896 }
1897 };
1898
1899 __proto.restore = function (option) {
1900 var pos = this.axisManager.get();
1901 var destPos = this.axisManager.map(pos, function (v, opt) {
1902 return Math.min(opt.range[1], Math.max(opt.range[0], v));
1903 });
1904 this.stopAnimation();
1905 this.animateTo(destPos, this.getDuration(pos, destPos), option);
1906 };
1907
1908 __proto.animationEnd = function () {
1909 var beforeParam = this.getEventInfo();
1910 this._animateParam = null; // for Circular
1911
1912 var circularTargets = this.axisManager.filter(this.axisManager.get(), function (v, opt) {
1913 return isCircularable(v, opt.range, opt.circular);
1914 });
1915
1916 if (Object.keys(circularTargets).length > 0) {
1917 this.setTo(this.axisManager.map(circularTargets, function (v, opt) {
1918 return getCirculatedPos(v, opt.range, opt.circular);
1919 }));
1920 }
1921
1922 this.interruptManager.setInterrupt(false);
1923 this.eventManager.triggerAnimationEnd(!!beforeParam);
1924
1925 if (this.axisManager.isOutside()) {
1926 this.restore(beforeParam);
1927 } else {
1928 this.finish(!!beforeParam);
1929 }
1930 };
1931
1932 __proto.finish = function (isTrusted) {
1933 this._animateParam = null;
1934 this.interruptManager.setInterrupt(false);
1935 this.eventManager.triggerFinish(isTrusted);
1936 };
1937
1938 __proto.getUserControl = function (param) {
1939 var userWish = param.setTo();
1940 userWish.destPos = this.axisManager.get(userWish.destPos);
1941 userWish.duration = clamp(userWish.duration, this._options.minimumDuration, this._options.maximumDuration);
1942 return userWish;
1943 };
1944
1945 __proto.animateTo = function (destPos, duration, option) {
1946 var _this = this;
1947
1948 this.stopAnimation();
1949
1950 var param = this._createAnimationParam(destPos, duration, option);
1951
1952 var depaPos = __assign({}, param.depaPos);
1953
1954 var retTrigger = this.eventManager.triggerAnimationStart(param); // to control
1955
1956 var userWish = this.getUserControl(param); // You can't stop the 'animationStart' event when 'circular' is true.
1957
1958 if (!retTrigger && this.axisManager.every(userWish.destPos, function (v, opt) {
1959 return isCircularable(v, opt.range, opt.circular);
1960 })) {
1961 console.warn("You can't stop the 'animation' event when 'circular' is true.");
1962 }
1963
1964 if (retTrigger && !equal(userWish.destPos, depaPos)) {
1965 var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || null;
1966
1967 this._animateLoop({
1968 depaPos: depaPos,
1969 destPos: userWish.destPos,
1970 duration: userWish.duration,
1971 delta: this.axisManager.getDelta(depaPos, userWish.destPos),
1972 isTrusted: !!inputEvent,
1973 inputEvent: inputEvent,
1974 input: (option === null || option === void 0 ? void 0 : option.input) || null
1975 }, function () {
1976 return _this.animationEnd();
1977 });
1978 }
1979 };
1980
1981 __proto.setTo = function (pos, duration) {
1982 if (duration === void 0) {
1983 duration = 0;
1984 }
1985
1986 var axes = Object.keys(pos);
1987 var orgPos = this.axisManager.get(axes);
1988
1989 if (equal(pos, orgPos)) {
1990 return this;
1991 }
1992
1993 this.interruptManager.setInterrupt(true);
1994 var movedPos = filter(pos, function (v, k) {
1995 return orgPos[k] !== v;
1996 });
1997
1998 if (!Object.keys(movedPos).length) {
1999 return this;
2000 }
2001
2002 movedPos = this.axisManager.map(movedPos, function (v, opt) {
2003 var range = opt.range,
2004 circular = opt.circular;
2005
2006 if (circular && (circular[0] || circular[1])) {
2007 return v;
2008 } else {
2009 return getInsidePosition(v, range, circular);
2010 }
2011 });
2012
2013 if (equal(movedPos, orgPos)) {
2014 return this;
2015 }
2016
2017 if (duration > 0) {
2018 this.animateTo(movedPos, duration);
2019 } else {
2020 this.stopAnimation();
2021 this.eventManager.triggerChange(movedPos);
2022 this.finish(false);
2023 }
2024
2025 return this;
2026 };
2027
2028 __proto.setBy = function (pos, duration) {
2029 if (duration === void 0) {
2030 duration = 0;
2031 }
2032
2033 return this.setTo(map(this.axisManager.get(Object.keys(pos)), function (v, k) {
2034 return v + pos[k];
2035 }), duration);
2036 };
2037
2038 __proto._createAnimationParam = function (pos, duration, option) {
2039 var depaPos = this.axisManager.get();
2040 var destPos = pos;
2041 var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || null;
2042 return {
2043 depaPos: depaPos,
2044 destPos: destPos,
2045 duration: clamp(duration, this._options.minimumDuration, this._options.maximumDuration),
2046 delta: this.axisManager.getDelta(depaPos, destPos),
2047 inputEvent: inputEvent,
2048 input: (option === null || option === void 0 ? void 0 : option.input) || null,
2049 isTrusted: !!inputEvent,
2050 done: this.animationEnd
2051 };
2052 };
2053
2054 __proto._animateLoop = function (param, complete) {
2055 var _this = this;
2056
2057 if (param.duration) {
2058 this._animateParam = __assign(__assign({}, param), {
2059 startTime: new Date().getTime()
2060 });
2061 var originalIntendedPos_1 = map(param.destPos, function (v) {
2062 return v;
2063 });
2064
2065 var state_1 = this._initState(this._animateParam);
2066
2067 var loop_1 = function () {
2068 _this._raf = null;
2069 var animateParam = _this._animateParam;
2070
2071 var nextState = _this._getNextState(state_1);
2072
2073 var isCanceled = !_this.eventManager.triggerChange(nextState.pos, state_1.pos);
2074 state_1 = nextState;
2075
2076 if (nextState.finished) {
2077 animateParam.destPos = _this._getFinalPos(animateParam.destPos, originalIntendedPos_1);
2078
2079 if (!equal(animateParam.destPos, _this.axisManager.get(Object.keys(animateParam.destPos)))) {
2080 _this.eventManager.triggerChange(animateParam.destPos, nextState.pos);
2081 }
2082
2083 complete();
2084 return;
2085 } else if (isCanceled) {
2086 _this.finish(false);
2087 } else {
2088 _this._raf = requestAnimationFrame(loop_1);
2089 }
2090 };
2091
2092 loop_1();
2093 } else {
2094 this.eventManager.triggerChange(param.destPos);
2095 complete();
2096 }
2097 };
2098 /**
2099 * Get estimated final value.
2100 *
2101 * If destPos is within the 'error range' of the original intended position, the initial intended position is returned.
2102 * - eg. original intended pos: 100, destPos: 100.0000000004 ==> return 100;
2103 * If dest Pos is outside the 'range of error' compared to the originally intended pos, it is returned rounded based on the originally intended pos.
2104 * - eg. original intended pos: 100.123 destPos: 50.12345 => return 50.123
2105 * @param originalIntendedPos
2106 * @param destPos
2107 */
2108
2109
2110 __proto._getFinalPos = function (destPos, originalIntendedPos) {
2111 var _this = this; // compare destPos and originalIntendedPos
2112 // eslint-disable-next-line @typescript-eslint/naming-convention
2113
2114
2115 var ERROR_LIMIT = 0.000001;
2116 var finalPos = map(destPos, function (value, key) {
2117 if (value >= originalIntendedPos[key] - ERROR_LIMIT && value <= originalIntendedPos[key] + ERROR_LIMIT) {
2118 // In error range, return original intended
2119 return originalIntendedPos[key];
2120 } else {
2121 // Out of error range, return rounded pos.
2122 var roundUnit = _this._getRoundUnit(value, key);
2123
2124 var result = roundNumber(value, roundUnit);
2125 return result;
2126 }
2127 });
2128 return finalPos;
2129 };
2130
2131 __proto._getRoundUnit = function (val, key) {
2132 var roundUnit = this._options.round; // manual mode
2133
2134 var minRoundUnit = null; // auto mode
2135 // auto mode
2136
2137 if (!roundUnit) {
2138 // Get minimum round unit
2139 var options = this.axisManager.getAxisOptions(key);
2140 minRoundUnit = inversePow(Math.max(getDecimalPlace(options.range[0]), getDecimalPlace(options.range[1]), getDecimalPlace(val)));
2141 }
2142
2143 return minRoundUnit || roundUnit;
2144 };
2145
2146 return AnimationManager;
2147}();
2148
2149var EasingManager =
2150/*#__PURE__*/
2151function (_super) {
2152 __extends(EasingManager, _super);
2153
2154 function EasingManager() {
2155 var _this = _super !== null && _super.apply(this, arguments) || this;
2156
2157 _this._useDuration = true;
2158 return _this;
2159 }
2160
2161 var __proto = EasingManager.prototype;
2162
2163 __proto.interpolate = function (displacement, threshold) {
2164 var initSlope = this._easing(0.00001) / 0.00001;
2165 return this._easing(displacement / (threshold * initSlope)) * threshold;
2166 };
2167
2168 __proto.updateAnimation = function (options) {
2169 var _a;
2170
2171 var animateParam = this._animateParam;
2172
2173 if (!animateParam) {
2174 return;
2175 }
2176
2177 var diffTime = new Date().getTime() - animateParam.startTime;
2178 var pos = (options === null || options === void 0 ? void 0 : options.destPos) || animateParam.destPos;
2179 var duration = (_a = options === null || options === void 0 ? void 0 : options.duration) !== null && _a !== void 0 ? _a : animateParam.duration;
2180
2181 if ((options === null || options === void 0 ? void 0 : options.restart) || duration <= diffTime) {
2182 this.setTo(pos, duration - diffTime);
2183 return;
2184 }
2185
2186 if (options === null || options === void 0 ? void 0 : options.destPos) {
2187 var currentPos = this.axisManager.get(); // When destination is changed, new delta should be calculated as remaining percent.
2188 // For example, moving x:0, y:0 to x:200, y:200 and it has current easing percent of 92%. coordinate is x:184 and y:184
2189 // If destination changes to x:300, y:300. xdelta:200, ydelta:200 changes to xdelta:116, ydelta:116 and use remaining easingPer as 100%, not 8% as previous.
2190 // Therefore, original easingPer by time is kept. And divided by (1 - self._initialEasingPer) which means new total easing percent. Like calculating 8% as 100%.
2191
2192 this._initialEasingPer = this._prevEasingPer;
2193 animateParam.delta = this.axisManager.getDelta(currentPos, pos);
2194 animateParam.destPos = pos;
2195 }
2196
2197 if (options === null || options === void 0 ? void 0 : options.duration) {
2198 var ratio = (diffTime + this._durationOffset) / animateParam.duration; // Use durationOffset for keeping animation ratio after duration is changed.
2199 // newRatio = (diffTime + newDurationOffset) / newDuration = oldRatio
2200 // newDurationOffset = oldRatio * newDuration - diffTime
2201
2202 this._durationOffset = ratio * duration - diffTime;
2203 animateParam.duration = duration;
2204 }
2205 };
2206
2207 __proto._initState = function (info) {
2208 this._initialEasingPer = 0;
2209 this._prevEasingPer = 0;
2210 this._durationOffset = 0;
2211 return {
2212 pos: info.depaPos,
2213 easingPer: 0,
2214 finished: false
2215 };
2216 };
2217
2218 __proto._getNextState = function (prevState) {
2219 var _this = this;
2220
2221 var animateParam = this._animateParam;
2222 var prevPos = prevState.pos;
2223 var destPos = animateParam.destPos;
2224 var directions = map(prevPos, function (value, key) {
2225 return value <= destPos[key] ? 1 : -1;
2226 });
2227 var diffTime = new Date().getTime() - animateParam.startTime;
2228 var ratio = (diffTime + this._durationOffset) / animateParam.duration;
2229
2230 var easingPer = this._easing(ratio);
2231
2232 var toPos = this.axisManager.map(prevPos, function (pos, options, key) {
2233 var nextPos = ratio >= 1 ? destPos[key] : pos + animateParam.delta[key] * (easingPer - _this._prevEasingPer) / (1 - _this._initialEasingPer); // Subtract distance from distance already moved.
2234 // Recalculate the remaining distance.
2235 // Fix the bouncing phenomenon by changing the range.
2236
2237 var circulatedPos = getCirculatedPos(nextPos, options.range, options.circular);
2238
2239 if (nextPos !== circulatedPos) {
2240 // circular
2241 var rangeOffset = directions[key] * (options.range[1] - options.range[0]);
2242 destPos[key] -= rangeOffset;
2243 prevPos[key] -= rangeOffset;
2244 }
2245
2246 return circulatedPos;
2247 });
2248 this._prevEasingPer = easingPer;
2249 return {
2250 pos: toPos,
2251 easingPer: easingPer,
2252 finished: easingPer >= 1
2253 };
2254 };
2255
2256 __proto._easing = function (p) {
2257 return p > 1 ? 1 : this._options.easing(p);
2258 };
2259
2260 return EasingManager;
2261}(AnimationManager);
2262
2263/**
2264 * @typedef {Object} AxisOption The Axis information. The key of the axis specifies the name to use as the logical virtual coordinate system.
2265 * @ko 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다.
2266 * @param {Number[]} [range] The range of coordinate <ko>좌표 범위</ko>
2267 * @param {Number} [range[0]=0] The coordinate of the minimum <ko>최소 좌표</ko>
2268 * @param {Number} [range[1]=0] The coordinate of the maximum <ko>최대 좌표</ko>
2269 * @param {Number} [startPos=range[0]] The coordinates to be moved when creating an instance <ko>인스턴스 생성시 이동할 좌표</ko>
2270 * @param {Number[]} [bounce] The size of bouncing area. The coordinates can exceed the coordinate area as much as the bouncing area based on user action. If the coordinates does not exceed the bouncing area when an element is dragged, the coordinates where bouncing effects are applied are retuned back into the coordinate area<ko>바운스 영역의 크기. 사용자의 동작에 따라 좌표가 좌표 영역을 넘어 바운스 영역의 크기만큼 더 이동할 수 있다. 사용자가 끌어다 놓는 동작을 했을 때 좌표가 바운스 영역에 있으면, 바운스 효과가 적용된 좌표가 다시 좌표 영역 안으로 들어온다</ko>
2271 * @param {Number} [bounce[0]=0] The size of coordinate of the minimum area <ko>최소 좌표 바운스 영역의 크기</ko>
2272 * @param {Number} [bounce[1]=0] The size of coordinate of the maximum area <ko>최대 좌표 바운스 영역의 크기</ko>
2273 * @param {Boolean[]} [circular] Indicates whether a circular element is available. If it is set to "true" and an element is dragged outside the coordinate area, the element will appear on the other side.<ko>순환 여부. 'true'로 설정한 방향의 좌표 영역 밖으로 엘리먼트가 이동하면 반대 방향에서 엘리먼트가 나타난다</ko>
2274 * @param {Boolean} [circular[0]=false] Indicates whether to circulate to the coordinate of the minimum <ko>최소 좌표 방향의 순환 여부</ko>
2275 * @param {Boolean} [circular[1]=false] Indicates whether to circulate to the coordinate of the maximum <ko>최대 좌표 방향의 순환 여부</ko>
2276 **/
2277
2278/**
2279 * @typedef {Object} AxesOption The option object of the eg.Axes module
2280 * @ko eg.Axes 모듈의 옵션 객체
2281 * @param {Function} [easing=easing.easeOutCubic] The easing function to apply to an animation <ko>애니메이션에 적용할 easing 함수</ko>
2282 * @param {Number} [maximumDuration=Infinity] Maximum duration of the animation <ko>가속도에 의해 애니메이션이 동작할 때의 최대 좌표 이동 시간</ko>
2283 * @param {Number} [minimumDuration=0] Minimum duration of the animation <ko>가속도에 의해 애니메이션이 동작할 때의 최소 좌표 이동 시간</ko>
2284 * @param {Number} [deceleration=0.0006] Deceleration of the animation where acceleration is manually enabled by user. A higher value indicates shorter running time. <ko>사용자의 동작으로 가속도가 적용된 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아진다</ko>
2285 * @param {Boolean} [interruptable=true] Indicates whether an animation is interruptible.
2286 * - true: It can be paused or stopped by user action or the API.
2287 * - false: It cannot be paused or stopped by user action or the API while it is running.
2288 * <ko>진행 중인 애니메이션 중지 가능 여부.
2289 * - true: 사용자의 동작이나 API로 애니메이션을 중지할 수 있다.
2290 * - false: 애니메이션이 진행 중일 때는 사용자의 동작이나 API가 적용되지 않는다</ko>
2291 * @param {Number} [round=null] Rounding unit. For example, 0.1 rounds to 0.1 decimal point(6.1234 => 6.1), 5 rounds to 5 (93 => 95)
2292 * [Details](https://github.com/naver/egjs-axes/wiki/round-option)<ko>반올림 단위. 예를 들어 0.1 은 소숫점 0.1 까지 반올림(6.1234 => 6.1), 5 는 5 단위로 반올림(93 => 95).
2293 * [상세내용](https://github.com/naver/egjs-axes/wiki/round-option)</ko>
2294 * @param {Boolean} [nested=false] Whether the event propagates to other instances when the coordinates reach the end of the movable area <ko>좌표가 이동 가능한 영역의 끝까지 도달했을 때 다른 인스턴스들로의 이벤트 전파 여부</ko>
2295 **/
2296
2297/**
2298 * A module used to change the information of user action entered by various input devices such as touch screen or mouse into the logical virtual coordinates. You can easily create a UI that responds to user actions.
2299 * @ko 터치 입력 장치나 마우스와 같은 다양한 입력 장치를 통해 전달 받은 사용자의 동작을 논리적인 가상 좌표로 변경하는 모듈이다. 사용자 동작에 반응하는 UI를 손쉽게 만들수 있다.
2300 * @extends eg.Component
2301 *
2302 * @param {Object.<string, AxisOption>} axis Axis information managed by eg.Axes. The key of the axis specifies the name to use as the logical virtual coordinate system. <ko>eg.Axes가 관리하는 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다.</ko>
2303 * @param {AxesOption} [options={}] The option object of the eg.Axes module<ko>eg.Axes 모듈의 옵션 객체</ko>
2304 * @param {Object.<string, number>} [startPos={}] The coordinates to be moved when creating an instance. It is applied with higher priority than startPos of axisOption.<ko>인스턴스 생성시 이동할 좌표, axisOption의 startPos보다 높은 우선순위로 적용된다.</ko>
2305 *
2306 * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"}
2307 * @example
2308 * ```js
2309 * // 1. Initialize eg.Axes
2310 * const axes = new eg.Axes({
2311 * something1: {
2312 * range: [0, 150],
2313 * bounce: 50
2314 * },
2315 * something2: {
2316 * range: [0, 200],
2317 * bounce: 100
2318 * },
2319 * somethingN: {
2320 * range: [1, 10],
2321 * }
2322 * }, {
2323 * deceleration : 0.0024
2324 * });
2325 *
2326 * // 2. attach event handler
2327 * axes.on({
2328 * "hold" : function(evt) {
2329 * },
2330 * "release" : function(evt) {
2331 * },
2332 * "animationStart" : function(evt) {
2333 * },
2334 * "animationEnd" : function(evt) {
2335 * },
2336 * "change" : function(evt) {
2337 * }
2338 * });
2339 *
2340 * // 3. Initialize inputTypes
2341 * const panInputArea = new eg.Axes.PanInput("#area", {
2342 * scale: [0.5, 1]
2343 * });
2344 * const panInputHmove = new eg.Axes.PanInput("#hmove");
2345 * const panInputVmove = new eg.Axes.PanInput("#vmove");
2346 * const pinchInputArea = new eg.Axes.PinchInput("#area", {
2347 * scale: 1.5
2348 * });
2349 *
2350 * // 4. Connect eg.Axes and InputTypes
2351 * // [PanInput] When the mouse or touchscreen is down and moved.
2352 * // Connect the 'something2' axis to the mouse or touchscreen x position and
2353 * // connect the 'somethingN' axis to the mouse or touchscreen y position.
2354 * axes.connect(["something2", "somethingN"], panInputArea); // or axes.connect("something2 somethingN", panInputArea);
2355 *
2356 * // Connect only one 'something1' axis to the mouse or touchscreen x position.
2357 * axes.connect(["something1"], panInputHmove); // or axes.connect("something1", panInputHmove);
2358 *
2359 * // Connect only one 'something2' axis to the mouse or touchscreen y position.
2360 * axes.connect(["", "something2"], panInputVmove); // or axes.connect(" something2", panInputVmove);
2361 *
2362 * // [PinchInput] Connect 'something2' axis when two pointers are moving toward (zoom-in) or away from each other (zoom-out).
2363 * axes.connect("something2", pinchInputArea);
2364 * ```
2365 */
2366
2367var Axes =
2368/*#__PURE__*/
2369function (_super) {
2370 __extends(Axes, _super);
2371 /**
2372 *
2373 */
2374
2375
2376 function Axes(axis, options, startPos) {
2377 if (axis === void 0) {
2378 axis = {};
2379 }
2380
2381 if (options === void 0) {
2382 options = {};
2383 }
2384
2385 if (startPos === void 0) {
2386 startPos = {};
2387 }
2388
2389 var _this = _super.call(this) || this;
2390
2391 _this.axis = axis;
2392 _this._inputs = [];
2393 _this.options = __assign({
2394 easing: function (x) {
2395 return 1 - Math.pow(1 - x, 3);
2396 },
2397 interruptable: true,
2398 maximumDuration: Infinity,
2399 minimumDuration: 0,
2400 deceleration: 0.0006,
2401 round: null,
2402 nested: false
2403 }, options);
2404 Object.keys(startPos).forEach(function (key) {
2405 _this.axis[key].startPos = startPos[key];
2406 });
2407 _this.interruptManager = new InterruptManager(_this.options);
2408 _this.axisManager = new AxisManager(_this.axis);
2409 _this.eventManager = new EventManager(_this);
2410 _this.animationManager = new EasingManager(_this);
2411 _this.inputObserver = new InputObserver(_this);
2412
2413 _this.eventManager.setAnimationManager(_this.animationManager);
2414
2415 _this.eventManager.triggerChange(_this.axisManager.get());
2416
2417 return _this;
2418 }
2419 /**
2420 * Connect the axis of eg.Axes to the inputType.
2421 * @ko eg.Axes의 축과 inputType을 연결한다
2422 * @param {(String[]|String)} axes The name of the axis to associate with inputType <ko>inputType과 연결할 축의 이름</ko>
2423 * @param {Object} inputType The inputType instance to associate with the axis of eg.Axes <ko>eg.Axes의 축과 연결할 inputType 인스턴스</ko>
2424 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
2425 * @example
2426 * ```js
2427 * const axes = new eg.Axes({
2428 * "x": {
2429 * range: [0, 100]
2430 * },
2431 * "xOther": {
2432 * range: [-100, 100]
2433 * }
2434 * });
2435 *
2436 * axes.connect("x", new eg.Axes.PanInput("#area1"))
2437 * .connect("x xOther", new eg.Axes.PanInput("#area2"))
2438 * .connect(" xOther", new eg.Axes.PanInput("#area3"))
2439 * .connect(["x"], new eg.Axes.PanInput("#area4"))
2440 * .connect(["xOther", "x"], new eg.Axes.PanInput("#area5"))
2441 * .connect(["", "xOther"], new eg.Axes.PanInput("#area6"));
2442 * ```
2443 */
2444
2445
2446 var __proto = Axes.prototype;
2447
2448 __proto.connect = function (axes, inputType) {
2449 var mapped;
2450
2451 if (typeof axes === "string") {
2452 mapped = axes.split(" ");
2453 } else {
2454 mapped = axes.concat();
2455 } // check same instance
2456
2457
2458 if (~this._inputs.indexOf(inputType)) {
2459 this.disconnect(inputType);
2460 }
2461
2462 inputType.mapAxes(mapped);
2463 inputType.connect(this.inputObserver);
2464
2465 this._inputs.push(inputType);
2466
2467 return this;
2468 };
2469 /**
2470 * Disconnect the axis of eg.Axes from the inputType.
2471 * @ko eg.Axes의 축과 inputType의 연결을 끊는다.
2472 * @param {Object} [inputType] An inputType instance associated with the axis of eg.Axes <ko>eg.Axes의 축과 연결한 inputType 인스턴스</ko>
2473 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
2474 * @example
2475 * ```js
2476 * const axes = new eg.Axes({
2477 * "x": {
2478 * range: [0, 100]
2479 * },
2480 * "xOther": {
2481 * range: [-100, 100]
2482 * }
2483 * });
2484 *
2485 * const input1 = new eg.Axes.PanInput("#area1");
2486 * const input2 = new eg.Axes.PanInput("#area2");
2487 * const input3 = new eg.Axes.PanInput("#area3");
2488 *
2489 * axes.connect("x", input1);
2490 * .connect("x xOther", input2)
2491 * .connect(["xOther", "x"], input3);
2492 *
2493 * axes.disconnect(input1); // disconnects input1
2494 * axes.disconnect(); // disconnects all of them
2495 * ```
2496 */
2497
2498
2499 __proto.disconnect = function (inputType) {
2500 if (inputType) {
2501 var index = this._inputs.indexOf(inputType);
2502
2503 if (index >= 0) {
2504 this._inputs[index].disconnect();
2505
2506 this._inputs.splice(index, 1);
2507 }
2508 } else {
2509 this._inputs.forEach(function (v) {
2510 return v.disconnect();
2511 });
2512
2513 this._inputs = [];
2514 }
2515
2516 return this;
2517 };
2518 /**
2519 * Returns the current position of the coordinates.
2520 * @ko 좌표의 현재 위치를 반환한다
2521 * @param {Object} [axes] The names of the axis <ko>축 이름들</ko>
2522 * @return {Object.<string, number>} Axis coordinate information <ko>축 좌표 정보</ko>
2523 * @example
2524 * ```js
2525 * const axes = new eg.Axes({
2526 * "x": {
2527 * range: [0, 100]
2528 * },
2529 * "xOther": {
2530 * range: [-100, 100]
2531 * },
2532 * "zoom": {
2533 * range: [50, 30]
2534 * }
2535 * });
2536 *
2537 * axes.get(); // {"x": 0, "xOther": -100, "zoom": 50}
2538 * axes.get(["x", "zoom"]); // {"x": 0, "zoom": 50}
2539 * ```
2540 */
2541
2542
2543 __proto.get = function (axes) {
2544 return this.axisManager.get(axes);
2545 };
2546 /**
2547 * Moves an axis to specific coordinates.
2548 * @ko 좌표를 이동한다.
2549 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko>
2550 * @param {Number} [duration=0] Duration of the animation (unit: ms) <ko>애니메이션 진행 시간(단위: ms)</ko>
2551 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
2552 * @example
2553 * ```js
2554 * const axes = new eg.Axes({
2555 * "x": {
2556 * range: [0, 100]
2557 * },
2558 * "xOther": {
2559 * range: [-100, 100]
2560 * },
2561 * "zoom": {
2562 * range: [50, 30]
2563 * }
2564 * });
2565 *
2566 * axes.setTo({"x": 30, "zoom": 60});
2567 * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60}
2568 *
2569 * axes.setTo({"x": 100, "xOther": 60}, 1000); // animatation
2570 *
2571 * // after 1000 ms
2572 * axes.get(); // {"x": 100, "xOther": 60, "zoom": 60}
2573 * ```
2574 */
2575
2576
2577 __proto.setTo = function (pos, duration) {
2578 if (duration === void 0) {
2579 duration = 0;
2580 }
2581
2582 this.animationManager.setTo(pos, duration);
2583 return this;
2584 };
2585 /**
2586 * Moves an axis from the current coordinates to specific coordinates.
2587 * @ko 현재 좌표를 기준으로 좌표를 이동한다.
2588 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko>
2589 * @param {Number} [duration=0] Duration of the animation (unit: ms) <ko>애니메이션 진행 시간(단위: ms)</ko>
2590 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
2591 * @example
2592 * ```js
2593 * const axes = new eg.Axes({
2594 * "x": {
2595 * range: [0, 100]
2596 * },
2597 * "xOther": {
2598 * range: [-100, 100]
2599 * },
2600 * "zoom": {
2601 * range: [50, 30]
2602 * }
2603 * });
2604 *
2605 * axes.setBy({"x": 30, "zoom": 10});
2606 * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60}
2607 *
2608 * axes.setBy({"x": 70, "xOther": 60}, 1000); // animatation
2609 *
2610 * // after 1000 ms
2611 * axes.get(); // {"x": 100, "xOther": -40, "zoom": 60}
2612 * ```
2613 */
2614
2615
2616 __proto.setBy = function (pos, duration) {
2617 if (duration === void 0) {
2618 duration = 0;
2619 }
2620
2621 this.animationManager.setBy(pos, duration);
2622 return this;
2623 };
2624 /**
2625 * Change the options of Axes instance.
2626 * @ko 인스턴스의 옵션을 변경한다.
2627 * @param {AxesOption} options Axes options to change <ko>변경할 옵션 목록</ko>
2628 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
2629 * @example
2630 * ```js
2631 * const axes = new eg.Axes({
2632 * "x": {
2633 * range: [0, 100]
2634 * },
2635 * }, {
2636 * round: 10,
2637 * });
2638 *
2639 * axes.setTo({"x": 48});
2640 * axes.get(); // {"x": 50}
2641 *
2642 * axes.setOptions({
2643 * round: 1,
2644 * });
2645 *
2646 * axes.setTo({"x": 48});
2647 * axes.get(); // {"x": 48}
2648 * ```
2649 */
2650
2651
2652 __proto.setOptions = function (options) {
2653 this.options = __assign(__assign({}, this.options), options);
2654 return this;
2655 };
2656 /**
2657 * Change the information of an existing axis.
2658 * @ko 존재하는 축의 정보를 변경한다.
2659 * @param {Object.<string, AxisOption>} axis Axis options to change <ko>변경할 축의 정보</ko>
2660 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
2661 * @example
2662 * ```js
2663 * const axes = new eg.Axes({
2664 * "x": {
2665 * range: [0, 100]
2666 * },
2667 * });
2668 *
2669 * axes.setTo({"x": 150});
2670 * axes.get(); // {"x": 100}
2671 *
2672 * axes.setAxis({
2673 * "x": {
2674 * range: [0, 200]
2675 * },
2676 * });
2677 *
2678 * axes.setTo({"x": 150});
2679 * axes.get(); // {"x": 150}
2680 * ```
2681 */
2682
2683
2684 __proto.setAxis = function (axis) {
2685 this.axisManager.setAxis(axis);
2686 return this;
2687 };
2688 /**
2689 * Stop an animation in progress.
2690 * @ko 재생 중인 애니메이션을 정지한다.
2691 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
2692 * @example
2693 * ```js
2694 * const axes = new eg.Axes({
2695 * "x": {
2696 * range: [0, 100]
2697 * },
2698 * });
2699 *
2700 * axes.setTo({"x": 10}, 1000); // start animatation
2701 *
2702 * // after 500 ms
2703 * axes.stopAnimation(); // stop animation during movement.
2704 * ```
2705 */
2706
2707
2708 __proto.stopAnimation = function () {
2709 this.animationManager.stopAnimation();
2710 this.animationManager.finish(false);
2711 return this;
2712 };
2713 /**
2714 * Change the destination of an animation in progress.
2715 * @ko 재생 중인 애니메이션의 목적지와 진행 시간을 변경한다.
2716 * @param {UpdateAnimationOption} pos The coordinate to move to <ko>이동할 좌표</ko>
2717 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
2718 * @example
2719 * ```js
2720 * const axes = new eg.Axes({
2721 * "x": {
2722 * range: [0, 200]
2723 * },
2724 * "y": {
2725 * range: [0, 200]
2726 * }
2727 * });
2728 *
2729 * axes.setTo({"x": 50, "y": 50}, 1000); // trigger animation by setTo
2730 *
2731 * // after 500 ms
2732 * axes.updateAnimation({destPos: {"x": 100, "y": 100}}); // animation will end after 500 ms, at {"x": 100, "y": 100}
2733 *
2734 * // after 500 ms
2735 * axes.setTo({"x": 50, "y": 50}, 1000); // trigger animation by setTo
2736 *
2737 * // after 700 ms
2738 * axes.updateAnimation({destPos: {"x": 100, "y": 100}, duration: 1500, restart: true}); // this works same as axes.setTo({"x": 100, "y": 100}, 800) since restart is true.
2739 * ```
2740 */
2741
2742
2743 __proto.updateAnimation = function (options) {
2744 this.animationManager.updateAnimation(options);
2745 return this;
2746 };
2747 /**
2748 * Returns whether there is a coordinate in the bounce area of ​​the target axis.
2749 * @ko 대상 축 중 bounce영역에 좌표가 존재하는지를 반환한다
2750 * @param {Object} [axes] The names of the axis <ko>축 이름들</ko>
2751 * @return {Boolen} Whether the bounce area exists. <ko>bounce 영역 존재 여부</ko>
2752 * @example
2753 * ```js
2754 * const axes = new eg.Axes({
2755 * "x": {
2756 * range: [0, 100]
2757 * },
2758 * "xOther": {
2759 * range: [-100, 100]
2760 * },
2761 * "zoom": {
2762 * range: [50, 30]
2763 * }
2764 * });
2765 *
2766 * axes.isBounceArea(["x"]);
2767 * axes.isBounceArea(["x", "zoom"]);
2768 * axes.isBounceArea();
2769 * ```
2770 */
2771
2772
2773 __proto.isBounceArea = function (axes) {
2774 return this.axisManager.isOutside(axes);
2775 };
2776 /**
2777 * Destroys properties, and events used in a module and disconnect all connections to inputTypes.
2778 * @ko 모듈에 사용한 속성, 이벤트를 해제한다. 모든 inputType과의 연결을 끊는다.
2779 */
2780
2781
2782 __proto.destroy = function () {
2783 this.disconnect();
2784 this.eventManager.destroy();
2785 };
2786 /**
2787 * @name VERSION
2788 * @desc Version info string
2789 * @ko 버전정보 문자열
2790 *
2791 * @constant
2792 * @type {String}
2793 * @example
2794 * ```js
2795 * eg.Axes.VERSION; // ex) 3.3.3
2796 * ```
2797 */
2798
2799
2800 Axes.VERSION = "3.8.3";
2801 /* eslint-enable */
2802
2803 /**
2804 * @name TRANSFORM
2805 * @desc Returns the transform attribute with CSS vendor prefixes.
2806 * @ko CSS vendor prefixes를 붙인 transform 속성을 반환한다.
2807 *
2808 * @constant
2809 * @type {String}
2810 * @example
2811 * ```js
2812 * eg.Axes.TRANSFORM; // "transform" or "webkitTransform"
2813 * ```
2814 */
2815
2816 Axes.TRANSFORM = TRANSFORM;
2817 /**
2818 * @name DIRECTION_NONE
2819 * @constant
2820 * @type {Number}
2821 */
2822
2823 Axes.DIRECTION_NONE = DIRECTION_NONE;
2824 /**
2825 * @name DIRECTION_LEFT
2826 * @constant
2827 * @type {Number}
2828 */
2829
2830 Axes.DIRECTION_LEFT = DIRECTION_LEFT;
2831 /**
2832 * @name DIRECTION_RIGHT
2833 * @constant
2834 * @type {Number}
2835 */
2836
2837 Axes.DIRECTION_RIGHT = DIRECTION_RIGHT;
2838 /**
2839 * @name DIRECTION_UP
2840 * @constant
2841 * @type {Number}
2842 */
2843
2844 Axes.DIRECTION_UP = DIRECTION_UP;
2845 /**
2846 * @name DIRECTION_DOWN
2847 * @constant
2848 * @type {Number}
2849 */
2850
2851 Axes.DIRECTION_DOWN = DIRECTION_DOWN;
2852 /**
2853 * @name DIRECTION_HORIZONTAL
2854 * @constant
2855 * @type {Number}
2856 */
2857
2858 Axes.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL;
2859 /**
2860 * @name DIRECTION_VERTICAL
2861 * @constant
2862 * @type {Number}
2863 */
2864
2865 Axes.DIRECTION_VERTICAL = DIRECTION_VERTICAL;
2866 /**
2867 * @name DIRECTION_ALL
2868 * @constant
2869 * @type {Number}
2870 */
2871
2872 Axes.DIRECTION_ALL = DIRECTION_ALL;
2873 Axes = __decorate([core.ReactiveSubscribe], Axes);
2874 return Axes;
2875}(Component);
2876
2877/*
2878 * Copyright (c) 2015 NAVER Corp.
2879 * egjs projects are licensed under the MIT license
2880 */
2881
2882var getDirectionByAngle = function (angle, thresholdAngle) {
2883 if (thresholdAngle < 0 || thresholdAngle > 90) {
2884 return DIRECTION_NONE;
2885 }
2886
2887 var toAngle = Math.abs(angle);
2888 return toAngle > thresholdAngle && toAngle < 180 - thresholdAngle ? DIRECTION_VERTICAL : DIRECTION_HORIZONTAL;
2889};
2890/**
2891 * @typedef {Object} PanInputOption The option object of the eg.Axes.PanInput module.
2892 * @ko eg.Axes.PanInput 모듈의 옵션 객체
2893 * @param {String[]} [inputType=["touch", "mouse", "pointer"]] Types of input devices
2894 * - touch: Touch screen
2895 * - mouse: Mouse
2896 * - pointer: Mouse and touch <ko>입력 장치 종류
2897 * - touch: 터치 입력 장치
2898 * - mouse: 마우스
2899 * - pointer: 마우스 및 터치</ko>
2900 * @param {String[]} [inputKey=["any"]] List of key combinations to allow input
2901 * - any: any key
2902 * - shift: shift key
2903 * - ctrl: ctrl key and pinch gesture on the trackpad
2904 * - alt: alt key
2905 * - meta: meta key
2906 * - none: none of these keys are pressed <ko>입력을 허용할 키 조합 목록
2907 * - any: 아무 키
2908 * - shift: shift 키
2909 * - ctrl: ctrl 키 및 트랙패드의 pinch 제스쳐
2910 * - alt: alt 키
2911 * - meta: meta 키
2912 * - none: 아무 키도 눌리지 않은 상태 </ko>
2913 * @param {String[]} [inputButton=["left"]] List of buttons to allow input
2914 * - left: Left mouse button and normal touch
2915 * - middle: Mouse wheel press
2916 * - right: Right mouse button <ko>입력을 허용할 버튼 목록
2917 * - left: 마우스 왼쪽 버튼
2918 * - middle: 마우스 휠 눌림
2919 * - right: 마우스 오른쪽 버튼 </ko>
2920 * @param {Number[]} [scale] Coordinate scale that a user can move<ko>사용자의 동작으로 이동하는 좌표의 배율</ko>
2921 * @param {Number} [scale[0]=1] horizontal axis scale <ko>수평축 배율</ko>
2922 * @param {Number} [scale[1]=1] vertical axis scale <ko>수직축 배율</ko>
2923 * @param {Number} [thresholdAngle=45] The threshold value that determines whether user action is horizontal or vertical (0~90) <ko>사용자의 동작이 가로 방향인지 세로 방향인지 판단하는 기준 각도(0~90)</ko>
2924 * @param {Number} [threshold=0] Minimal pan distance required before recognizing <ko>사용자의 Pan 동작을 인식하기 위해산 최소한의 거리</ko>
2925 * @param {Boolean} [preventClickOnDrag=false] Whether to cancel the {@link https://developer.mozilla.org/en/docs/Web/API/Element/click_event click} event when the user finishes dragging more than 1 pixel <ko>사용자가 1픽셀 이상 드래그를 마쳤을 때 {@link https://developer.mozilla.org/ko/docs/Web/API/Element/click_event click} 이벤트 취소 여부</ko>
2926 * @param {Number} [iOSEdgeSwipeThreshold=30] Area (px) that can go to the next page when swiping the right edge in iOS safari <ko>iOS Safari에서 오른쪽 엣지를 스와이프 하는 경우 다음 페이지로 넘어갈 수 있는 영역(px)</ko>
2927 * @param {String} [touchAction=null] Value that overrides the element's "touch-action" css property. If set to null, it is automatically set to prevent scrolling in the direction of the connected axis. <ko>엘리먼트의 "touch-action" CSS 속성을 덮어쓰는 값. 만약 null로 설정된 경우, 연결된 축 방향으로의 스크롤을 방지하게끔 자동으로 설정된다.</ko>
2928 **/
2929
2930/**
2931 * A module that passes the amount of change to eg.Axes when the mouse or touchscreen is down and moved. use less than two axes.
2932 * @ko 마우스나 터치 스크린을 누르고 움직일때의 변화량을 eg.Axes에 전달하는 모듈. 두개 이하의 축을 사용한다.
2933 *
2934 * @example
2935 * ```js
2936 * const pan = new eg.Axes.PanInput("#area", {
2937 * inputType: ["touch"],
2938 * scale: [1, 1.3],
2939 * });
2940 *
2941 * // Connect the 'something2' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved.
2942 * // Connect the 'somethingN' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved.
2943 * axes.connect(["something2", "somethingN"], pan); // or axes.connect("something2 somethingN", pan);
2944 *
2945 * // Connect only one 'something1' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved.
2946 * axes.connect(["something1"], pan); // or axes.connect("something1", pan);
2947 *
2948 * // Connect only one 'something2' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved.
2949 * axes.connect(["", "something2"], pan); // or axes.connect(" something2", pan);
2950 * ```
2951 * @param {String|HTMLElement|Ref<HTMLElement>|jQuery} element An element to use the eg.Axes.PanInput module <ko>eg.Axes.PanInput 모듈을 사용할 엘리먼트</ko>
2952 * @param {PanInputOption} [options={}] The option object of the eg.Axes.PanInput module<ko>eg.Axes.PanInput 모듈의 옵션 객체</ko>
2953 */
2954
2955var PanInput =
2956/*#__PURE__*/
2957function () {
2958 /**
2959 *
2960 */
2961 function PanInput(el, options) {
2962 var _this = this;
2963
2964 this.axes = [];
2965 this.element = null;
2966 this._enabled = false;
2967 this._activeEvent = null;
2968 this._atRightEdge = false;
2969 this._rightEdgeTimer = 0;
2970 this._dragged = false;
2971 this._isOverThreshold = false;
2972
2973 this._preventClickWhenDragged = function (e) {
2974 if (_this._dragged) {
2975 e.preventDefault();
2976 e.stopPropagation();
2977 }
2978
2979 _this._dragged = false;
2980 };
2981
2982 this._voidFunction = function () {};
2983
2984 this.element = $(el);
2985 this.options = __assign({
2986 inputType: ["touch", "mouse", "pointer"],
2987 inputKey: [ANY],
2988 inputButton: [MOUSE_LEFT],
2989 scale: [1, 1],
2990 thresholdAngle: 45,
2991 threshold: 0,
2992 preventClickOnDrag: false,
2993 iOSEdgeSwipeThreshold: IOS_EDGE_THRESHOLD,
2994 releaseOnScroll: false,
2995 touchAction: null
2996 }, options);
2997 this._onPanstart = this._onPanstart.bind(this);
2998 this._onPanmove = this._onPanmove.bind(this);
2999 this._onPanend = this._onPanend.bind(this);
3000 }
3001
3002 var __proto = PanInput.prototype;
3003
3004 __proto.mapAxes = function (axes) {
3005 this._direction = getDirection(!!axes[0], !!axes[1]);
3006 this.axes = axes;
3007 };
3008
3009 __proto.connect = function (observer) {
3010 if (this._activeEvent) {
3011 this._detachElementEvent();
3012
3013 this._detachWindowEvent(this._activeEvent);
3014 }
3015
3016 this._attachElementEvent(observer);
3017
3018 this._originalCssProps = setCssProps(this.element, this.options, this._direction);
3019 return this;
3020 };
3021
3022 __proto.disconnect = function () {
3023 this._detachElementEvent();
3024
3025 this._detachWindowEvent(this._activeEvent);
3026
3027 if (!isCssPropsFromAxes(this._originalCssProps)) {
3028 revertCssProps(this.element, this._originalCssProps);
3029 }
3030
3031 this._direction = DIRECTION_NONE;
3032 return this;
3033 };
3034 /**
3035 * Destroys elements, properties, and events used in a module.
3036 * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다.
3037 */
3038
3039
3040 __proto.destroy = function () {
3041 this.disconnect();
3042 this.element = null;
3043 };
3044 /**
3045 * Enables input devices
3046 * @ko 입력 장치를 사용할 수 있게 한다
3047 * @return {PanInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
3048 */
3049
3050
3051 __proto.enable = function () {
3052 this._enabled = true;
3053 return this;
3054 };
3055 /**
3056 * Disables input devices
3057 * @ko 입력 장치를 사용할 수 없게 한다.
3058 * @return {PanInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
3059 */
3060
3061
3062 __proto.disable = function () {
3063 this._enabled = false;
3064 return this;
3065 };
3066 /**
3067 * Returns whether to use an input device
3068 * @ko 입력 장치 사용 여부를 반환한다.
3069 * @return {Boolean} Whether to use an input device <ko>입력장치 사용여부</ko>
3070 */
3071
3072
3073 __proto.isEnabled = function () {
3074 return this._enabled;
3075 };
3076 /**
3077 * Releases current user input.
3078 * @ko 사용자의 입력을 강제로 중단시킨다.
3079 * @return {PanInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
3080 */
3081
3082
3083 __proto.release = function () {
3084 var activeEvent = this._activeEvent;
3085 var prevEvent = activeEvent.prevEvent;
3086 activeEvent.onRelease();
3087
3088 this._observer.release(this, prevEvent, [0, 0]);
3089
3090 this._detachWindowEvent(activeEvent);
3091
3092 return this;
3093 };
3094
3095 __proto._onPanstart = function (event) {
3096 var _a = this.options,
3097 inputKey = _a.inputKey,
3098 inputButton = _a.inputButton;
3099 var activeEvent = this._activeEvent;
3100 var panEvent = activeEvent.onEventStart(event, inputKey, inputButton);
3101
3102 if (!panEvent || !this._enabled || activeEvent.getTouches(event, inputButton) > 1) {
3103 return;
3104 }
3105
3106 if (panEvent.srcEvent.cancelable !== false) {
3107 var edgeThreshold = this.options.iOSEdgeSwipeThreshold;
3108 this._dragged = false;
3109 this._isOverThreshold = false;
3110
3111 this._observer.hold(this, panEvent);
3112
3113 this._atRightEdge = IS_IOS_SAFARI && panEvent.center.x > window.innerWidth - edgeThreshold;
3114
3115 this._attachWindowEvent(activeEvent);
3116
3117 activeEvent.prevEvent = panEvent;
3118 }
3119 };
3120
3121 __proto._onPanmove = function (event) {
3122 var _this = this;
3123
3124 var _a = this.options,
3125 iOSEdgeSwipeThreshold = _a.iOSEdgeSwipeThreshold,
3126 preventClickOnDrag = _a.preventClickOnDrag,
3127 releaseOnScroll = _a.releaseOnScroll,
3128 inputKey = _a.inputKey,
3129 inputButton = _a.inputButton,
3130 threshold = _a.threshold,
3131 thresholdAngle = _a.thresholdAngle;
3132 var activeEvent = this._activeEvent;
3133 var panEvent = activeEvent.onEventMove(event, inputKey, inputButton);
3134 var touches = activeEvent.getTouches(event, inputButton);
3135
3136 if (touches === 0 || releaseOnScroll && panEvent && !panEvent.srcEvent.cancelable) {
3137 this._onPanend(event);
3138
3139 return;
3140 }
3141
3142 if (!panEvent || !this._enabled || touches > 1) {
3143 return;
3144 }
3145
3146 var userDirection = getDirectionByAngle(panEvent.angle, thresholdAngle);
3147 var useHorizontal = useDirection(DIRECTION_HORIZONTAL, this._direction, userDirection);
3148 var useVertical = useDirection(DIRECTION_VERTICAL, this._direction, userDirection);
3149
3150 if (activeEvent.prevEvent && IS_IOS_SAFARI) {
3151 var swipeLeftToRight = panEvent.center.x < 0;
3152
3153 if (swipeLeftToRight) {
3154 // iOS swipe left => right
3155 this.release();
3156 return;
3157 } else if (this._atRightEdge) {
3158 clearTimeout(this._rightEdgeTimer); // - is right to left
3159
3160 var swipeRightToLeft = panEvent.deltaX < -iOSEdgeSwipeThreshold;
3161
3162 if (swipeRightToLeft) {
3163 this._atRightEdge = false;
3164 } else {
3165 // iOS swipe right => left
3166 this._rightEdgeTimer = window.setTimeout(function () {
3167 return _this.release();
3168 }, 100);
3169 }
3170 }
3171 }
3172
3173 var distance = this._getDistance([panEvent.deltaX, panEvent.deltaY], [useHorizontal, useVertical]);
3174
3175 var offset = this._getOffset([panEvent.offsetX, panEvent.offsetY], [useHorizontal, useVertical]);
3176
3177 var prevent = offset.some(function (v) {
3178 return v !== 0;
3179 });
3180
3181 if (prevent) {
3182 if (panEvent.srcEvent.cancelable !== false) {
3183 panEvent.srcEvent.preventDefault();
3184 }
3185
3186 panEvent.srcEvent.stopPropagation();
3187 }
3188
3189 panEvent.preventSystemEvent = prevent;
3190
3191 if (prevent && (this._isOverThreshold || distance >= threshold)) {
3192 this._dragged = preventClickOnDrag;
3193 this._isOverThreshold = true;
3194
3195 this._observer.change(this, panEvent, toAxis(this.axes, offset));
3196 }
3197
3198 activeEvent.prevEvent = panEvent;
3199 };
3200
3201 __proto._onPanend = function (event) {
3202 var inputButton = this.options.inputButton;
3203 var activeEvent = this._activeEvent;
3204 activeEvent.onEventEnd(event);
3205
3206 if (!this._enabled || activeEvent.getTouches(event, inputButton) !== 0) {
3207 return;
3208 }
3209
3210 this._detachWindowEvent(activeEvent);
3211
3212 clearTimeout(this._rightEdgeTimer);
3213 var prevEvent = activeEvent.prevEvent;
3214 var velocity = this._isOverThreshold ? this._getOffset([Math.abs(prevEvent.velocityX) * (prevEvent.offsetX < 0 ? -1 : 1), Math.abs(prevEvent.velocityY) * (prevEvent.offsetY < 0 ? -1 : 1)], [useDirection(DIRECTION_HORIZONTAL, this._direction), useDirection(DIRECTION_VERTICAL, this._direction)]) : [0, 0];
3215 activeEvent.onRelease();
3216
3217 this._observer.release(this, prevEvent, velocity);
3218 };
3219
3220 __proto._attachWindowEvent = function (activeEvent) {
3221 var _this = this;
3222
3223 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) {
3224 window.addEventListener(event, _this._onPanmove, getAddEventOptions(event));
3225 });
3226 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) {
3227 window.addEventListener(event, _this._onPanend, getAddEventOptions(event));
3228 });
3229 };
3230
3231 __proto._detachWindowEvent = function (activeEvent) {
3232 var _this = this;
3233
3234 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) {
3235 window.removeEventListener(event, _this._onPanmove);
3236 });
3237 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) {
3238 window.removeEventListener(event, _this._onPanend);
3239 });
3240 };
3241
3242 __proto._getOffset = function (properties, direction) {
3243 var scale = this.options.scale;
3244 return [direction[0] ? properties[0] * scale[0] : 0, direction[1] ? properties[1] * scale[1] : 0];
3245 };
3246
3247 __proto._getDistance = function (delta, direction) {
3248 return Math.sqrt(Number(direction[0]) * Math.pow(delta[0], 2) + Number(direction[1]) * Math.pow(delta[1], 2));
3249 };
3250
3251 __proto._attachElementEvent = function (observer) {
3252 var _this = this;
3253
3254 var activeEvent = convertInputType(this.options.inputType);
3255 var element = this.element;
3256
3257 if (!activeEvent) {
3258 return;
3259 }
3260
3261 if (!element) {
3262 throw new Error("Element to connect input does not exist.");
3263 }
3264
3265 this._observer = observer;
3266 this._enabled = true;
3267 this._activeEvent = activeEvent;
3268 element.addEventListener("click", this._preventClickWhenDragged, true);
3269 activeEvent.start.forEach(function (event) {
3270 element.addEventListener(event, _this._onPanstart);
3271 }); // adding event listener to element prevents invalid behavior in iOS Safari
3272
3273 activeEvent.move.forEach(function (event) {
3274 element.addEventListener(event, _this._voidFunction);
3275 });
3276 };
3277
3278 __proto._detachElementEvent = function () {
3279 var _this = this;
3280
3281 var activeEvent = this._activeEvent;
3282 var element = this.element;
3283
3284 if (element) {
3285 element.removeEventListener("click", this._preventClickWhenDragged, true);
3286 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.start.forEach(function (event) {
3287 element.removeEventListener(event, _this._onPanstart);
3288 });
3289 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) {
3290 element.removeEventListener(event, _this._voidFunction);
3291 });
3292 }
3293
3294 this._enabled = false;
3295 this._observer = null;
3296 };
3297
3298 return PanInput;
3299}();
3300
3301/**
3302 * A module that passes the angle moved by touch to Axes and uses one axis of rotation.
3303 * [Details](https://github.com/naver/egjs-axes/wiki/RotatePanInput)
3304 * @ko 터치에 의해 움직인 각도를 Axes 에 전달하며 1개의 회전축만 사용한다.
3305 * [상세내용](https://github.com/naver/egjs-axes/wiki/RotatePanInput-%7C-%ED%95%9C%EA%B5%AD%EC%96%B4)
3306 *
3307 * @example
3308 * ```js
3309 * const input = new eg.Axes.RotatePanInput("#area");
3310 *
3311 * var axes = new eg.Axes({
3312 * // property name('angle') could be anything you want (eg. x, y, z...)
3313 * angle: {
3314 * range: [-180, 180] // from -180deg to 180deg
3315 * }
3316 * });
3317 *
3318 * axes.connect("angle", input)
3319 * ```
3320 * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.RotatePanInput module <ko>eg.Axes.RotatePanInput 모듈을 사용할 엘리먼트</ko>
3321 * @param {PanInputOption} [options] The option object of the eg.Axes.PanInput module<ko>eg.Axes.PanInput 모듈의 옵션 객체</ko>
3322 * @extends PanInput
3323 */
3324
3325var RotatePanInput =
3326/*#__PURE__*/
3327function (_super) {
3328 __extends(RotatePanInput, _super);
3329 /**
3330 *
3331 */
3332
3333
3334 function RotatePanInput(el, options) {
3335 var _this = _super.call(this, el, options) || this;
3336
3337 _this._prevQuadrant = null;
3338 _this._lastDiff = 0;
3339 return _this;
3340 }
3341
3342 var __proto = RotatePanInput.prototype;
3343
3344 __proto.mapAxes = function (axes) {
3345 this._direction = Axes.DIRECTION_ALL;
3346 this.axes = axes;
3347 };
3348
3349 __proto._onPanstart = function (event) {
3350 var _a = this.options,
3351 inputKey = _a.inputKey,
3352 inputButton = _a.inputButton;
3353 var activeEvent = this._activeEvent;
3354 var panEvent = activeEvent.onEventStart(event, inputKey, inputButton);
3355
3356 if (!panEvent || !this.isEnabled()) {
3357 return;
3358 }
3359
3360 var rect = this.element.getBoundingClientRect();
3361
3362 this._observer.hold(this, panEvent);
3363
3364 this._attachWindowEvent(activeEvent); // TODO: how to do if element is ellipse not circle.
3365
3366
3367 this._coefficientForDistanceToAngle = 360 / (rect.width * Math.PI); // from 2*pi*r * x / 360
3368 // TODO: provide a way to set origin like https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin
3369
3370 this._rotateOrigin = [rect.left + (rect.width - 1) / 2, rect.top + (rect.height - 1) / 2]; // init angle.
3371
3372 this._prevAngle = null;
3373
3374 this._triggerChange(panEvent);
3375
3376 activeEvent.prevEvent = panEvent;
3377 };
3378
3379 __proto._onPanmove = function (event) {
3380 var _a = this.options,
3381 inputKey = _a.inputKey,
3382 inputButton = _a.inputButton;
3383 var activeEvent = this._activeEvent;
3384 var panEvent = activeEvent.onEventMove(event, inputKey, inputButton);
3385
3386 if (!panEvent || !this.isEnabled()) {
3387 return;
3388 }
3389
3390 if (panEvent.srcEvent.cancelable !== false) {
3391 panEvent.srcEvent.preventDefault();
3392 }
3393
3394 panEvent.srcEvent.stopPropagation();
3395
3396 this._triggerChange(panEvent);
3397
3398 activeEvent.prevEvent = panEvent;
3399 };
3400
3401 __proto._onPanend = function (event) {
3402 var activeEvent = this._activeEvent;
3403 activeEvent.onEventEnd(event);
3404
3405 if (!this.isEnabled()) {
3406 return;
3407 }
3408
3409 var prevEvent = activeEvent.prevEvent;
3410
3411 this._triggerChange(prevEvent);
3412
3413 var vx = prevEvent.velocityX;
3414 var vy = prevEvent.velocityY;
3415 var velocity = Math.sqrt(vx * vx + vy * vy) * (this._lastDiff > 0 ? -1 : 1); // clockwise
3416
3417 activeEvent.onRelease();
3418
3419 this._observer.release(this, prevEvent, [velocity * this._coefficientForDistanceToAngle]);
3420
3421 this._detachWindowEvent(activeEvent);
3422 };
3423
3424 __proto._triggerChange = function (event) {
3425 var _a = this._getPosFromOrigin(event.center.x, event.center.y),
3426 x = _a.x,
3427 y = _a.y;
3428
3429 var angle = getAngle(x, y);
3430 var positiveAngle = angle < 0 ? 360 + angle : angle;
3431
3432 var quadrant = this._getQuadrant(event.center.x, event.center.y);
3433
3434 var diff = this._getDifference(this._prevAngle, positiveAngle, this._prevQuadrant, quadrant);
3435
3436 this._prevAngle = positiveAngle;
3437 this._prevQuadrant = quadrant;
3438
3439 if (diff === 0) {
3440 return;
3441 }
3442
3443 this._lastDiff = diff;
3444
3445 this._observer.change(this, event, toAxis(this.axes, [-diff])); // minus for clockwise
3446
3447 };
3448
3449 __proto._getDifference = function (prevAngle, angle, prevQuadrant, quadrant) {
3450 var diff;
3451
3452 if (prevAngle === null) {
3453 diff = 0;
3454 } else if (prevQuadrant === 1 && quadrant === 4) {
3455 diff = -prevAngle - (360 - angle);
3456 } else if (prevQuadrant === 4 && quadrant === 1) {
3457 diff = 360 - prevAngle + angle;
3458 } else {
3459 diff = angle - prevAngle;
3460 }
3461
3462 return diff;
3463 };
3464
3465 __proto._getPosFromOrigin = function (posX, posY) {
3466 return {
3467 x: posX - this._rotateOrigin[0],
3468 y: this._rotateOrigin[1] - posY
3469 };
3470 };
3471
3472 __proto._getQuadrant = function (posX, posY) {
3473 /**
3474 * Quadrant
3475 * y(+)
3476 * |
3477 * 2 | 1
3478 * --------------->x(+)
3479 * 3 | 4
3480 * |
3481 */
3482 var _a = this._getPosFromOrigin(posX, posY),
3483 x = _a.x,
3484 y = _a.y;
3485
3486 var q = 0;
3487
3488 if (x >= 0 && y >= 0) {
3489 q = 1;
3490 } else if (x < 0 && y >= 0) {
3491 q = 2;
3492 } else if (x < 0 && y < 0) {
3493 q = 3;
3494 } else if (x >= 0 && y < 0) {
3495 q = 4;
3496 }
3497
3498 return q;
3499 };
3500
3501 return RotatePanInput;
3502}(PanInput);
3503
3504/**
3505 * @typedef {Object} PinchInputOption The option object of the eg.Axes.PinchInput module
3506 * @ko eg.Axes.PinchInput 모듈의 옵션 객체
3507 * @param {Number} [scale=1] Coordinate scale that a user can move<ko>사용자의 동작으로 이동하는 좌표의 배율</ko>
3508 * @param {Number} [threshold=0] Minimal scale before recognizing <ko>사용자의 Pinch 동작을 인식하기 위해산 최소한의 배율</ko>
3509 * @param {String[]} [inputType=["touch", "pointer"]] Types of input devices
3510 * - touch: Touch screen
3511 * - pointer: Mouse and touch <ko>입력 장치 종류
3512 * - touch: 터치 입력 장치
3513 * - pointer: 마우스 및 터치</ko>
3514 * @param {String} [touchAction="none"] Value that overrides the element's "touch-action" css property. It is set to "none" to prevent scrolling during touch. <ko>엘리먼트의 "touch-action" CSS 속성을 덮어쓰는 값. 터치 도중 스크롤을 방지하기 위해 "none" 으로 설정되어 있다.</ko>
3515 **/
3516
3517/**
3518 * A module that passes the amount of change to eg.Axes when two pointers are moving toward (zoom-in) or away from each other (zoom-out). use one axis.
3519 * @ko 2개의 pointer를 이용하여 zoom-in하거나 zoom-out 하는 동작의 변화량을 eg.Axes에 전달하는 모듈. 한 개 의 축을 사용한다.
3520 * @example
3521 * ```js
3522 * const pinch = new eg.Axes.PinchInput("#area", {
3523 * scale: 1
3524 * });
3525 *
3526 * // Connect 'something' axis when two pointers are moving toward (zoom-in) or away from each other (zoom-out).
3527 * axes.connect("something", pinch);
3528 * ```
3529 * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.PinchInput module <ko>eg.Axes.PinchInput 모듈을 사용할 엘리먼트</ko>
3530 * @param {PinchInputOption} [options] The option object of the eg.Axes.PinchInput module<ko>eg.Axes.PinchInput 모듈의 옵션 객체</ko>
3531 */
3532
3533var PinchInput =
3534/*#__PURE__*/
3535function () {
3536 /**
3537 *
3538 */
3539 function PinchInput(el, options) {
3540 this.axes = [];
3541 this.element = null;
3542 this._pinchFlag = false;
3543 this._enabled = false;
3544 this._activeEvent = null;
3545 this._isOverThreshold = false;
3546 this.element = $(el);
3547 this.options = __assign({
3548 scale: 1,
3549 threshold: 0,
3550 inputType: ["touch", "pointer"],
3551 touchAction: "none"
3552 }, options);
3553 this._onPinchStart = this._onPinchStart.bind(this);
3554 this._onPinchMove = this._onPinchMove.bind(this);
3555 this._onPinchEnd = this._onPinchEnd.bind(this);
3556 }
3557
3558 var __proto = PinchInput.prototype;
3559
3560 __proto.mapAxes = function (axes) {
3561 this.axes = axes;
3562 };
3563
3564 __proto.connect = function (observer) {
3565 if (this._activeEvent) {
3566 this._detachEvent();
3567 }
3568
3569 this._attachEvent(observer);
3570
3571 this._originalCssProps = setCssProps(this.element, this.options, DIRECTION_ALL);
3572 return this;
3573 };
3574
3575 __proto.disconnect = function () {
3576 this._detachEvent();
3577
3578 if (!isCssPropsFromAxes(this._originalCssProps)) {
3579 revertCssProps(this.element, this._originalCssProps);
3580 }
3581
3582 return this;
3583 };
3584 /**
3585 * Destroys elements, properties, and events used in a module.
3586 * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다.
3587 */
3588
3589
3590 __proto.destroy = function () {
3591 this.disconnect();
3592 this.element = null;
3593 };
3594 /**
3595 * Enables input devices
3596 * @ko 입력 장치를 사용할 수 있게 한다
3597 * @return {PinchInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
3598 */
3599
3600
3601 __proto.enable = function () {
3602 this._enabled = true;
3603 return this;
3604 };
3605 /**
3606 * Disables input devices
3607 * @ko 입력 장치를 사용할 수 없게 한다.
3608 * @return {PinchInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
3609 */
3610
3611
3612 __proto.disable = function () {
3613 this._enabled = false;
3614 return this;
3615 };
3616 /**
3617 * Returns whether to use an input device
3618 * @ko 입력 장치를 사용 여부를 반환한다.
3619 * @return {Boolean} Whether to use an input device <ko>입력장치 사용여부</ko>
3620 */
3621
3622
3623 __proto.isEnabled = function () {
3624 return this._enabled;
3625 };
3626
3627 __proto._onPinchStart = function (event) {
3628 var activeEvent = this._activeEvent;
3629 var pinchEvent = activeEvent.onEventStart(event);
3630
3631 if (!pinchEvent || !this._enabled || activeEvent.getTouches(event) !== 2) {
3632 return;
3633 }
3634
3635 this._baseValue = this._observer.get(this)[this.axes[0]];
3636
3637 this._observer.hold(this, event);
3638
3639 this._pinchFlag = true;
3640 this._isOverThreshold = false;
3641 activeEvent.prevEvent = pinchEvent;
3642 };
3643
3644 __proto._onPinchMove = function (event) {
3645 var threshold = this.options.threshold;
3646 var activeEvent = this._activeEvent;
3647 var pinchEvent = activeEvent.onEventMove(event);
3648
3649 if (!pinchEvent || !this._pinchFlag || !this._enabled || activeEvent.getTouches(event) !== 2) {
3650 return;
3651 }
3652
3653 var distance = this._getDistance(pinchEvent.scale);
3654
3655 var offset = this._getOffset(pinchEvent.scale, activeEvent.prevEvent.scale);
3656
3657 if (this._isOverThreshold || distance >= threshold) {
3658 this._isOverThreshold = true;
3659
3660 this._observer.change(this, event, toAxis(this.axes, [offset]));
3661 }
3662
3663 activeEvent.prevEvent = pinchEvent;
3664 };
3665
3666 __proto._onPinchEnd = function (event) {
3667 var activeEvent = this._activeEvent;
3668 activeEvent.onEventEnd(event);
3669
3670 if (!this._pinchFlag || !this._enabled || activeEvent.getTouches(event) >= 2) {
3671 return;
3672 }
3673
3674 activeEvent.onRelease();
3675
3676 this._observer.release(this, event, [0], 0);
3677
3678 this._baseValue = null;
3679 this._pinchFlag = false;
3680 };
3681
3682 __proto._attachEvent = function (observer) {
3683 var _this = this;
3684
3685 var activeEvent = convertInputType(this.options.inputType);
3686 var element = this.element;
3687
3688 if (!activeEvent) {
3689 return;
3690 }
3691
3692 if (!element) {
3693 throw new Error("Element to connect input does not exist.");
3694 }
3695
3696 this._observer = observer;
3697 this._enabled = true;
3698 this._activeEvent = activeEvent;
3699 activeEvent.start.forEach(function (event) {
3700 element.addEventListener(event, _this._onPinchStart, false);
3701 });
3702 activeEvent.move.forEach(function (event) {
3703 element.addEventListener(event, _this._onPinchMove, false);
3704 });
3705 activeEvent.end.forEach(function (event) {
3706 element.addEventListener(event, _this._onPinchEnd, false);
3707 });
3708 };
3709
3710 __proto._detachEvent = function () {
3711 var _this = this;
3712
3713 var activeEvent = this._activeEvent;
3714 var element = this.element;
3715
3716 if (element) {
3717 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.start.forEach(function (event) {
3718 element.removeEventListener(event, _this._onPinchStart, false);
3719 });
3720 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) {
3721 element.removeEventListener(event, _this._onPinchMove, false);
3722 });
3723 activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) {
3724 element.removeEventListener(event, _this._onPinchEnd, false);
3725 });
3726 }
3727
3728 this._enabled = false;
3729 this._observer = null;
3730 };
3731
3732 __proto._getOffset = function (pinchScale, prev) {
3733 if (prev === void 0) {
3734 prev = 1;
3735 }
3736
3737 return this._baseValue * (pinchScale - prev) * this.options.scale;
3738 };
3739
3740 __proto._getDistance = function (pinchScale) {
3741 return Math.abs(pinchScale - 1);
3742 };
3743
3744 return PinchInput;
3745}();
3746
3747/**
3748 * @typedef {Object} WheelInputOption The option object of the eg.Axes.WheelInput module
3749 * @ko eg.Axes.WheelInput 모듈의 옵션 객체
3750 * @param {String[]} [inputKey=["any"]] List of key combinations to allow input
3751 * - any: any key
3752 * - shift: shift key
3753 * - ctrl: ctrl key and pinch gesture on the trackpad
3754 * - alt: alt key
3755 * - meta: meta key
3756 * - none: none of these keys are pressed <ko>입력을 허용할 키 조합 목록
3757 * - any: 아무 키
3758 * - shift: shift 키
3759 * - ctrl: ctrl 키 및 트랙패드의 pinch 제스쳐
3760 * - alt: alt 키
3761 * - meta: meta 키
3762 * - none: 아무 키도 눌리지 않은 상태 </ko>
3763 * @param {Number} [scale=1] Coordinate scale that a user can move<ko>사용자의 동작으로 이동하는 좌표의 배율</ko>
3764 * @param {Number} [releaseDelay=300] Millisecond that trigger release event after last input<ko>마지막 입력 이후 release 이벤트가 트리거되기까지의 밀리초</ko>
3765 * @param {Boolean} [useNormalized=true] Whether to calculate scroll speed the same in all browsers<ko>모든 브라우저에서 스크롤 속도를 동일하게 처리할지 여부</ko>
3766 * @param {Boolean} [useAnimation=false] Whether to process coordinate changes through the mouse wheel as a continuous animation<ko>마우스 휠을 통한 좌표 변화를 연속적인 애니메이션으로 처리할지 여부</ko>
3767 **/
3768
3769/**
3770 * A module that passes the amount of change to eg.Axes when the mouse wheel is moved. use one axis.
3771 * @ko 마우스 휠이 움직일때의 변화량을 eg.Axes에 전달하는 모듈. 두개 이하의 축을 사용한다.
3772 *
3773 * @example
3774 * ```js
3775 * const wheel = new eg.Axes.WheelInput("#area", {
3776 * scale: 1
3777 * });
3778 *
3779 * // Connect only one 'something1' axis to the vertical mouse wheel.
3780 * axes.connect(["something1"], wheel); // or axes.connect("something1", wheel);
3781 *
3782 * // Connect only one 'something2' axis to the horizontal mouse wheel.
3783 * axes.connect(["", "something2"], wheel); // or axes.connect(" something2", pan);
3784 *
3785 * // Connect the 'something1' axis to the vertical mouse wheel.
3786 * // Connect the 'something2' axis to the horizontal mouse wheel.
3787 * axes.connect(["something1", "something2"], wheel);
3788 * ```
3789 * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.WheelInput module <ko>eg.Axes.WheelInput 모듈을 사용할 엘리먼트</ko>
3790 * @param {WheelInputOption} [options] The option object of the eg.Axes.WheelInput module<ko>eg.Axes.WheelInput 모듈의 옵션 객체</ko>
3791 */
3792
3793var WheelInput =
3794/*#__PURE__*/
3795function () {
3796 /**
3797 *
3798 */
3799 function WheelInput(el, options) {
3800 this.axes = [];
3801 this.element = null;
3802 this._enabled = false;
3803 this._holding = false;
3804 this._timer = null;
3805 this.element = $(el);
3806 this.options = __assign({
3807 inputKey: [ANY],
3808 scale: 1,
3809 releaseDelay: 300,
3810 useNormalized: true,
3811 useAnimation: false
3812 }, options);
3813 this._onWheel = this._onWheel.bind(this);
3814 }
3815
3816 var __proto = WheelInput.prototype;
3817
3818 __proto.mapAxes = function (axes) {
3819 // vertical mouse wheel is mapped into axes[0]
3820 this._direction = getDirection(!!axes[1], !!axes[0]);
3821 this.axes = axes;
3822 };
3823
3824 __proto.connect = function (observer) {
3825 this._detachEvent();
3826
3827 this._attachEvent(observer);
3828
3829 return this;
3830 };
3831
3832 __proto.disconnect = function () {
3833 this._detachEvent();
3834
3835 return this;
3836 };
3837 /**
3838 * Destroys elements, properties, and events used in a module.
3839 * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다.
3840 */
3841
3842
3843 __proto.destroy = function () {
3844 this.disconnect();
3845 this.element = null;
3846 };
3847 /**
3848 * Enables input devices
3849 * @ko 입력 장치를 사용할 수 있게 한다
3850 * @return {WheelInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
3851 */
3852
3853
3854 __proto.enable = function () {
3855 this._enabled = true;
3856 return this;
3857 };
3858 /**
3859 * Disables input devices
3860 * @ko 입력 장치를 사용할 수 없게 한다.
3861 * @return {WheelInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
3862 */
3863
3864
3865 __proto.disable = function () {
3866 this._enabled = false;
3867 return this;
3868 };
3869 /**
3870 * Returns whether to use an input device
3871 * @ko 입력 장치를 사용 여부를 반환한다.
3872 * @return {Boolean} Whether to use an input device <ko>입력장치 사용여부</ko>
3873 */
3874
3875
3876 __proto.isEnabled = function () {
3877 return this._enabled;
3878 };
3879
3880 __proto._onWheel = function (event) {
3881 var _this = this;
3882
3883 if (!this._enabled || !isValidKey(event, this.options.inputKey)) {
3884 return;
3885 }
3886
3887 var offset = this._getOffset([event.deltaY, event.deltaX], [useDirection(DIRECTION_VERTICAL, this._direction), useDirection(DIRECTION_HORIZONTAL, this._direction)]);
3888
3889 if (offset[0] === 0 && offset[1] === 0) {
3890 return;
3891 }
3892
3893 event.preventDefault();
3894
3895 if (!this._holding) {
3896 this._observer.hold(this, event);
3897
3898 this._holding = true;
3899 }
3900
3901 this._observer.change(this, event, toAxis(this.axes, offset), this.options.useAnimation);
3902
3903 clearTimeout(this._timer);
3904 this._timer = setTimeout(function () {
3905 if (_this._holding) {
3906 _this._holding = false;
3907
3908 _this._observer.release(_this, event, [0]);
3909 }
3910 }, this.options.releaseDelay);
3911 };
3912
3913 __proto._getOffset = function (properties, direction) {
3914 var scale = this.options.scale;
3915 var useNormalized = this.options.useNormalized;
3916 return [direction[0] && properties[0] ? (properties[0] > 0 ? -1 : 1) * (useNormalized ? 1 : Math.abs(properties[0])) * scale : 0, direction[1] && properties[1] ? (properties[1] > 0 ? -1 : 1) * (useNormalized ? 1 : Math.abs(properties[1])) * scale : 0];
3917 };
3918
3919 __proto._attachEvent = function (observer) {
3920 var element = this.element;
3921
3922 if (!element) {
3923 throw new Error("Element to connect input does not exist.");
3924 }
3925
3926 this._observer = observer;
3927 element.addEventListener("wheel", this._onWheel);
3928 this._enabled = true;
3929 };
3930
3931 __proto._detachEvent = function () {
3932 var element = this.element;
3933
3934 if (element) {
3935 this.element.removeEventListener("wheel", this._onWheel);
3936 }
3937
3938 this._enabled = false;
3939 this._observer = null;
3940
3941 if (this._timer) {
3942 clearTimeout(this._timer);
3943 this._timer = null;
3944 }
3945 };
3946
3947 return WheelInput;
3948}();
3949
3950var KEY_LEFT_ARROW = 37;
3951var KEY_A = 65;
3952var KEY_UP_ARROW = 38;
3953var KEY_W = 87;
3954var KEY_RIGHT_ARROW = 39;
3955var KEY_D = 68;
3956var KEY_DOWN_ARROW = 40;
3957var KEY_S = 83;
3958/* eslint-disable */
3959
3960var DIRECTION_REVERSE = -1;
3961var DIRECTION_FORWARD = 1;
3962var DIRECTION_HORIZONTAL$1 = -1;
3963var DIRECTION_VERTICAL$1 = 1;
3964var DELAY = 80;
3965/**
3966 * @typedef {Object} MoveKeyInputOption The option object of the eg.Axes.MoveKeyInput module
3967 * @ko eg.Axes.MoveKeyInput 모듈의 옵션 객체
3968 * @param {Array<Number>} [scale] Coordinate scale that a user can move<ko>사용자의 동작으로 이동하는 좌표의 배율</ko>
3969 * @param {Number} [scale[0]=1] Coordinate scale for the first axis<ko>첫번째 축의 배율</ko>
3970 * @param {Number} [scale[1]=1] Coordinate scale for the decond axis<ko>두번째 축의 배율</ko>
3971 **/
3972
3973/**
3974 * A module that passes the amount of change to eg.Axes when the move key stroke is occured. use two axis.
3975 * @ko 이동키 입력이 발생했을 때의 변화량을 eg.Axes에 전달하는 모듈. 두 개 의 축을 사용한다.
3976 *
3977 * @example
3978 * ```js
3979 * const moveKey = new eg.Axes.MoveKeyInput("#area", {
3980 * scale: [1, 1]
3981 * });
3982 *
3983 * // Connect 'x', 'y' axes when the moveKey is pressed.
3984 * axes.connect(["x", "y"], moveKey);
3985 * ```
3986 * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.MoveKeyInput module <ko>eg.Axes.MoveKeyInput 모듈을 사용할 엘리먼트</ko>
3987 * @param {MoveKeyInputOption} [options] The option object of the eg.Axes.MoveKeyInput module<ko>eg.Axes.MoveKeyInput 모듈의 옵션 객체</ko>
3988 */
3989
3990var MoveKeyInput =
3991/*#__PURE__*/
3992function () {
3993 /**
3994 *
3995 */
3996 function MoveKeyInput(el, options) {
3997 this.axes = [];
3998 this.element = null;
3999 this._enabled = false;
4000 this._holding = false;
4001 this._timer = null;
4002 this.element = $(el);
4003 this.options = __assign({
4004 scale: [1, 1]
4005 }, options);
4006 this._onKeydown = this._onKeydown.bind(this);
4007 this._onKeyup = this._onKeyup.bind(this);
4008 }
4009
4010 var __proto = MoveKeyInput.prototype;
4011
4012 __proto.mapAxes = function (axes) {
4013 this.axes = axes;
4014 };
4015
4016 __proto.connect = function (observer) {
4017 this._detachEvent(); // add tabindex="0" to the container for making it focusable
4018
4019
4020 if (this.element.getAttribute("tabindex") !== "0") {
4021 this.element.setAttribute("tabindex", "0");
4022 }
4023
4024 this._attachEvent(observer);
4025
4026 return this;
4027 };
4028
4029 __proto.disconnect = function () {
4030 this._detachEvent();
4031
4032 return this;
4033 };
4034 /**
4035 * Destroys elements, properties, and events used in a module.
4036 * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다.
4037 */
4038
4039
4040 __proto.destroy = function () {
4041 this.disconnect();
4042 this.element = null;
4043 };
4044 /**
4045 * Enables input devices
4046 * @ko 입력 장치를 사용할 수 있게 한다
4047 * @return {MoveKeyInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
4048 */
4049
4050
4051 __proto.enable = function () {
4052 this._enabled = true;
4053 return this;
4054 };
4055 /**
4056 * Disables input devices
4057 * @ko 입력 장치를 사용할 수 없게 한다.
4058 * @return {MoveKeyInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
4059 */
4060
4061
4062 __proto.disable = function () {
4063 this._enabled = false;
4064 return this;
4065 };
4066 /**
4067 * Returns whether to use an input device
4068 * @ko 입력 장치를 사용 여부를 반환한다.
4069 * @return {Boolean} Whether to use an input device <ko>입력장치 사용여부</ko>
4070 */
4071
4072
4073 __proto.isEnabled = function () {
4074 return this._enabled;
4075 };
4076
4077 __proto._onKeydown = function (event) {
4078 if (!this._enabled) {
4079 return;
4080 }
4081
4082 var isMoveKey = true;
4083 var direction = DIRECTION_FORWARD;
4084 var move = DIRECTION_HORIZONTAL$1;
4085
4086 switch (event.keyCode) {
4087 case KEY_LEFT_ARROW:
4088 case KEY_A:
4089 direction = DIRECTION_REVERSE;
4090 break;
4091
4092 case KEY_RIGHT_ARROW:
4093 case KEY_D:
4094 break;
4095
4096 case KEY_DOWN_ARROW:
4097 case KEY_S:
4098 direction = DIRECTION_REVERSE;
4099 move = DIRECTION_VERTICAL$1;
4100 break;
4101
4102 case KEY_UP_ARROW:
4103 case KEY_W:
4104 move = DIRECTION_VERTICAL$1;
4105 break;
4106
4107 default:
4108 isMoveKey = false;
4109 }
4110
4111 if (move === DIRECTION_HORIZONTAL$1 && !this.axes[0] || move === DIRECTION_VERTICAL$1 && !this.axes[1]) {
4112 isMoveKey = false;
4113 }
4114
4115 if (!isMoveKey) {
4116 return;
4117 }
4118
4119 event.preventDefault();
4120 var offsets = move === DIRECTION_HORIZONTAL$1 ? [+this.options.scale[0] * direction, 0] : [0, +this.options.scale[1] * direction];
4121
4122 if (!this._holding) {
4123 this._observer.hold(this, event);
4124
4125 this._holding = true;
4126 }
4127
4128 clearTimeout(this._timer);
4129
4130 this._observer.change(this, event, toAxis(this.axes, offsets));
4131 };
4132
4133 __proto._onKeyup = function (event) {
4134 var _this = this;
4135
4136 if (!this._holding) {
4137 return;
4138 }
4139
4140 clearTimeout(this._timer);
4141 this._timer = setTimeout(function () {
4142 _this._observer.release(_this, event, [0, 0]);
4143
4144 _this._holding = false;
4145 }, DELAY);
4146 };
4147
4148 __proto._attachEvent = function (observer) {
4149 var element = this.element;
4150
4151 if (!element) {
4152 throw new Error("Element to connect input does not exist.");
4153 }
4154
4155 this._observer = observer;
4156 element.addEventListener("keydown", this._onKeydown, false);
4157 element.addEventListener("keypress", this._onKeydown, false);
4158 element.addEventListener("keyup", this._onKeyup, false);
4159 this._enabled = true;
4160 };
4161
4162 __proto._detachEvent = function () {
4163 var element = this.element;
4164
4165 if (element) {
4166 element.removeEventListener("keydown", this._onKeydown, false);
4167 element.removeEventListener("keypress", this._onKeydown, false);
4168 element.removeEventListener("keyup", this._onKeyup, false);
4169 }
4170
4171 this._enabled = false;
4172 this._observer = null;
4173 };
4174
4175 return MoveKeyInput;
4176}();
4177
4178/*
4179 * Copyright (c) 2015 NAVER Corp.
4180 * egjs projects are licensed under the MIT license
4181 */
4182var REACTIVE_AXES = {
4183 methods: AXES_METHODS,
4184 events: AXES_EVENTS,
4185 created: function (data) {
4186 return new Axes(data.axis, data.options);
4187 },
4188 on: function (instance, name, callback) {
4189 instance.on(name, callback);
4190 },
4191 off: function (instance, name, callback) {
4192 instance.off(name, callback);
4193 },
4194 destroy: function (instance) {
4195 instance.destroy();
4196 }
4197};
4198
4199/*
4200 * Copyright (c) 2015 NAVER Corp.
4201 * egjs projects are licensed under the MIT license
4202 */
4203
4204var modules = ({
4205 default: Axes,
4206 PanInput: PanInput,
4207 RotatePanInput: RotatePanInput,
4208 PinchInput: PinchInput,
4209 WheelInput: WheelInput,
4210 MoveKeyInput: MoveKeyInput,
4211 AXES_METHODS: AXES_METHODS,
4212 AXES_EVENTS: AXES_EVENTS,
4213 REACTIVE_AXES: REACTIVE_AXES
4214});
4215
4216/*
4217 * Copyright (c) 2015 NAVER Corp.
4218 * egjs projects are licensed under the MIT license
4219 */
4220
4221for (var name in modules) {
4222 Axes[name] = modules[name];
4223}
4224
4225module.exports = Axes;
4226
4227exports.default = Axes;
4228exports.PanInput = PanInput;
4229exports.RotatePanInput = RotatePanInput;
4230exports.PinchInput = PinchInput;
4231exports.WheelInput = WheelInput;
4232exports.MoveKeyInput = MoveKeyInput;
4233exports.AXES_METHODS = AXES_METHODS;
4234exports.AXES_EVENTS = AXES_EVENTS;
4235exports.REACTIVE_AXES = REACTIVE_AXES;
4236//# sourceMappingURL=axes.cjs.js.map