UNPKG

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