UNPKG

248 kBJavaScriptView Raw
1/*
2Copyright (c) 2015-present NAVER Corp.
3name: @egjs/flicking
4license: MIT
5author: NAVER Corp.
6repository: https://github.com/naver/egjs-flicking
7version: 4.3.0
8*/
9import Component, { ComponentEvent } from '@egjs/component';
10import Axes, { PanInput } from '@egjs/axes';
11import ImReady from '@egjs/imready';
12
13/*! *****************************************************************************
14Copyright (c) Microsoft Corporation.
15
16Permission to use, copy, modify, and/or distribute this software for any
17purpose with or without fee is hereby granted.
18
19THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
20REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
23LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
24OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
25PERFORMANCE OF THIS SOFTWARE.
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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
36 };
37
38 return extendStatics(d, b);
39};
40
41function __extends(d, b) {
42 if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
43 extendStatics(d, b);
44
45 function __() {
46 this.constructor = d;
47 }
48
49 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
50}
51var __assign = function () {
52 __assign = Object.assign || function __assign(t) {
53 for (var s, i = 1, n = arguments.length; i < n; i++) {
54 s = arguments[i];
55
56 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
57 }
58
59 return t;
60 };
61
62 return __assign.apply(this, arguments);
63};
64function __awaiter(thisArg, _arguments, P, generator) {
65 function adopt(value) {
66 return value instanceof P ? value : new P(function (resolve) {
67 resolve(value);
68 });
69 }
70
71 return new (P || (P = Promise))(function (resolve, reject) {
72 function fulfilled(value) {
73 try {
74 step(generator.next(value));
75 } catch (e) {
76 reject(e);
77 }
78 }
79
80 function rejected(value) {
81 try {
82 step(generator["throw"](value));
83 } catch (e) {
84 reject(e);
85 }
86 }
87
88 function step(result) {
89 result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
90 }
91
92 step((generator = generator.apply(thisArg, _arguments || [])).next());
93 });
94}
95function __generator(thisArg, body) {
96 var _ = {
97 label: 0,
98 sent: function () {
99 if (t[0] & 1) throw t[1];
100 return t[1];
101 },
102 trys: [],
103 ops: []
104 },
105 f,
106 y,
107 t,
108 g;
109 return g = {
110 next: verb(0),
111 "throw": verb(1),
112 "return": verb(2)
113 }, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
114 return this;
115 }), g;
116
117 function verb(n) {
118 return function (v) {
119 return step([n, v]);
120 };
121 }
122
123 function step(op) {
124 if (f) throw new TypeError("Generator is already executing.");
125
126 while (_) try {
127 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
128 if (y = 0, t) op = [op[0] & 2, t.value];
129
130 switch (op[0]) {
131 case 0:
132 case 1:
133 t = op;
134 break;
135
136 case 4:
137 _.label++;
138 return {
139 value: op[1],
140 done: false
141 };
142
143 case 5:
144 _.label++;
145 y = op[1];
146 op = [0];
147 continue;
148
149 case 7:
150 op = _.ops.pop();
151
152 _.trys.pop();
153
154 continue;
155
156 default:
157 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
158 _ = 0;
159 continue;
160 }
161
162 if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
163 _.label = op[1];
164 break;
165 }
166
167 if (op[0] === 6 && _.label < t[1]) {
168 _.label = t[1];
169 t = op;
170 break;
171 }
172
173 if (t && _.label < t[2]) {
174 _.label = t[2];
175
176 _.ops.push(op);
177
178 break;
179 }
180
181 if (t[2]) _.ops.pop();
182
183 _.trys.pop();
184
185 continue;
186 }
187
188 op = body.call(thisArg, _);
189 } catch (e) {
190 op = [6, e];
191 y = 0;
192 } finally {
193 f = t = 0;
194 }
195
196 if (op[0] & 5) throw op[1];
197 return {
198 value: op[0] ? op[1] : void 0,
199 done: true
200 };
201 }
202}
203function __values(o) {
204 var s = typeof Symbol === "function" && Symbol.iterator,
205 m = s && o[s],
206 i = 0;
207 if (m) return m.call(o);
208 if (o && typeof o.length === "number") return {
209 next: function () {
210 if (o && i >= o.length) o = void 0;
211 return {
212 value: o && o[i++],
213 done: !o
214 };
215 }
216 };
217 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
218}
219function __read(o, n) {
220 var m = typeof Symbol === "function" && o[Symbol.iterator];
221 if (!m) return o;
222 var i = m.call(o),
223 r,
224 ar = [],
225 e;
226
227 try {
228 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
229 } catch (error) {
230 e = {
231 error: error
232 };
233 } finally {
234 try {
235 if (r && !r.done && (m = i["return"])) m.call(i);
236 } finally {
237 if (e) throw e.error;
238 }
239 }
240
241 return ar;
242}
243function __spreadArray(to, from) {
244 for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i];
245
246 return to;
247}
248
249/*
250 * Copyright (c) 2015 NAVER Corp.
251 * egjs projects are licensed under the MIT license
252 */
253
254/* eslint-disable @typescript-eslint/restrict-template-expressions */
255
256/**
257 * Error codes of {@link FlickingError}. Below are the conditions where each error code occurs.
258 * @ko {@link FlickingError}의 에러 코드. 아래는 각각의 에러 코드가 발생하는 조건입니다.
259 * @name ERROR_CODE
260 * @constant
261 * @type object
262 * @property {number} WRONG_TYPE Parameter type is wrong<ko>패러미터의 타입이 잘못되었을 경우</ko>
263 * @property {number} ELEMENT_NOT_FOUND Element is not found inside page with the given CSS selector<ko>주어진 CSS selector로 페이지 내에서 해당 엘리먼트를 찾지 못했을 경우</ko>
264 * @property {number} VAL_MUST_NOT_NULL Expected non-null value, but given `null` or `undefined`<ko>값을 기대했으나, `null`이나 `undefined`를 받은 경우</ko>
265 * @property {number} NOT_ATTACHED_TO_FLICKING When Flicking's component is not initialized (i.e. {@link Flicking#init} is not called)<ko>Flicking 내부 컴포넌트가 초기화되지 않은 경우 ({@link Flicking#init}이 호출되지 않은 경우)</ko>
266 * @property {number} WRONG_OPTION One of the options is wrong<ko>옵션들 중 잘못된 값이 있을 때</ko>
267 * @property {number} INDEX_OUT_OF_RANGE When the given index is out of possible range<ko>인덱스가 주어진 범위를 벗어난 경우</ko>
268 * @property {number} POSITION_NOT_REACHABLE When {@link Control#moveToPosition}'s position parameter is out of possible range.<ko>{@link Control#moveToPosition}의 `position` 패러미터가 도달 가능한 범위를 벗어난 경우</ko>
269 * @property {number} TRANSFORM_NOT_SUPPORTED CSS `transform` property is not available(<=IE8) <ko>CSS `transform` 속성을 사용할 수 없는 경우(<=IE8)</ko>
270 * @property {number} STOP_CALLED_BY_USER When the event's `stop()` is called by user.<ko>사용자에 의해 이벤트의 `stop()`이 호출된 경우</ko>
271 * @property {number} ANIMATION_INTERRUPTED When the animation is interrupted by user.<ko>사용자에 의해 애니메이션이 중단된 경우</ko>
272 * @property {number} ANIMATION_ALREADY_PLAYING When the animation is already playing.<ko>현재 애니메이션이 이미 진행중인 경우</ko>
273 * @property {number} NOT_ALLOWED_IN_FRAMEWORK When the non-allowed method is called from frameworks (React, Angular, Vue...)
274 * <ko>프레임워크(React, Angular, Vue ...)에서 사용 불가능한 메소드를 호출했을 경우</ko>
275 * @property {number} NOT_INITIALIZED When the {@link Flicking#init} is not called before but is needed<ko>{@link Flicking#init}의 호출이 필요하나, 아직 호출되지 않았을 경우</ko>
276 * @property {number} NO_ACTIVE When there're no active panel that flicking has selected. This may be due to the absence of any panels<ko>현재 Flicking이 선택한 패널이 없을 경우. 일반적으로 패널이 하나도 없는 경우에 발생할 수 있습니다</ko>
277 */
278var CODE = {
279 WRONG_TYPE: 0,
280 ELEMENT_NOT_FOUND: 1,
281 VAL_MUST_NOT_NULL: 2,
282 NOT_ATTACHED_TO_FLICKING: 3,
283 WRONG_OPTION: 4,
284 INDEX_OUT_OF_RANGE: 5,
285 POSITION_NOT_REACHABLE: 6,
286 TRANSFORM_NOT_SUPPORTED: 7,
287 STOP_CALLED_BY_USER: 8,
288 ANIMATION_INTERRUPTED: 9,
289 ANIMATION_ALREADY_PLAYING: 10,
290 NOT_ALLOWED_IN_FRAMEWORK: 11,
291 NOT_INITIALIZED: 12,
292 NO_ACTIVE: 13
293};
294var MESSAGE = {
295 WRONG_TYPE: function (wrongVal, correctTypes) {
296 return wrongVal + "(" + typeof wrongVal + ") is not a " + correctTypes.map(function (type) {
297 return "\"" + type + "\"";
298 }).join(" or ") + ".";
299 },
300 ELEMENT_NOT_FOUND: function (selector) {
301 return "Element with selector \"" + selector + "\" not found.";
302 },
303 VAL_MUST_NOT_NULL: function (val, name) {
304 return name + " should be provided. Given: " + val;
305 },
306 NOT_ATTACHED_TO_FLICKING: function (name) {
307 return name + " is not attached to the Flicking instance. \"init()\" should be called first.";
308 },
309 WRONG_OPTION: function (optionName, val) {
310 return "Option \"" + optionName + "\" is not in correct format, given: " + val;
311 },
312 INDEX_OUT_OF_RANGE: function (val, min, max) {
313 return "Index \"" + val + "\" is out of range: should be between " + min + " and " + max + ".";
314 },
315 POSITION_NOT_REACHABLE: function (position) {
316 return "Position \"" + position + "\" is not reachable.";
317 },
318 TRANSFORM_NOT_SUPPORTED: "Browser does not support CSS transform.",
319 STOP_CALLED_BY_USER: "Event stop() is called by user.",
320 ANIMATION_INTERRUPTED: "Animation is interrupted by user input.",
321 ANIMATION_ALREADY_PLAYING: "Animation is already playing.",
322 NOT_ALLOWED_IN_FRAMEWORK: "This behavior is not allowed in the frameworks like React, Vue, or Angular.",
323 NOT_INITIALIZED: "Flicking is not initialized yet, call init() first.",
324 NO_ACTIVE: "There's no active panel that Flicking has selected. This may be due to the absence of any panels."
325};
326
327/*
328 * Copyright (c) 2015 NAVER Corp.
329 * egjs projects are licensed under the MIT license
330 */
331/**
332 * Event type object with event name strings of {@link Flicking}
333 * @ko {@link Flicking}의 이벤트 이름 문자열들을 담은 객체
334 * @type {object}
335 * @property {"holdStart"} HOLD_START holdStart event<ko>holdStart 이벤트</ko>
336 * @property {"holdEnd"} HOLD_END holdEnd event<ko>holdEnd 이벤트</ko>
337 * @property {"moveStart"} MOVE_START moveStart event<ko>moveStart 이벤트</ko>
338 * @property {"move"} MOVE move event<ko>move 이벤트</ko>
339 * @property {"moveEnd"} MOVE_END moveEnd event<ko>moveEnd 이벤트</ko>
340 * @property {"willChange"} WILL_CHANGE willChange event<ko>willChange 이벤트</ko>
341 * @property {"changed"} CHANGED changed event<ko>changed 이벤트</ko>
342 * @property {"willRestore"} WILL_RESTORE willRestore event<ko>willRestore 이벤트</ko>
343 * @property {"restored"} RESTORED restored event<ko>restored 이벤트</ko>
344 * @property {"select"} SELECT select event<ko>select 이벤트</ko>
345 * @property {"needPanel"} NEED_PANEL needPanel event<ko>needPanel 이벤트</ko>
346 * @property {"panelChange"} PANEL_CHANGE panelChange event<ko>panelChange 이벤트</ko>
347 * @example
348 * ```ts
349 * import { EVENTS } from "@egjs/flicking";
350 * EVENTS.MOVE_START; // "moveStart"
351 * ```
352 */
353
354var EVENTS = {
355 READY: "ready",
356 BEFORE_RESIZE: "beforeResize",
357 AFTER_RESIZE: "afterResize",
358 HOLD_START: "holdStart",
359 HOLD_END: "holdEnd",
360 MOVE_START: "moveStart",
361 MOVE: "move",
362 MOVE_END: "moveEnd",
363 WILL_CHANGE: "willChange",
364 CHANGED: "changed",
365 WILL_RESTORE: "willRestore",
366 RESTORED: "restored",
367 SELECT: "select",
368 NEED_PANEL: "needPanel",
369 VISIBLE_CHANGE: "visibleChange",
370 REACH_EDGE: "reachEdge",
371 PANEL_CHANGE: "panelChange"
372};
373/**
374 * An object with all possible predefined literal string for the {@link Flicking#align align} option
375 * @ko {@link Flicking#align align} 옵션에 사용되는 미리 정의된 리터럴 상수들을 담고 있는 객체
376 * @type {object}
377 * @property {"prev"} PREV left/top align<ko>좌/상 정렬</ko>
378 * @property {"center"} CENTER center align<ko>중앙 정렬</ko>
379 * @property {"next"} NEXT right/bottom align<ko>우/하 정렬</ko>
380 */
381
382var ALIGN = {
383 PREV: "prev",
384 CENTER: "center",
385 NEXT: "next"
386};
387/**
388 * An object of directions
389 * @ko 방향을 나타내는 값들을 담고 있는 객체
390 * @type {object}
391 * @property {"PREV"} PREV "left" when {@link Flicking#horizontal horizontal} is true, and "top" when {@link Flicking#horizontal horizontal} is false
392 * <ko>{@link Flicking#horizontal horizontal}가 `true`일 경우 왼쪽, {@link Flicking#horizontal horizontal}가 `false`일 경우 위쪽을 의미합니다</ko>
393 * @property {"NEXT"} NEXT "right" when {@link Flicking#horizontal horizontal} is true, and "bottom" when {@link Flicking#horizontal horizontal} is false
394 * <ko>{@link Flicking#horizontal horizontal}가 `true`일 경우 오른쪽, {@link Flicking#horizontal horizontal}가 `false`일 경우 아래쪽을 의미합니다</ko>
395 * @property {null} NONE This value usually means it's the same position<ko>주로 제자리인 경우를 의미합니다</ko>
396 */
397
398var DIRECTION = {
399 PREV: "PREV",
400 NEXT: "NEXT",
401 NONE: null
402};
403/**
404 * An object with all possible {@link Flicking#moveType moveType}s
405 * @ko Flicking이 제공하는 {@link Flicking#moveType moveType}들을 담고 있는 객체
406 * @type {object}
407 * @property {"snap"} SNAP Flicking's {@link Flicking#moveType moveType} that enables {@link SnapControl} as a Flicking's {@link Flicking#control control}
408 * <ko>Flicking의 {@link Flicking#control control}을 {@link SnapControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>
409 * @property {"freeScroll"} FREE_SCROLL Flicking's {@link Flicking#moveType moveType} that enables {@link FreeControl} as a Flicking's {@link Flicking#control control}
410 * <ko>Flicking의 {@link Flicking#control control}을 {@link FreeControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>
411 * @property {"strict"} STRICT Flicking's {@link Flicking#moveType moveType} that enables {@link StrictControl} as a Flicking's {@link Flicking#control control}
412 * <ko>Flicking의 {@link Flicking#control control}을 {@link StrictControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>
413 */
414
415var MOVE_TYPE = {
416 SNAP: "snap",
417 FREE_SCROLL: "freeScroll",
418 STRICT: "strict"
419};
420
421var getElement = function (el, parent) {
422 var targetEl = null;
423
424 if (isString(el)) {
425 var parentEl = parent ? parent : document;
426 var queryResult = parentEl.querySelector(el);
427
428 if (!queryResult) {
429 throw new FlickingError(MESSAGE.ELEMENT_NOT_FOUND(el), CODE.ELEMENT_NOT_FOUND);
430 }
431
432 targetEl = queryResult;
433 } else if (el && el.nodeType === Node.ELEMENT_NODE) {
434 targetEl = el;
435 }
436
437 if (!targetEl) {
438 throw new FlickingError(MESSAGE.WRONG_TYPE(el, ["HTMLElement", "string"]), CODE.WRONG_TYPE);
439 }
440
441 return targetEl;
442};
443var checkExistence = function (value, nameOnErrMsg) {
444 if (value == null) {
445 throw new FlickingError(MESSAGE.VAL_MUST_NOT_NULL(value, nameOnErrMsg), CODE.VAL_MUST_NOT_NULL);
446 }
447};
448var clamp = function (x, min, max) {
449 return Math.max(Math.min(x, max), min);
450};
451var getFlickingAttached = function (val, nameToThrowOnError) {
452 if (!val) {
453 throw new FlickingError(MESSAGE.NOT_ATTACHED_TO_FLICKING(nameToThrowOnError), CODE.NOT_ATTACHED_TO_FLICKING);
454 }
455
456 return val;
457};
458var toArray = function (iterable) {
459 return [].slice.call(iterable);
460};
461var parseAlign$1 = function (align, size) {
462 var alignPoint;
463
464 if (isString(align)) {
465 switch (align) {
466 case ALIGN.PREV:
467 alignPoint = 0;
468 break;
469
470 case ALIGN.CENTER:
471 alignPoint = 0.5 * size;
472 break;
473
474 case ALIGN.NEXT:
475 alignPoint = size;
476 break;
477
478 default:
479 alignPoint = parseArithmeticSize(align, size);
480
481 if (alignPoint == null) {
482 throw new FlickingError(MESSAGE.WRONG_OPTION("align", align), CODE.WRONG_OPTION);
483 }
484
485 }
486 } else {
487 alignPoint = align;
488 }
489
490 return alignPoint;
491};
492var parseBounce = function (bounce, size) {
493 var parsedBounce;
494
495 if (Array.isArray(bounce)) {
496 parsedBounce = bounce.map(function (val) {
497 return parseArithmeticSize(val, size);
498 });
499 } else {
500 var parsedVal = parseArithmeticSize(bounce, size);
501 parsedBounce = [parsedVal, parsedVal];
502 }
503
504 return parsedBounce.map(function (val) {
505 if (val == null) {
506 throw new FlickingError(MESSAGE.WRONG_OPTION("bounce", bounce), CODE.WRONG_OPTION);
507 }
508
509 return val;
510 });
511};
512var parseArithmeticSize = function (cssValue, base) {
513 var parsed = parseArithmeticExpression(cssValue);
514 if (parsed == null) return null;
515 return parsed.percentage * base + parsed.absolute;
516};
517var parseArithmeticExpression = function (cssValue) {
518 var cssRegex = /(?:(\+|\-)\s*)?(\d+(?:\.\d+)?(%|px)?)/g;
519
520 if (typeof cssValue === "number") {
521 return {
522 percentage: 0,
523 absolute: cssValue
524 };
525 }
526
527 var parsed = {
528 percentage: 0,
529 absolute: 0
530 };
531 var idx = 0;
532 var matchResult = cssRegex.exec(cssValue);
533
534 while (matchResult != null) {
535 var sign = matchResult[1];
536 var value = matchResult[2];
537 var unit = matchResult[3];
538 var parsedValue = parseFloat(value);
539
540 if (idx <= 0) {
541 sign = sign || "+";
542 } // Return default value for values not in good form
543
544
545 if (!sign) {
546 return null;
547 }
548
549 var signMultiplier = sign === "+" ? 1 : -1;
550
551 if (unit === "%") {
552 parsed.percentage += signMultiplier * (parsedValue / 100);
553 } else {
554 parsed.absolute += signMultiplier * parsedValue;
555 } // Match next occurrence
556
557
558 ++idx;
559 matchResult = cssRegex.exec(cssValue);
560 } // None-matched
561
562
563 if (idx === 0) {
564 return null;
565 }
566
567 return parsed;
568};
569var getDirection = function (start, end) {
570 if (start === end) return DIRECTION.NONE;
571 return start < end ? DIRECTION.NEXT : DIRECTION.PREV;
572};
573var parseElement = function (element) {
574 if (!Array.isArray(element)) {
575 element = [element];
576 }
577
578 var elements = [];
579 element.forEach(function (el) {
580 if (isString(el)) {
581 var tempDiv = document.createElement("div");
582 tempDiv.innerHTML = el;
583 elements.push.apply(elements, __spreadArray([], __read(toArray(tempDiv.children))));
584
585 while (tempDiv.firstChild) {
586 tempDiv.removeChild(tempDiv.firstChild);
587 }
588 } else if (el && el.nodeType === Node.ELEMENT_NODE) {
589 elements.push(el);
590 } else {
591 throw new FlickingError(MESSAGE.WRONG_TYPE(el, ["HTMLElement", "string"]), CODE.WRONG_TYPE);
592 }
593 });
594 return elements;
595};
596var getMinusCompensatedIndex = function (idx, max) {
597 return idx < 0 ? clamp(idx + max, 0, max) : clamp(idx, 0, max);
598};
599var includes = function (array, target) {
600 var e_1, _a;
601
602 try {
603 for (var array_1 = __values(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) {
604 var val = array_1_1.value;
605 if (val === target) return true;
606 }
607 } catch (e_1_1) {
608 e_1 = {
609 error: e_1_1
610 };
611 } finally {
612 try {
613 if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1);
614 } finally {
615 if (e_1) throw e_1.error;
616 }
617 }
618
619 return false;
620};
621var isString = function (val) {
622 return typeof val === "string";
623};
624var circulatePosition = function (pos, min, max) {
625 var size = max - min;
626
627 if (pos < min) {
628 var offset = (min - pos) % size;
629 pos = max - offset;
630 } else if (pos > max) {
631 var offset = (pos - max) % size;
632 pos = min + offset;
633 }
634
635 return pos;
636};
637var find = function (array, checker) {
638 var e_2, _a;
639
640 try {
641 for (var array_2 = __values(array), array_2_1 = array_2.next(); !array_2_1.done; array_2_1 = array_2.next()) {
642 var val = array_2_1.value;
643
644 if (checker(val)) {
645 return val;
646 }
647 }
648 } catch (e_2_1) {
649 e_2 = {
650 error: e_2_1
651 };
652 } finally {
653 try {
654 if (array_2_1 && !array_2_1.done && (_a = array_2.return)) _a.call(array_2);
655 } finally {
656 if (e_2) throw e_2.error;
657 }
658 }
659
660 return null;
661};
662var findIndex = function (array, checker) {
663 for (var idx = 0; idx < array.length; idx++) {
664 if (checker(array[idx])) {
665 return idx;
666 }
667 }
668
669 return -1;
670};
671var getProgress = function (pos, prev, next) {
672 return (pos - prev) / (next - prev);
673}; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
674
675var getStyle = function (el) {
676 return window.getComputedStyle(el) || el.currentStyle;
677};
678var isBetween = function (val, min, max) {
679 return val >= min && val <= max;
680};
681var circulateIndex = function (index, max) {
682 if (index >= max) {
683 return index % max;
684 } else if (index < 0) {
685 return getMinusCompensatedIndex((index + 1) % max - 1, max);
686 } else {
687 return index;
688 }
689};
690var setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
691 obj.__proto__ = proto;
692 return obj;
693};
694
695/*
696 * Copyright (c) 2015 NAVER Corp.
697 * egjs projects are licensed under the MIT license
698 */
699/**
700 * Special type of known error that {@link Flicking} throws.
701 * @ko Flicking 내부에서 알려진 오류 발생시 throw되는 에러
702 * @property {number} code Error code<ko>에러 코드</ko>
703 * @property {string} message Error message<ko>에러 메시지</ko>
704 * @see {@link Constants.ERROR_CODE ERROR_CODE}
705 * @example
706 * ```ts
707 * import Flicking, { FlickingError, ERROR_CODES } from "@egjs/flicking";
708 * try {
709 * const flicking = new Flicking(".flicking-viewport")
710 * } catch (e) {
711 * if (e instanceof FlickingError && e.code === ERROR_CODES.ELEMENT_NOT_FOUND) {
712 * console.error("Element not found")
713 * }
714 * }
715 * ```
716 */
717
718var FlickingError = function (_super) {
719 __extends(FlickingError, _super);
720 /**
721 * @param message Error message<ko>에러 메시지</ko>
722 * @param code Error code<ko>에러 코드</ko>
723 */
724
725
726 function FlickingError(message, code) {
727 var _this = _super.call(this, message) || this;
728
729 setPrototypeOf(_this, FlickingError.prototype);
730 _this.name = "FlickingError";
731 _this.code = code;
732 return _this;
733 }
734
735 return FlickingError;
736}(Error);
737
738/*
739 * Copyright (c) 2015 NAVER Corp.
740 * egjs projects are licensed under the MIT license
741 */
742/**
743 * A component that manages viewport size
744 * @ko 뷰포트 크기 정보를 담당하는 컴포넌트
745 */
746
747var Viewport = function () {
748 /**
749 * @param el A viewport element<ko>뷰포트 엘리먼트</ko>
750 */
751 function Viewport(el) {
752 this._el = el;
753 this._width = 0;
754 this._height = 0;
755 this._padding = {
756 left: 0,
757 right: 0,
758 top: 0,
759 bottom: 0
760 };
761 this._isBorderBoxSizing = false;
762 }
763
764 var __proto = Viewport.prototype;
765 Object.defineProperty(__proto, "element", {
766 /**
767 * A viewport(root) element
768 * @ko 뷰포트(root) 엘리먼트
769 * @type {HTMLElement}
770 * @readonly
771 */
772 get: function () {
773 return this._el;
774 },
775 enumerable: false,
776 configurable: true
777 });
778 Object.defineProperty(__proto, "width", {
779 /**
780 * Viewport width, without paddings
781 * @ko 뷰포트 너비
782 * @type {number}
783 * @readonly
784 */
785 get: function () {
786 return this._width - this._padding.left - this._padding.right;
787 },
788 enumerable: false,
789 configurable: true
790 });
791 Object.defineProperty(__proto, "height", {
792 /**
793 * Viewport height, without paddings
794 * @ko 뷰포트 높이
795 * @type {number}
796 * @readonly
797 */
798 get: function () {
799 return this._height - this._padding.top - this._padding.bottom;
800 },
801 enumerable: false,
802 configurable: true
803 });
804 Object.defineProperty(__proto, "padding", {
805 /**
806 * Viewport paddings
807 * @ko 뷰포트 CSS padding 값
808 * @type {object}
809 * @property {number} left CSS `padding-left`
810 * @property {number} right CSS `padding-right`
811 * @property {number} top CSS `padding-top`
812 * @property {number} bottom CSS `padding-bottom`
813 * @readonly
814 */
815 get: function () {
816 return this._padding;
817 },
818 enumerable: false,
819 configurable: true
820 });
821 /**
822 * Change viewport's size.
823 * This will change the actual size of `.flicking-viewport` element by changing its CSS width/height property
824 * @ko 뷰포트 크기를 변경합니다.
825 * `.flicking-viewport` 엘리먼트에 해당 크기의 CSS width/height를 적용합니다
826 * @param {object} [size] New viewport size<ko>새 뷰포트 크기</ko>
827 * @param {number|string} [size.width] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>
828 * @param {number|string} [size.height] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>
829 */
830
831 __proto.setSize = function (_a) {
832 var width = _a.width,
833 height = _a.height;
834 var el = this._el;
835 var padding = this._padding;
836 var isBorderBoxSizing = this._isBorderBoxSizing;
837
838 if (width != null) {
839 if (isString(width)) {
840 el.style.width = width;
841 } else {
842 var newWidth = isBorderBoxSizing ? width + padding.left + padding.right : width;
843 el.style.width = newWidth + "px";
844 }
845 }
846
847 if (height != null) {
848 if (isString(height)) {
849 el.style.height = height;
850 } else {
851 var newHeight = isBorderBoxSizing ? height + padding.top + padding.bottom : height;
852 el.style.height = newHeight + "px";
853 }
854 }
855
856 this.resize();
857 };
858 /**
859 * Update width/height to the current viewport element's size
860 * @ko 현재 뷰포트 엘리먼트의 크기로 너비/높이를 업데이트합니다
861 */
862
863
864 __proto.resize = function () {
865 var el = this._el;
866 var elStyle = getStyle(el);
867 this._width = el.clientWidth;
868 this._height = el.clientHeight;
869 this._padding = {
870 left: parseFloat(elStyle.paddingLeft),
871 right: parseFloat(elStyle.paddingRight),
872 top: parseFloat(elStyle.paddingTop),
873 bottom: parseFloat(elStyle.paddingBottom)
874 };
875 this._isBorderBoxSizing = elStyle.boxSizing === "border-box";
876 };
877
878 return Viewport;
879}();
880
881/**
882 * All possible @egjs/axes event keys
883 * @internal
884 */
885var EVENT = {
886 HOLD: "hold",
887 CHANGE: "change",
888 RELEASE: "release",
889 ANIMATION_END: "animationEnd",
890 FINISH: "finish"
891};
892/**
893 * An Axis key that Flicking uses
894 * @internal
895 */
896
897var POSITION_KEY = "flick";
898
899var STATE_TYPE;
900
901(function (STATE_TYPE) {
902 STATE_TYPE[STATE_TYPE["IDLE"] = 0] = "IDLE";
903 STATE_TYPE[STATE_TYPE["HOLDING"] = 1] = "HOLDING";
904 STATE_TYPE[STATE_TYPE["DRAGGING"] = 2] = "DRAGGING";
905 STATE_TYPE[STATE_TYPE["ANIMATING"] = 3] = "ANIMATING";
906 STATE_TYPE[STATE_TYPE["DISABLED"] = 4] = "DISABLED";
907})(STATE_TYPE || (STATE_TYPE = {}));
908/**
909 * A component that shows the current status of the user input or the animation
910 * @ko 현재 사용자 입력 또는 애니메이션 상태를 나타내는 컴포넌트
911 * @internal
912 */
913
914
915var State = function () {
916 function State() {
917 this._delta = 0;
918 this._targetPanel = null;
919 }
920
921 var __proto = State.prototype;
922 Object.defineProperty(__proto, "delta", {
923 /**
924 * A sum of delta values of change events from the last hold event of Axes
925 * @ko 이전 hold이벤트부터 change에 의해 발생한 이동 delta값의 합산
926 * @type {number}
927 * @readonly
928 */
929 get: function () {
930 return this._delta;
931 },
932 enumerable: false,
933 configurable: true
934 });
935 Object.defineProperty(__proto, "targetPanel", {
936 /**
937 * A panel to set as {@link Control#activePanel} after the animation is finished
938 * @ko 애니메이션 종료시 {@link Control#activePanel}로 설정할 패널
939 * @type {number}
940 * @readonly
941 */
942 get: function () {
943 return this._targetPanel;
944 },
945 set: function (val) {
946 this._targetPanel = val;
947 },
948 enumerable: false,
949 configurable: true
950 });
951 /**
952 * An callback which is called when state has changed to this state
953 * @ko 현재 상태로 돌입했을때 호출되는 콜백 함수
954 * @param {State} prevState An previous state<ko>이전 상태값</ko>
955 * @return {void}
956 */
957
958 __proto.onEnter = function (prevState) {
959 this._delta = prevState._delta;
960 this._targetPanel = prevState._targetPanel;
961 };
962 /**
963 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} event
964 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} 이벤트 핸들러
965 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
966 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
967 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} event of Axes
968 * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} 이벤트</ko>
969 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
970 * @return {void}
971 */
972
973
974 __proto.onHold = function (ctx) {// DO NOTHING
975 };
976 /**
977 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} event
978 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} 이벤트 핸들러
979 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
980 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
981 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} event of Axes
982 * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} 이벤트</ko>
983 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
984 * @return {void}
985 */
986
987
988 __proto.onChange = function (ctx) {// DO NOTHING
989 };
990 /**
991 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event
992 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트 핸들러
993 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
994 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
995 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of Axes
996 * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
997 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
998 * @return {void}
999 */
1000
1001
1002 __proto.onRelease = function (ctx) {// DO NOTHING
1003 };
1004 /**
1005 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} event
1006 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} 이벤트 핸들러
1007 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
1008 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
1009 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} event of Axes
1010 * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} 이벤트</ko>
1011 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
1012 * @return {void}
1013 */
1014
1015
1016 __proto.onAnimationEnd = function (ctx) {// DO NOTHING
1017 };
1018 /**
1019 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} event
1020 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} 이벤트 핸들러
1021 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
1022 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
1023 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} event of Axes<ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} 이벤트</ko>
1024 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
1025 * @return {void}
1026 */
1027
1028
1029 __proto.onFinish = function (ctx) {// DO NOTHING
1030 };
1031
1032 __proto._moveToChangedPosition = function (ctx) {
1033 var flicking = ctx.flicking,
1034 axesEvent = ctx.axesEvent,
1035 transitTo = ctx.transitTo;
1036 var delta = axesEvent.delta[POSITION_KEY];
1037
1038 if (!delta) {
1039 return;
1040 }
1041
1042 this._delta += delta;
1043 var camera = flicking.camera;
1044 var prevPosition = camera.position;
1045 var position = axesEvent.pos[POSITION_KEY];
1046 var newPosition = flicking.circularEnabled ? circulatePosition(position, camera.range.min, camera.range.max) : position;
1047 camera.lookAt(newPosition);
1048 var moveEvent = new ComponentEvent(EVENTS.MOVE, {
1049 isTrusted: axesEvent.isTrusted,
1050 holding: this.holding,
1051 direction: getDirection(0, axesEvent.delta[POSITION_KEY]),
1052 axesEvent: axesEvent
1053 });
1054 flicking.trigger(moveEvent);
1055
1056 if (moveEvent.isCanceled()) {
1057 // Return to previous position
1058 camera.lookAt(prevPosition);
1059 transitTo(STATE_TYPE.DISABLED);
1060 }
1061 };
1062
1063 return State;
1064}();
1065
1066/**
1067 * A default state when there's no user input and no animation's playing
1068 * @ko 사용자의 입력이 없고, 애니메이션이 동작하고있지 않은 기본 상태
1069 * @internal
1070 */
1071
1072var IdleState = function (_super) {
1073 __extends(IdleState, _super);
1074
1075 function IdleState() {
1076 var _this = _super !== null && _super.apply(this, arguments) || this;
1077 /**
1078 * Whether user is clicking or touching
1079 * @ko 현재 사용자가 클릭/터치중인지 여부
1080 * @type {false}
1081 * @readonly
1082 */
1083
1084
1085 _this.holding = false;
1086 /**
1087 * Whether Flicking's animating
1088 * @ko 현재 애니메이션 동작 여부
1089 * @type {false}
1090 * @readonly
1091 */
1092
1093 _this.animating = false;
1094 return _this;
1095 }
1096
1097 var __proto = IdleState.prototype;
1098
1099 __proto.onEnter = function () {
1100 this._delta = 0;
1101 this._targetPanel = null;
1102 };
1103
1104 __proto.onHold = function (ctx) {
1105 // Shouldn't do any action until any panels on flicking area
1106 var flicking = ctx.flicking,
1107 axesEvent = ctx.axesEvent,
1108 transitTo = ctx.transitTo;
1109
1110 if (flicking.renderer.panelCount <= 0) {
1111 transitTo(STATE_TYPE.DISABLED);
1112 return;
1113 }
1114
1115 var holdStartEvent = new ComponentEvent(EVENTS.HOLD_START, {
1116 axesEvent: axesEvent
1117 });
1118 flicking.trigger(holdStartEvent);
1119
1120 if (holdStartEvent.isCanceled()) {
1121 transitTo(STATE_TYPE.DISABLED);
1122 } else {
1123 transitTo(STATE_TYPE.HOLDING);
1124 }
1125 }; // By methods call
1126
1127
1128 __proto.onChange = function (ctx) {
1129 var flicking = ctx.flicking,
1130 axesEvent = ctx.axesEvent,
1131 transitTo = ctx.transitTo;
1132 var controller = flicking.control.controller;
1133 var animatingContext = controller.animatingContext;
1134 var moveStartEvent = new ComponentEvent(EVENTS.MOVE_START, {
1135 isTrusted: axesEvent.isTrusted,
1136 holding: this.holding,
1137 direction: getDirection(animatingContext.start, animatingContext.end),
1138 axesEvent: axesEvent
1139 });
1140 flicking.trigger(moveStartEvent);
1141
1142 if (moveStartEvent.isCanceled()) {
1143 transitTo(STATE_TYPE.DISABLED);
1144 } else {
1145 // Trigger AnimatingState's onChange, to trigger "move" event immediately
1146 transitTo(STATE_TYPE.ANIMATING).onChange(ctx);
1147 }
1148 };
1149
1150 return IdleState;
1151}(State);
1152
1153/**
1154 * A state that activates when user's holding the Flicking area, but not moved a single pixel yet
1155 * @ko 사용자의 입력이 시작되었으나, 아직 움직이지는 않은 상태
1156 * @internal
1157 */
1158
1159var HoldingState = function (_super) {
1160 __extends(HoldingState, _super);
1161
1162 function HoldingState() {
1163 var _this = _super !== null && _super.apply(this, arguments) || this;
1164 /**
1165 * Whether user is clicking or touching
1166 * @ko 현재 사용자가 클릭/터치중인지 여부
1167 * @type {true}
1168 * @readonly
1169 */
1170
1171
1172 _this.holding = true;
1173 /**
1174 * Whether Flicking's animating
1175 * @ko 현재 애니메이션 동작 여부
1176 * @type {false}
1177 * @readonly
1178 */
1179
1180 _this.animating = false;
1181 _this._releaseEvent = null;
1182 return _this;
1183 }
1184
1185 var __proto = HoldingState.prototype;
1186
1187 __proto.onChange = function (ctx) {
1188 var flicking = ctx.flicking,
1189 axesEvent = ctx.axesEvent,
1190 transitTo = ctx.transitTo;
1191 var inputEvent = axesEvent.inputEvent;
1192 var offset = flicking.horizontal ? inputEvent.offsetX : inputEvent.offsetY;
1193 var moveStartEvent = new ComponentEvent(EVENTS.MOVE_START, {
1194 isTrusted: axesEvent.isTrusted,
1195 holding: this.holding,
1196 direction: getDirection(0, -offset),
1197 axesEvent: axesEvent
1198 });
1199 flicking.trigger(moveStartEvent);
1200
1201 if (moveStartEvent.isCanceled()) {
1202 transitTo(STATE_TYPE.DISABLED);
1203 } else {
1204 // Trigger DraggingState's onChange, to trigger "move" event immediately
1205 transitTo(STATE_TYPE.DRAGGING).onChange(ctx);
1206 }
1207 };
1208
1209 __proto.onRelease = function (ctx) {
1210 var flicking = ctx.flicking,
1211 axesEvent = ctx.axesEvent,
1212 transitTo = ctx.transitTo;
1213 flicking.trigger(new ComponentEvent(EVENTS.HOLD_END, {
1214 axesEvent: axesEvent
1215 }));
1216
1217 if (axesEvent.delta.flick !== 0) {
1218 // Sometimes "release" event on axes triggered before "change" event
1219 // Especially if user flicked panel fast in really short amount of time
1220 // if delta is not zero, that means above case happened.
1221 // Event flow should be HOLD_START -> MOVE_START -> MOVE -> HOLD_END
1222 // At least one move event should be included between holdStart and holdEnd
1223 axesEvent.setTo({
1224 flick: flicking.camera.position
1225 }, 0);
1226 transitTo(STATE_TYPE.IDLE);
1227 return;
1228 } // Can't handle select event here,
1229 // As "finish" axes event happens
1230
1231
1232 this._releaseEvent = axesEvent;
1233 };
1234
1235 __proto.onFinish = function (ctx) {
1236 var e_1, _a;
1237
1238 var flicking = ctx.flicking,
1239 transitTo = ctx.transitTo; // Should transite to IDLE state before select event
1240 // As user expects hold is already finished
1241
1242 transitTo(STATE_TYPE.IDLE);
1243
1244 if (!this._releaseEvent) {
1245 return;
1246 } // Handle release event here
1247 // To prevent finish event called twice
1248
1249
1250 var releaseEvent = this._releaseEvent; // Static click
1251
1252 /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */
1253
1254 var srcEvent = releaseEvent.inputEvent.srcEvent;
1255 var clickedElement;
1256
1257 if (srcEvent.type === "touchend") {
1258 var touchEvent = srcEvent;
1259 var touch = touchEvent.changedTouches[0];
1260 clickedElement = document.elementFromPoint(touch.clientX, touch.clientY);
1261 } else {
1262 clickedElement = srcEvent.target;
1263 }
1264 /* eslint-enable */
1265
1266
1267 var panels = flicking.renderer.panels;
1268 var clickedPanel = null;
1269
1270 try {
1271 for (var panels_1 = __values(panels), panels_1_1 = panels_1.next(); !panels_1_1.done; panels_1_1 = panels_1.next()) {
1272 var panel = panels_1_1.value;
1273
1274 if (panel.contains(clickedElement)) {
1275 clickedPanel = panel;
1276 break;
1277 }
1278 }
1279 } catch (e_1_1) {
1280 e_1 = {
1281 error: e_1_1
1282 };
1283 } finally {
1284 try {
1285 if (panels_1_1 && !panels_1_1.done && (_a = panels_1.return)) _a.call(panels_1);
1286 } finally {
1287 if (e_1) throw e_1.error;
1288 }
1289 }
1290
1291 if (clickedPanel) {
1292 var cameraPosition = flicking.camera.position;
1293 var clickedPanelPosition = clickedPanel.position;
1294 flicking.trigger(new ComponentEvent(EVENTS.SELECT, {
1295 index: clickedPanel.index,
1296 panel: clickedPanel,
1297 // Direction to the clicked panel
1298 direction: getDirection(cameraPosition, clickedPanelPosition)
1299 }));
1300 }
1301 };
1302
1303 return HoldingState;
1304}(State);
1305
1306/**
1307 * A state that activates when user's dragging the Flicking area
1308 * @ko 사용자가 드래깅중인 상태
1309 * @internal
1310 */
1311
1312var DraggingState = function (_super) {
1313 __extends(DraggingState, _super);
1314
1315 function DraggingState() {
1316 var _this = _super !== null && _super.apply(this, arguments) || this;
1317 /**
1318 * Whether user is clicking or touching
1319 * @ko 현재 사용자가 클릭/터치중인지 여부
1320 * @type {true}
1321 * @readonly
1322 */
1323
1324
1325 _this.holding = true;
1326 /**
1327 * Whether Flicking's animating
1328 * @ko 현재 애니메이션 동작 여부
1329 * @type {true}
1330 * @readonly
1331 */
1332
1333 _this.animating = true;
1334 return _this;
1335 }
1336
1337 var __proto = DraggingState.prototype;
1338
1339 __proto.onChange = function (ctx) {
1340 this._moveToChangedPosition(ctx);
1341 };
1342
1343 __proto.onRelease = function (ctx) {
1344 var flicking = ctx.flicking,
1345 axesEvent = ctx.axesEvent,
1346 transitTo = ctx.transitTo; // Update last position to cope with Axes's animating behavior
1347 // Axes uses start position when animation start
1348
1349 flicking.trigger(new ComponentEvent(EVENTS.HOLD_END, {
1350 axesEvent: axesEvent
1351 }));
1352
1353 if (flicking.renderer.panelCount <= 0) {
1354 // There're no panels
1355 transitTo(STATE_TYPE.IDLE);
1356 return;
1357 }
1358
1359 transitTo(STATE_TYPE.ANIMATING);
1360 var control = flicking.control;
1361 var position = axesEvent.destPos[POSITION_KEY];
1362 var duration = Math.max(axesEvent.duration, flicking.duration);
1363 void control.moveToPosition(position, duration, axesEvent);
1364 };
1365
1366 return DraggingState;
1367}(State);
1368
1369/**
1370 * A state that activates when Flicking's animating by user input or method call
1371 * @ko 사용자 입력이나 메소드 호출에 의해 Flicking의 애니메이션이 동작중인 상태
1372 * @internal
1373 */
1374
1375var AnimatingState = function (_super) {
1376 __extends(AnimatingState, _super);
1377
1378 function AnimatingState() {
1379 var _this = _super !== null && _super.apply(this, arguments) || this;
1380 /**
1381 * Whether user is clicking or touching
1382 * @ko 현재 사용자가 클릭/터치중인지 여부
1383 * @type {false}
1384 * @readonly
1385 */
1386
1387
1388 _this.holding = false;
1389 /**
1390 * Whether Flicking's animating
1391 * @ko 현재 애니메이션 동작 여부
1392 * @type {true}
1393 * @readonly
1394 */
1395
1396 _this.animating = true;
1397 return _this;
1398 }
1399
1400 var __proto = AnimatingState.prototype;
1401
1402 __proto.onHold = function (ctx) {
1403 var flicking = ctx.flicking,
1404 axesEvent = ctx.axesEvent,
1405 transitTo = ctx.transitTo;
1406 this._delta = 0;
1407 flicking.control.updateInput();
1408 var holdStartEvent = new ComponentEvent(EVENTS.HOLD_START, {
1409 axesEvent: axesEvent
1410 });
1411 flicking.trigger(holdStartEvent);
1412
1413 if (holdStartEvent.isCanceled()) {
1414 transitTo(STATE_TYPE.DISABLED);
1415 } else {
1416 transitTo(STATE_TYPE.DRAGGING);
1417 }
1418 };
1419
1420 __proto.onChange = function (ctx) {
1421 this._moveToChangedPosition(ctx);
1422 };
1423
1424 __proto.onFinish = function (ctx) {
1425 var flicking = ctx.flicking,
1426 axesEvent = ctx.axesEvent,
1427 transitTo = ctx.transitTo;
1428 var control = flicking.control;
1429 var controller = control.controller;
1430 var animatingContext = controller.animatingContext;
1431 transitTo(STATE_TYPE.IDLE);
1432 flicking.trigger(new ComponentEvent(EVENTS.MOVE_END, {
1433 isTrusted: axesEvent.isTrusted,
1434 direction: getDirection(animatingContext.start, animatingContext.end),
1435 axesEvent: axesEvent
1436 }));
1437 control.setActive(this._targetPanel, control.activePanel, axesEvent.isTrusted);
1438 };
1439
1440 return AnimatingState;
1441}(State);
1442
1443/**
1444 * A state that activates when Flicking is stopped by event's `stop` method
1445 * @ko 이벤트의 `stop`호출에 의해 Flicking이 정지된 상태
1446 * @internal
1447 */
1448
1449var DisabledState = function (_super) {
1450 __extends(DisabledState, _super);
1451
1452 function DisabledState() {
1453 var _this = _super !== null && _super.apply(this, arguments) || this;
1454 /**
1455 * Whether user is clicking or touching
1456 * @ko 현재 사용자가 클릭/터치중인지 여부
1457 * @type {false}
1458 * @readonly
1459 */
1460
1461
1462 _this.holding = false;
1463 /**
1464 * Whether Flicking's animating
1465 * @ko 현재 애니메이션 동작 여부
1466 * @type {true}
1467 * @readonly
1468 */
1469
1470 _this.animating = true;
1471 return _this;
1472 }
1473
1474 var __proto = DisabledState.prototype;
1475
1476 __proto.onAnimationEnd = function (ctx) {
1477 var transitTo = ctx.transitTo;
1478 transitTo(STATE_TYPE.IDLE);
1479 };
1480
1481 __proto.onChange = function (ctx) {
1482 var axesEvent = ctx.axesEvent,
1483 transitTo = ctx.transitTo; // Can stop Axes's change event
1484
1485 axesEvent.stop();
1486 transitTo(STATE_TYPE.IDLE);
1487 };
1488
1489 __proto.onRelease = function (ctx) {
1490 var axesEvent = ctx.axesEvent,
1491 transitTo = ctx.transitTo; // This is needed when stopped hold start event
1492
1493 if (axesEvent.delta.flick === 0) {
1494 transitTo(STATE_TYPE.IDLE);
1495 }
1496 };
1497
1498 return DisabledState;
1499}(State);
1500
1501/**
1502 * @internal
1503 */
1504
1505var StateMachine = function () {
1506 function StateMachine() {
1507 var _this = this;
1508
1509 this.transitTo = function (nextStateType) {
1510 var nextState;
1511
1512 switch (nextStateType) {
1513 case STATE_TYPE.IDLE:
1514 nextState = new IdleState();
1515 break;
1516
1517 case STATE_TYPE.HOLDING:
1518 nextState = new HoldingState();
1519 break;
1520
1521 case STATE_TYPE.DRAGGING:
1522 nextState = new DraggingState();
1523 break;
1524
1525 case STATE_TYPE.ANIMATING:
1526 nextState = new AnimatingState();
1527 break;
1528
1529 case STATE_TYPE.DISABLED:
1530 nextState = new DisabledState();
1531 break;
1532 }
1533
1534 nextState.onEnter(_this._state);
1535 _this._state = nextState;
1536 return _this._state;
1537 };
1538
1539 this._state = new IdleState();
1540 }
1541
1542 var __proto = StateMachine.prototype;
1543 Object.defineProperty(__proto, "state", {
1544 get: function () {
1545 return this._state;
1546 },
1547 enumerable: false,
1548 configurable: true
1549 });
1550
1551 __proto.fire = function (eventType, externalCtx) {
1552 var currentState = this._state;
1553
1554 var ctx = __assign(__assign({}, externalCtx), {
1555 transitTo: this.transitTo
1556 });
1557
1558 switch (eventType) {
1559 case EVENT.HOLD:
1560 currentState.onHold(ctx);
1561 break;
1562
1563 case EVENT.CHANGE:
1564 currentState.onChange(ctx);
1565 break;
1566
1567 case EVENT.RELEASE:
1568 currentState.onRelease(ctx);
1569 break;
1570
1571 case EVENT.ANIMATION_END:
1572 currentState.onAnimationEnd(ctx);
1573 break;
1574
1575 case EVENT.FINISH:
1576 currentState.onFinish(ctx);
1577 break;
1578 }
1579 };
1580
1581 return StateMachine;
1582}();
1583
1584/*
1585 * Copyright (c) 2015 NAVER Corp.
1586 * egjs projects are licensed under the MIT license
1587 */
1588/**
1589 * A controller that handles the {@link https://naver.github.io/egjs-axes/ @egjs/axes} events
1590 * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 이벤트를 처리하는 컨트롤러 컴포넌트
1591 * @internal
1592 */
1593
1594var AxesController = function () {
1595 /** */
1596 function AxesController() {
1597 var _this = this;
1598
1599 this._onAxesHold = function () {
1600 _this._dragged = false;
1601 };
1602
1603 this._onAxesChange = function () {
1604 _this._dragged = true;
1605 };
1606
1607 this._preventClickWhenDragged = function (e) {
1608 if (_this._dragged) {
1609 e.preventDefault();
1610 e.stopPropagation();
1611 }
1612
1613 _this._dragged = false;
1614 };
1615
1616 this._resetInternalValues();
1617
1618 this._stateMachine = new StateMachine();
1619 }
1620
1621 var __proto = AxesController.prototype;
1622 Object.defineProperty(__proto, "axes", {
1623 /**
1624 * An {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
1625 * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes}의 인스턴스
1626 * @type {Axes}
1627 * @see https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html
1628 * @readonly
1629 */
1630 get: function () {
1631 return this._axes;
1632 },
1633 enumerable: false,
1634 configurable: true
1635 });
1636 Object.defineProperty(__proto, "stateMachine", {
1637 /**
1638 * @internal
1639 */
1640 get: function () {
1641 return this._stateMachine;
1642 },
1643 enumerable: false,
1644 configurable: true
1645 });
1646 Object.defineProperty(__proto, "state", {
1647 /**
1648 * A activated {@link State} that shows the current status of the user input or the animation
1649 * @ko 현재 활성화된 {@link State} 인스턴스로 사용자 입력 또는 애니메이션 상태를 나타냅니다
1650 * @type {State}
1651 */
1652 get: function () {
1653 return this._stateMachine.state;
1654 },
1655 enumerable: false,
1656 configurable: true
1657 });
1658 Object.defineProperty(__proto, "animatingContext", {
1659 /**
1660 * A context of the current animation playing
1661 * @ko 현재 재생중인 애니메이션 정보
1662 * @type {object}
1663 * @property {number} start A start position of the animation<ko>애니메이션 시작 지점</ko>
1664 * @property {number} end A end position of the animation<ko>애니메이션 끝 지점</ko>
1665 * @property {number} offset camera offset<ko>카메라 오프셋</ko>
1666 * @readonly
1667 */
1668 get: function () {
1669 return this._animatingContext;
1670 },
1671 enumerable: false,
1672 configurable: true
1673 });
1674 Object.defineProperty(__proto, "controlParams", {
1675 /**
1676 * A current control parameters of the Axes instance
1677 * @ko 활성화된 현재 Axes 패러미터들
1678 * @type {ControlParams}
1679 */
1680 get: function () {
1681 var axes = this._axes;
1682
1683 if (!axes) {
1684 return {
1685 range: {
1686 min: 0,
1687 max: 0
1688 },
1689 position: 0,
1690 circular: false
1691 };
1692 }
1693
1694 var axis = axes.axis[POSITION_KEY];
1695 return {
1696 range: {
1697 min: axis.range[0],
1698 max: axis.range[1]
1699 },
1700 circular: axis.circular[0],
1701 position: this.position
1702 };
1703 },
1704 enumerable: false,
1705 configurable: true
1706 });
1707 Object.defineProperty(__proto, "enabled", {
1708 /**
1709 * A Boolean indicating whether the user input is enabled
1710 * @ko 현재 사용자 입력이 활성화되었는지를 나타내는 값
1711 * @type {boolean}
1712 * @readonly
1713 */
1714 get: function () {
1715 var _a, _b;
1716
1717 return (_b = (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.isEnable()) !== null && _b !== void 0 ? _b : false;
1718 },
1719 enumerable: false,
1720 configurable: true
1721 });
1722 Object.defineProperty(__proto, "position", {
1723 /**
1724 * Current position value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
1725 * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 좌표 값
1726 * @type {number}
1727 * @readonly
1728 */
1729 get: function () {
1730 var _a, _b;
1731
1732 return (_b = (_a = this._axes) === null || _a === void 0 ? void 0 : _a.get([POSITION_KEY])[POSITION_KEY]) !== null && _b !== void 0 ? _b : 0;
1733 },
1734 enumerable: false,
1735 configurable: true
1736 });
1737 Object.defineProperty(__proto, "range", {
1738 /**
1739 * Current range value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
1740 * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 이동 범위 값
1741 * @type {number[]}
1742 * @readonly
1743 */
1744 get: function () {
1745 var _a, _b;
1746
1747 return (_b = (_a = this._axes) === null || _a === void 0 ? void 0 : _a.axis[POSITION_KEY].range) !== null && _b !== void 0 ? _b : [0, 0];
1748 },
1749 enumerable: false,
1750 configurable: true
1751 });
1752 Object.defineProperty(__proto, "bounce", {
1753 /**
1754 * Actual bounce size(px)
1755 * @ko 적용된 bounce 크기(px 단위)
1756 * @type {number[]}
1757 * @readonly
1758 */
1759 get: function () {
1760 var _a;
1761
1762 return (_a = this._axes) === null || _a === void 0 ? void 0 : _a.axis[POSITION_KEY].bounce;
1763 },
1764 enumerable: false,
1765 configurable: true
1766 });
1767 /**
1768 * Initialize AxesController
1769 * @ko AxesController를 초기화합니다
1770 * @param {Flicking} flicking An instance of Flicking
1771 * @chainable
1772 * @return {this}
1773 */
1774
1775 __proto.init = function (flicking) {
1776 var _a;
1777
1778 var _this = this;
1779
1780 this._flicking = flicking;
1781 this._axes = new Axes((_a = {}, _a[POSITION_KEY] = {
1782 range: [0, 0],
1783 circular: false,
1784 bounce: [0, 0]
1785 }, _a), {
1786 deceleration: flicking.deceleration,
1787 interruptable: flicking.interruptable,
1788 easing: flicking.easing
1789 });
1790 this._panInput = new PanInput(flicking.viewport.element, {
1791 inputType: flicking.inputType,
1792 iOSEdgeSwipeThreshold: flicking.iOSEdgeSwipeThreshold,
1793 scale: flicking.horizontal ? [-1, 0] : [0, -1],
1794 releaseOnScroll: true
1795 });
1796 var axes = this._axes;
1797 axes.connect(flicking.horizontal ? [POSITION_KEY, ""] : ["", POSITION_KEY], this._panInput);
1798
1799 var _loop_1 = function (key) {
1800 var eventType = EVENT[key];
1801 axes.on(eventType, function (e) {
1802 _this._stateMachine.fire(eventType, {
1803 flicking: flicking,
1804 axesEvent: e
1805 });
1806 });
1807 };
1808
1809 for (var key in EVENT) {
1810 _loop_1(key);
1811 }
1812
1813 return this;
1814 };
1815 /**
1816 * Destroy AxesController and return to initial state
1817 * @ko AxesController를 초기 상태로 되돌립니다
1818 * @return {void}
1819 */
1820
1821
1822 __proto.destroy = function () {
1823 var _a;
1824
1825 if (this._axes) {
1826 this.removePreventClickHandler();
1827
1828 this._axes.destroy();
1829 }
1830
1831 (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.destroy();
1832
1833 this._resetInternalValues();
1834 };
1835 /**
1836 * Enable input from the user (mouse/touch)
1837 * @ko 사용자의 입력(마우스/터치)를 활성화합니다
1838 * @chainable
1839 * @return {this}
1840 */
1841
1842
1843 __proto.enable = function () {
1844 var _a;
1845
1846 (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.enable();
1847 return this;
1848 };
1849 /**
1850 * Disable input from the user (mouse/touch)
1851 * @ko 사용자의 입력(마우스/터치)를 막습니다
1852 * @chainable
1853 * @return {this}
1854 */
1855
1856
1857 __proto.disable = function () {
1858 var _a;
1859
1860 (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.disable();
1861 return this;
1862 };
1863 /**
1864 * Update {@link https://naver.github.io/egjs-axes/ @egjs/axes}'s state
1865 * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 상태를 갱신합니다
1866 * @chainable
1867 * @throws {FlickingError}
1868 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link AxesController#init init} is not called before
1869 * <ko>{@link AxesController#init init}이 이전에 호출되지 않은 경우</ko>
1870 * @return {this}
1871 */
1872
1873
1874 __proto.update = function (controlParams) {
1875 var _a;
1876
1877 var flicking = getFlickingAttached(this._flicking, "Control");
1878 var camera = flicking.camera;
1879 var axes = this._axes;
1880 var axis = axes.axis[POSITION_KEY];
1881 axis.circular = [controlParams.circular, controlParams.circular];
1882 axis.range = [controlParams.range.min, controlParams.range.max];
1883 axis.bounce = parseBounce(flicking.bounce, camera.size);
1884 axes.axm.set((_a = {}, _a[POSITION_KEY] = controlParams.position, _a));
1885 return this;
1886 };
1887 /**
1888 * Attach a handler to the camera element to prevent click events during animation
1889 * @ko 카메라 엘리먼트에 애니메이션 도중에 클릭 이벤트를 방지하는 핸들러를 부착합니다
1890 * @return {this}
1891 */
1892
1893
1894 __proto.addPreventClickHandler = function () {
1895 var flicking = getFlickingAttached(this._flicking, "Control");
1896 var axes = this._axes;
1897 var cameraEl = flicking.camera.element;
1898 axes.on(EVENT.HOLD, this._onAxesHold);
1899 axes.on(EVENT.CHANGE, this._onAxesChange);
1900 cameraEl.addEventListener("click", this._preventClickWhenDragged, true);
1901 return this;
1902 };
1903 /**
1904 * Detach a handler to the camera element to prevent click events during animation
1905 * @ko 카메라 엘리먼트에 애니메이션 도중에 클릭 이벤트를 방지하는 핸들러를 탈착합니다
1906 * @return {this}
1907 */
1908
1909
1910 __proto.removePreventClickHandler = function () {
1911 var flicking = getFlickingAttached(this._flicking, "Control");
1912 var axes = this._axes;
1913 var cameraEl = flicking.camera.element;
1914 axes.off(EVENT.HOLD, this._onAxesHold);
1915 axes.off(EVENT.CHANGE, this._onAxesChange);
1916 cameraEl.removeEventListener("click", this._preventClickWhenDragged, true);
1917 return this;
1918 };
1919 /**
1920 * Run Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#setTo setTo} using the given position
1921 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#setTo setTo} 메소드를 주어진 좌표를 이용하여 수행합니다
1922 * @param {number} position A position to move<ko>이동할 좌표</ko>
1923 * @param {number} duration Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>
1924 * @param {number} [axesEvent] If provided, it'll use its {@link https://naver#github#io/egjs-axes/release/latest/doc/eg#Axes#html#setTo setTo} method instead<ko>이 값이 주어졌을 경우, 해당 이벤트의 {@link https://naver#github#io/egjs-axes/release/latest/doc/eg#Axes#html#setTo setTo} 메소드를 대신해서 사용합니다.</ko>
1925 * @throws {FlickingError}
1926 * |code|condition|
1927 * |---|---|
1928 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
1929 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
1930 * <ko>
1931 *
1932 * |code|condition|
1933 * |---|---|
1934 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
1935 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
1936 *
1937 * </ko>
1938 * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
1939 */
1940
1941
1942 __proto.animateTo = function (position, duration, axesEvent) {
1943 var _a;
1944
1945 var _this = this;
1946
1947 var axes = this._axes;
1948
1949 if (!axes) {
1950 return Promise.reject(new FlickingError(MESSAGE.NOT_ATTACHED_TO_FLICKING("Control"), CODE.NOT_ATTACHED_TO_FLICKING));
1951 }
1952
1953 var startPos = axes.get([POSITION_KEY])[POSITION_KEY];
1954
1955 if (startPos === position) {
1956 var flicking = getFlickingAttached(this._flicking, "Control");
1957 flicking.camera.lookAt(position);
1958 return Promise.resolve();
1959 }
1960
1961 this._animatingContext = {
1962 start: startPos,
1963 end: position,
1964 offset: 0
1965 };
1966
1967 var animate = function () {
1968 var _a, _b;
1969
1970 var resetContext = function () {
1971 _this._animatingContext = {
1972 start: 0,
1973 end: 0,
1974 offset: 0
1975 };
1976 };
1977
1978 axes.once(EVENT.FINISH, resetContext);
1979
1980 if (axesEvent) {
1981 axesEvent.setTo((_a = {}, _a[POSITION_KEY] = position, _a), duration);
1982 } else {
1983 axes.setTo((_b = {}, _b[POSITION_KEY] = position, _b), duration);
1984 }
1985 };
1986
1987 if (duration === 0) {
1988 var flicking = getFlickingAttached(this._flicking, "Control");
1989 var camera = flicking.camera;
1990 animate();
1991 var newPos = flicking.circularEnabled ? circulatePosition(position, camera.range.min, camera.range.max) : position;
1992 axes.axm.set((_a = {}, _a[POSITION_KEY] = newPos, _a));
1993 return Promise.resolve();
1994 } else {
1995 return new Promise(function (resolve, reject) {
1996 var animationFinishHandler = function () {
1997 axes.off(EVENT.HOLD, interruptionHandler);
1998 resolve();
1999 };
2000
2001 var interruptionHandler = function () {
2002 axes.off(EVENT.FINISH, animationFinishHandler);
2003 reject(new FlickingError(MESSAGE.ANIMATION_INTERRUPTED, CODE.ANIMATION_INTERRUPTED));
2004 };
2005
2006 axes.once(EVENT.FINISH, animationFinishHandler);
2007 axes.once(EVENT.HOLD, interruptionHandler);
2008 animate();
2009 });
2010 }
2011 };
2012
2013 __proto._resetInternalValues = function () {
2014 this._flicking = null;
2015 this._axes = null;
2016 this._panInput = null;
2017 this._animatingContext = {
2018 start: 0,
2019 end: 0,
2020 offset: 0
2021 };
2022 this._dragged = false;
2023 };
2024
2025 return AxesController;
2026}();
2027
2028/**
2029 * A component that manages inputs and animation of Flicking
2030 * @ko Flicking의 입력 장치 & 애니메이션을 담당하는 컴포넌트
2031 */
2032
2033var Control = function () {
2034 /** */
2035 function Control() {
2036 this._flicking = null;
2037 this._controller = new AxesController();
2038 this._activePanel = null;
2039 }
2040
2041 var __proto = Control.prototype;
2042 Object.defineProperty(__proto, "controller", {
2043 /**
2044 * A controller that handles the {@link https://naver.github.io/egjs-axes/ @egjs/axes} events
2045 * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 이벤트를 처리하는 컨트롤러 컴포넌트
2046 * @type {AxesController}
2047 * @readonly
2048 */
2049 get: function () {
2050 return this._controller;
2051 },
2052 enumerable: false,
2053 configurable: true
2054 });
2055 Object.defineProperty(__proto, "activeIndex", {
2056 /**
2057 * Index number of the {@link Flicking#currentPanel currentPanel}
2058 * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호
2059 * @type {number}
2060 * @default 0
2061 * @readonly
2062 */
2063 get: function () {
2064 var _a, _b;
2065
2066 return (_b = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.index) !== null && _b !== void 0 ? _b : -1;
2067 },
2068 enumerable: false,
2069 configurable: true
2070 });
2071 Object.defineProperty(__proto, "activePanel", {
2072 /**
2073 * An active panel
2074 * @ko 현재 선택된 패널
2075 * @type {Panel | null}
2076 * @readonly
2077 */
2078 get: function () {
2079 return this._activePanel;
2080 },
2081 enumerable: false,
2082 configurable: true
2083 });
2084 Object.defineProperty(__proto, "animating", {
2085 /**
2086 * Whether Flicking's animating
2087 * @ko 현재 애니메이션 동작 여부
2088 * @type {boolean}
2089 * @readonly
2090 */
2091 get: function () {
2092 return this._controller.state.animating;
2093 },
2094 enumerable: false,
2095 configurable: true
2096 });
2097 Object.defineProperty(__proto, "holding", {
2098 /**
2099 * Whether user is clicking or touching
2100 * @ko 현재 사용자가 클릭/터치중인지 여부
2101 * @type {boolean}
2102 * @readonly
2103 */
2104 get: function () {
2105 return this._controller.state.holding;
2106 },
2107 enumerable: false,
2108 configurable: true
2109 });
2110 /**
2111 * Initialize Control
2112 * @ko Control을 초기화합니다
2113 * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>
2114 * @chainable
2115 * @return {this}
2116 */
2117
2118 __proto.init = function (flicking) {
2119 this._flicking = flicking;
2120
2121 this._controller.init(flicking);
2122
2123 return this;
2124 };
2125 /**
2126 * Destroy Control and return to initial state
2127 * @ko Control을 초기 상태로 되돌립니다
2128 * @return {void}
2129 */
2130
2131
2132 __proto.destroy = function () {
2133 this._controller.destroy();
2134
2135 this._flicking = null;
2136 this._activePanel = null;
2137 };
2138 /**
2139 * Enable input from the user (mouse/touch)
2140 * @ko 사용자의 입력(마우스/터치)를 활성화합니다
2141 * @chainable
2142 * @return {this}
2143 */
2144
2145
2146 __proto.enable = function () {
2147 this._controller.enable();
2148
2149 return this;
2150 };
2151 /**
2152 * Disable input from the user (mouse/touch)
2153 * @ko 사용자의 입력(마우스/터치)를 막습니다
2154 * @chainable
2155 * @return {this}
2156 */
2157
2158
2159 __proto.disable = function () {
2160 this._controller.disable();
2161
2162 return this;
2163 };
2164 /**
2165 * Update position after resizing
2166 * @ko resize 이후에 position을 업데이트합니다
2167 * @param {number} progressInPanel Previous camera's progress in active panel before resize<ko>Resize 이전 현재 선택된 패널 내에서의 카메라 progress 값</ko>
2168 * @throws {FlickingError}
2169 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
2170 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
2171 * @chainable
2172 * @return {Promise<void>}
2173 */
2174
2175
2176 __proto.updatePosition = function (_progressInPanel) {
2177 var flicking = getFlickingAttached(this._flicking, "Control");
2178 var camera = flicking.camera;
2179 var activePanel = this._activePanel;
2180
2181 if (activePanel) {
2182 camera.lookAt(camera.clampToReachablePosition(activePanel.position));
2183 }
2184 };
2185 /**
2186 * Update {@link Control#controller controller}'s state
2187 * @ko {@link Control#controller controller}의 내부 상태를 갱신합니다
2188 * @chainable
2189 * @return {this}
2190 */
2191
2192
2193 __proto.updateInput = function () {
2194 var flicking = getFlickingAttached(this._flicking, "Control");
2195 var camera = flicking.camera;
2196
2197 this._controller.update(camera.controlParams);
2198
2199 return this;
2200 };
2201 /**
2202 * Reset {@link Control#activePanel activePanel} to `null`
2203 * @ko {@link Control#activePanel activePanel}을 `null`로 초기화합니다
2204 * @chainable
2205 * @return {this}
2206 */
2207
2208
2209 __proto.resetActive = function () {
2210 this._activePanel = null;
2211 return this;
2212 };
2213 /**
2214 * Move {@link Camera} to the given panel
2215 * @ko {@link Camera}를 해당 패널 위로 이동합니다
2216 * @param {Panel} panel The target panel to move<ko>이동할 패널</ko>
2217 * @param {object} options An options object<ko>옵션 오브젝트</ko>
2218 * @param {number} duration Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>
2219 * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}
2220 * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
2221 * @param {DIRECTION} [direction=DIRECTION.NONE] Direction to move, only available in the {@link Flicking#circular circular} mode<ko>이동할 방향. {@link Flicking#circular circular} 옵션 활성화시에만 사용 가능합니다</ko>
2222 * @fires Flicking#moveStart
2223 * @fires Flicking#move
2224 * @fires Flicking#moveEnd
2225 * @fires Flicking#willChange
2226 * @fires Flicking#changed
2227 * @fires Flicking#willRestore
2228 * @fires Flicking#restored
2229 * @fires Flicking#needPanel
2230 * @fires Flicking#visibleChange
2231 * @fires Flicking#reachEdge
2232 * @throws {FlickingError}
2233 * |code|condition|
2234 * |---|---|
2235 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
2236 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
2237 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
2238 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
2239 * <ko>
2240 *
2241 * |code|condition|
2242 * |---|---|
2243 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
2244 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
2245 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
2246 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
2247 *
2248 * </ko>
2249 * @return {Promise<void>} A Promise which will be resolved after reaching the target panel<ko>해당 패널 도달시에 resolve되는 Promise</ko>
2250 */
2251
2252
2253 __proto.moveToPanel = function (panel, _a) {
2254 var duration = _a.duration,
2255 _b = _a.direction,
2256 direction = _b === void 0 ? DIRECTION.NONE : _b,
2257 axesEvent = _a.axesEvent;
2258 return __awaiter(this, void 0, void 0, function () {
2259 var flicking, camera, position, nearestAnchor, camPos_1, camRangeDiff, possiblePositions;
2260 return __generator(this, function (_c) {
2261 flicking = getFlickingAttached(this._flicking, "Control");
2262 camera = flicking.camera;
2263 position = panel.position;
2264 nearestAnchor = camera.findNearestAnchor(position);
2265
2266 if (panel.removed || !nearestAnchor) {
2267 return [2
2268 /*return*/
2269 , Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(panel.position), CODE.POSITION_NOT_REACHABLE))];
2270 }
2271
2272 if (!camera.canReach(panel)) {
2273 // Override position & panel if that panel is not reachable
2274 position = nearestAnchor.position;
2275 panel = nearestAnchor.panel;
2276 } else if (flicking.circularEnabled) {
2277 camPos_1 = this._controller.position;
2278 camRangeDiff = camera.rangeDiff;
2279 possiblePositions = [position, position + camRangeDiff, position - camRangeDiff].filter(function (pos) {
2280 if (direction === DIRECTION.NONE) return true;
2281 return direction === DIRECTION.PREV ? pos <= camPos_1 : pos >= camPos_1;
2282 });
2283 position = possiblePositions.reduce(function (nearestPosition, pos) {
2284 if (Math.abs(camPos_1 - pos) < Math.abs(camPos_1 - nearestPosition)) {
2285 return pos;
2286 } else {
2287 return nearestPosition;
2288 }
2289 }, Infinity);
2290 }
2291
2292 this._triggerIndexChangeEvent(panel, panel.position, axesEvent);
2293
2294 return [2
2295 /*return*/
2296 , this._animateToPosition({
2297 position: position,
2298 duration: duration,
2299 newActivePanel: panel,
2300 axesEvent: axesEvent
2301 })];
2302 });
2303 });
2304 };
2305 /**
2306 * @internal
2307 */
2308
2309
2310 __proto.setActive = function (newActivePanel, prevActivePanel, isTrusted) {
2311 var _a;
2312
2313 var flicking = getFlickingAttached(this._flicking, "Control");
2314 this._activePanel = newActivePanel;
2315 flicking.camera.updateAdaptiveHeight();
2316
2317 if (newActivePanel !== prevActivePanel) {
2318 flicking.trigger(new ComponentEvent(EVENTS.CHANGED, {
2319 index: newActivePanel.index,
2320 panel: newActivePanel,
2321 prevIndex: (_a = prevActivePanel === null || prevActivePanel === void 0 ? void 0 : prevActivePanel.index) !== null && _a !== void 0 ? _a : -1,
2322 prevPanel: prevActivePanel,
2323 isTrusted: isTrusted,
2324 direction: prevActivePanel ? getDirection(prevActivePanel.position, newActivePanel.position) : DIRECTION.NONE
2325 }));
2326 } else {
2327 flicking.trigger(new ComponentEvent(EVENTS.RESTORED, {
2328 isTrusted: isTrusted
2329 }));
2330 }
2331 };
2332
2333 __proto._triggerIndexChangeEvent = function (panel, position, axesEvent) {
2334 var _a;
2335
2336 var flicking = getFlickingAttached(this._flicking, "Control");
2337 var triggeringEvent = panel !== this._activePanel ? EVENTS.WILL_CHANGE : EVENTS.WILL_RESTORE;
2338 var camera = flicking.camera;
2339 var activePanel = this._activePanel;
2340 var event = new ComponentEvent(triggeringEvent, {
2341 index: panel.index,
2342 panel: panel,
2343 isTrusted: (axesEvent === null || axesEvent === void 0 ? void 0 : axesEvent.isTrusted) || false,
2344 direction: getDirection((_a = activePanel === null || activePanel === void 0 ? void 0 : activePanel.position) !== null && _a !== void 0 ? _a : camera.position, position)
2345 });
2346 flicking.trigger(event);
2347
2348 if (event.isCanceled()) {
2349 throw new FlickingError(MESSAGE.STOP_CALLED_BY_USER, CODE.STOP_CALLED_BY_USER);
2350 }
2351 };
2352
2353 __proto._animateToPosition = function (_a) {
2354 var position = _a.position,
2355 duration = _a.duration,
2356 newActivePanel = _a.newActivePanel,
2357 axesEvent = _a.axesEvent;
2358 return __awaiter(this, void 0, void 0, function () {
2359 var flicking, animate, state;
2360
2361 var _this = this;
2362
2363 return __generator(this, function (_b) {
2364 flicking = getFlickingAttached(this._flicking, "Control");
2365
2366 animate = function () {
2367 return _this._controller.animateTo(position, duration, axesEvent);
2368 };
2369
2370 state = this._controller.state;
2371 state.targetPanel = newActivePanel;
2372
2373 if (duration <= 0) {
2374 return [2
2375 /*return*/
2376 , animate()];
2377 } else {
2378 return [2
2379 /*return*/
2380 , animate().then(function () {
2381 return __awaiter(_this, void 0, void 0, function () {
2382 return __generator(this, function (_a) {
2383 switch (_a.label) {
2384 case 0:
2385 return [4
2386 /*yield*/
2387 , flicking.renderer.render()];
2388
2389 case 1:
2390 _a.sent();
2391
2392 return [2
2393 /*return*/
2394 ];
2395 }
2396 });
2397 });
2398 }).catch(function (err) {
2399 if (axesEvent && err instanceof FlickingError && err.code === CODE.ANIMATION_INTERRUPTED) return;
2400 throw err;
2401 })];
2402 }
2403 });
2404 });
2405 };
2406
2407 return Control;
2408}();
2409
2410/**
2411 * A data component that has actual position where the camera should be stopped at
2412 * @ko 카메라가 정지해야하는 실제 위치를 담고 있는 데이터 컴포넌트
2413 */
2414var AnchorPoint = function () {
2415 /**
2416 * @param {object} options An options object<ko>옵션 객체</ko>
2417 * @param {number} [options.index] Index of AnchorPoint<ko>AnchorPoint의 인덱스</ko>
2418 * @param {number} [options.position] Position of AnchorPoint<ko>AnchorPoint의 좌표</ko>
2419 * @param {Panel} [options.panel] A {@link Panel} instance AnchorPoint is referencing to<ko>AnchorPoint가 참조하고 있는 {@link Panel}</ko>
2420 */
2421 function AnchorPoint(_a) {
2422 var index = _a.index,
2423 position = _a.position,
2424 panel = _a.panel;
2425 this._index = index;
2426 this._pos = position;
2427 this._panel = panel;
2428 }
2429
2430 var __proto = AnchorPoint.prototype;
2431 Object.defineProperty(__proto, "index", {
2432 /**
2433 * Index of AnchorPoint
2434 * @ko AnchorPoint의 인덱스
2435 * @type {number}
2436 * @readonly
2437 */
2438 get: function () {
2439 return this._index;
2440 },
2441 enumerable: false,
2442 configurable: true
2443 });
2444 Object.defineProperty(__proto, "position", {
2445 /**
2446 * Position of AnchorPoint
2447 * @ko AnchorPoint의 좌표
2448 * @type {number}
2449 * @readonly
2450 */
2451 get: function () {
2452 return this._pos;
2453 },
2454 enumerable: false,
2455 configurable: true
2456 });
2457 Object.defineProperty(__proto, "panel", {
2458 /**
2459 * A {@link Panel} instance AnchorPoint is referencing to
2460 * @ko AnchorPoint가 참조하고 있는 {@link Panel}
2461 * @type {Panel}
2462 * @readonly
2463 */
2464 get: function () {
2465 return this._panel;
2466 },
2467 enumerable: false,
2468 configurable: true
2469 });
2470 return AnchorPoint;
2471}();
2472
2473/**
2474 * A {@link Control} that uses a release momentum to choose destination panel
2475 * @ko 입력을 중단한 시점의 가속도에 영향받아 도달할 패널을 계산하는 이동 방식을 사용하는 {@link Control}
2476 */
2477
2478var SnapControl = function (_super) {
2479 __extends(SnapControl, _super);
2480 /** */
2481
2482
2483 function SnapControl(_a) {
2484 var _b = _a === void 0 ? {} : _a,
2485 _c = _b.count,
2486 count = _c === void 0 ? Infinity : _c;
2487
2488 var _this = _super.call(this) || this;
2489
2490 _this._count = count;
2491 return _this;
2492 }
2493
2494 var __proto = SnapControl.prototype;
2495 Object.defineProperty(__proto, "count", {
2496 /**
2497 * Maximum number of panels can go after release
2498 * @ko 입력 중단 이후 통과하여 이동할 수 있는 패널의 최대 갯수
2499 * @type {number}
2500 * @default Infinity
2501 */
2502 get: function () {
2503 return this._count;
2504 },
2505 set: function (val) {
2506 this._count = val;
2507 },
2508 enumerable: false,
2509 configurable: true
2510 });
2511 /**
2512 * Move {@link Camera} to the given position
2513 * @ko {@link Camera}를 주어진 좌표로 이동합니다
2514 * @param {number} position The target position to move<ko>이동할 좌표</ko>
2515 * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
2516 * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}
2517 * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
2518 * @fires Flicking#moveStart
2519 * @fires Flicking#move
2520 * @fires Flicking#moveEnd
2521 * @fires Flicking#willChange
2522 * @fires Flicking#changed
2523 * @fires Flicking#willRestore
2524 * @fires Flicking#restored
2525 * @fires Flicking#needPanel
2526 * @fires Flicking#visibleChange
2527 * @fires Flicking#reachEdge
2528 * @throws {FlickingError}
2529 * |code|condition|
2530 * |---|---|
2531 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
2532 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
2533 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
2534 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
2535 * <ko>
2536 *
2537 * |code|condition|
2538 * |---|---|
2539 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
2540 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
2541 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
2542 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
2543 *
2544 * </ko>
2545 * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
2546 */
2547
2548 __proto.moveToPosition = function (position, duration, axesEvent) {
2549 return __awaiter(this, void 0, void 0, function () {
2550 var flicking, camera, activeAnchor, anchorAtCamera, state, snapThreshold, posDelta, absPosDelta, snapDelta, targetAnchor;
2551 return __generator(this, function (_a) {
2552 flicking = getFlickingAttached(this._flicking, "Control");
2553 camera = flicking.camera;
2554 activeAnchor = camera.findActiveAnchor();
2555 anchorAtCamera = camera.findNearestAnchor(camera.position);
2556 state = flicking.control.controller.state;
2557
2558 if (!activeAnchor || !anchorAtCamera) {
2559 return [2
2560 /*return*/
2561 , Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE))];
2562 }
2563
2564 snapThreshold = this._calcSnapThreshold(position, activeAnchor);
2565 posDelta = flicking.animating ? state.delta : position - camera.position;
2566 absPosDelta = Math.abs(posDelta);
2567 snapDelta = axesEvent && axesEvent.delta[POSITION_KEY] !== 0 ? Math.abs(axesEvent.delta[POSITION_KEY]) : absPosDelta;
2568
2569 if (snapDelta >= snapThreshold && snapDelta > 0) {
2570 // Move to anchor at position
2571 targetAnchor = this._findSnappedAnchor(position, anchorAtCamera);
2572 } else if (absPosDelta >= flicking.threshold && absPosDelta > 0) {
2573 // Move to the adjacent panel
2574 targetAnchor = this._findAdjacentAnchor(posDelta, anchorAtCamera);
2575 } else {
2576 // Restore to active panel
2577 targetAnchor = anchorAtCamera;
2578 }
2579
2580 this._triggerIndexChangeEvent(targetAnchor.panel, position, axesEvent);
2581
2582 return [2
2583 /*return*/
2584 , this._animateToPosition({
2585 position: camera.clampToReachablePosition(targetAnchor.position),
2586 duration: duration,
2587 newActivePanel: targetAnchor.panel,
2588 axesEvent: axesEvent
2589 })];
2590 });
2591 });
2592 };
2593
2594 __proto._findSnappedAnchor = function (position, anchorAtCamera) {
2595 var flicking = getFlickingAttached(this._flicking, "Control");
2596 var camera = flicking.camera;
2597 var count = this._count;
2598 var currentPos = camera.position;
2599 var clampedPosition = camera.clampToReachablePosition(position);
2600 var anchorAtPosition = camera.findAnchorIncludePosition(clampedPosition);
2601
2602 if (!anchorAtCamera || !anchorAtPosition) {
2603 throw new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE);
2604 }
2605
2606 if (!isFinite(count)) {
2607 return anchorAtPosition;
2608 }
2609
2610 var panelCount = flicking.panelCount;
2611 var anchors = camera.anchorPoints;
2612 var loopCount = Math.sign(position - currentPos) * Math.floor(Math.abs(position - currentPos) / camera.rangeDiff);
2613
2614 if (position > currentPos && anchorAtPosition.index < anchorAtCamera.index || anchorAtPosition.position > anchorAtCamera.position && anchorAtPosition.index === anchorAtCamera.index) {
2615 loopCount += 1;
2616 } else if (position < currentPos && anchorAtPosition.index > anchorAtCamera.index || anchorAtPosition.position < anchorAtCamera.position && anchorAtPosition.index === anchorAtCamera.index) {
2617 loopCount -= 1;
2618 }
2619
2620 var circularIndexOffset = loopCount * panelCount;
2621 var anchorAtPositionIndex = anchorAtPosition.index + circularIndexOffset;
2622
2623 if (Math.abs(anchorAtPositionIndex - anchorAtCamera.index) <= count) {
2624 var anchor = anchors[anchorAtPosition.index];
2625 return new AnchorPoint({
2626 index: anchor.index,
2627 position: anchor.position + loopCount * camera.rangeDiff,
2628 panel: anchor.panel
2629 });
2630 }
2631
2632 if (flicking.circularEnabled) {
2633 var targetAnchor = anchors[circulateIndex(anchorAtCamera.index + Math.sign(position - currentPos) * count, panelCount)];
2634 var loop = Math.floor(count / panelCount);
2635
2636 if (position > currentPos && targetAnchor.index < anchorAtCamera.index) {
2637 loop += 1;
2638 } else if (position < currentPos && targetAnchor.index > anchorAtCamera.index) {
2639 loop -= 1;
2640 }
2641
2642 return new AnchorPoint({
2643 index: targetAnchor.index,
2644 position: targetAnchor.position + loop * camera.rangeDiff,
2645 panel: targetAnchor.panel
2646 });
2647 } else {
2648 return anchors[clamp(anchorAtCamera.index + Math.sign(position - currentPos) * count, 0, anchors.length - 1)];
2649 }
2650 };
2651
2652 __proto._findAdjacentAnchor = function (posDelta, anchorAtCamera) {
2653 var _a;
2654
2655 var flicking = getFlickingAttached(this._flicking, "Control");
2656 var camera = flicking.camera;
2657 var adjacentAnchor = (_a = posDelta > 0 ? camera.getNextAnchor(anchorAtCamera) : camera.getPrevAnchor(anchorAtCamera)) !== null && _a !== void 0 ? _a : anchorAtCamera;
2658 return adjacentAnchor;
2659 };
2660
2661 __proto._calcSnapThreshold = function (position, activeAnchor) {
2662 var isNextDirection = position > activeAnchor.position;
2663 var panel = activeAnchor.panel;
2664 var panelSize = panel.size;
2665 var alignPos = panel.alignPosition; // Minimum distance needed to decide prev/next panel as nearest
2666
2667 /*
2668 * | Prev | Next |
2669 * |<------>|<------------>|
2670 * [ |<-Anchor ]
2671 */
2672
2673 return isNextDirection ? panelSize - alignPos + panel.margin.next : alignPos + panel.margin.prev;
2674 };
2675
2676 return SnapControl;
2677}(Control);
2678
2679/**
2680 * A {@link Control} that can be scrolled freely without alignment
2681 * @ko 패널이 정해진 지점에 정렬되지 않고, 자유롭게 스크롤할 수 있는 이동 방식을 사용하는 {@link Control}
2682 */
2683
2684var FreeControl = function (_super) {
2685 __extends(FreeControl, _super);
2686 /** */
2687
2688
2689 function FreeControl(_a) {
2690 var _b = _a === void 0 ? {} : _a,
2691 _c = _b.stopAtEdge,
2692 stopAtEdge = _c === void 0 ? true : _c;
2693
2694 var _this = _super.call(this) || this;
2695
2696 _this._stopAtEdge = stopAtEdge;
2697 return _this;
2698 }
2699
2700 var __proto = FreeControl.prototype;
2701 Object.defineProperty(__proto, "stopAtEdge", {
2702 /**
2703 * Make scroll animation to stop at the start/end of the scroll area, not going out the bounce area
2704 * @ko 스크롤 애니메이션을 스크롤 영역의 시작과 끝부분에서 멈추도록 하여, 바운스 영역을 넘어가지 않도록 합니다
2705 * @type {boolean}
2706 * @default true
2707 */
2708 get: function () {
2709 return this._stopAtEdge;
2710 },
2711 set: function (val) {
2712 this._stopAtEdge = val;
2713 },
2714 enumerable: false,
2715 configurable: true
2716 });
2717 /**
2718 * Update position after resizing
2719 * @ko resize 이후에 position을 업데이트합니다
2720 * @param {number} progressInPanel Previous camera's progress in active panel before resize<ko>Resize 이전 현재 선택된 패널 내에서의 카메라 progress 값</ko>
2721 * @throws {FlickingError}
2722 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
2723 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
2724 * @chainable
2725 * @return {Promise<void>}
2726 */
2727
2728 __proto.updatePosition = function (progressInPanel) {
2729 var flicking = getFlickingAttached(this._flicking, "Control");
2730 var camera = flicking.camera;
2731 var activePanel = this._activePanel;
2732
2733 if (activePanel) {
2734 var panelRange = activePanel.range;
2735 var newPosition = panelRange.min + (panelRange.max - panelRange.min) * progressInPanel;
2736 camera.lookAt(camera.clampToReachablePosition(newPosition));
2737 }
2738 };
2739 /**
2740 * Move {@link Camera} to the given position
2741 * @ko {@link Camera}를 주어진 좌표로 이동합니다
2742 * @param {number} position The target position to move<ko>이동할 좌표</ko>
2743 * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
2744 * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}
2745 * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
2746 * @fires Flicking#moveStart
2747 * @fires Flicking#move
2748 * @fires Flicking#moveEnd
2749 * @fires Flicking#willChange
2750 * @fires Flicking#changed
2751 * @fires Flicking#willRestore
2752 * @fires Flicking#restored
2753 * @fires Flicking#needPanel
2754 * @fires Flicking#visibleChange
2755 * @fires Flicking#reachEdge
2756 * @throws {FlickingError}
2757 * |code|condition|
2758 * |---|---|
2759 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
2760 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
2761 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
2762 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
2763 * <ko>
2764 *
2765 * |code|condition|
2766 * |---|---|
2767 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
2768 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
2769 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
2770 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
2771 *
2772 * </ko>
2773 * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
2774 */
2775
2776
2777 __proto.moveToPosition = function (position, duration, axesEvent) {
2778 return __awaiter(this, void 0, void 0, function () {
2779 var flicking, camera, targetPos, anchorAtPosition, targetPanel;
2780 return __generator(this, function (_a) {
2781 flicking = getFlickingAttached(this._flicking, "Control");
2782 camera = flicking.camera;
2783 targetPos = camera.clampToReachablePosition(position);
2784 anchorAtPosition = camera.findAnchorIncludePosition(targetPos);
2785
2786 if (!anchorAtPosition) {
2787 return [2
2788 /*return*/
2789 , Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE))];
2790 }
2791
2792 targetPanel = anchorAtPosition.panel; // Trigger only change event
2793
2794 if (targetPanel !== this._activePanel) {
2795 this._triggerIndexChangeEvent(targetPanel, position, axesEvent);
2796 }
2797
2798 return [2
2799 /*return*/
2800 , this._animateToPosition({
2801 position: this._stopAtEdge ? targetPos : position,
2802 duration: duration,
2803 newActivePanel: targetPanel,
2804 axesEvent: axesEvent
2805 })];
2806 });
2807 });
2808 };
2809
2810 return FreeControl;
2811}(Control);
2812
2813/**
2814 * A {@link Control} that allow you to select the maximum number of panels to move at a time
2815 * @ko 한번에 최대로 이동할 패널의 개수를 선택 가능한 {@link Control}
2816 */
2817
2818var StrictControl = function (_super) {
2819 __extends(StrictControl, _super);
2820 /** */
2821
2822
2823 function StrictControl(_a) {
2824 var _b = _a === void 0 ? {} : _a,
2825 _c = _b.count,
2826 count = _c === void 0 ? 1 : _c;
2827
2828 var _this = _super.call(this) || this;
2829
2830 _this.setActive = function (newActivePanel, prevActivePanel, isTrusted) {
2831 _super.prototype.setActive.call(_this, newActivePanel, prevActivePanel, isTrusted);
2832
2833 _this.updateInput();
2834 };
2835
2836 _this._count = count;
2837
2838 _this._resetIndexRange();
2839
2840 return _this;
2841 }
2842
2843 var __proto = StrictControl.prototype;
2844 Object.defineProperty(__proto, "count", {
2845 /**
2846 * Maximum number of panels that can be moved at a time
2847 * @ko 최대로 움직일 수 있는 패널의 개수
2848 * @type {number}
2849 * @default 1
2850 */
2851 get: function () {
2852 return this._count;
2853 },
2854 set: function (val) {
2855 this._count = val;
2856 },
2857 enumerable: false,
2858 configurable: true
2859 });
2860 /**
2861 * Destroy Control and return to initial state
2862 * @ko Control을 초기 상태로 되돌립니다
2863 * @return {void}
2864 */
2865
2866 __proto.destroy = function () {
2867 _super.prototype.destroy.call(this);
2868
2869 this._resetIndexRange();
2870 };
2871 /**
2872 * Update {@link Control#controller controller}'s state
2873 * @ko {@link Control#controller controller}의 내부 상태를 갱신합니다
2874 * @chainable
2875 * @return {this}
2876 */
2877
2878
2879 __proto.updateInput = function () {
2880 var _a;
2881
2882 var flicking = getFlickingAttached(this._flicking, "Control");
2883 var camera = flicking.camera;
2884 var renderer = flicking.renderer;
2885 var controller = this._controller;
2886 var controlParams = camera.controlParams;
2887 var count = this._count;
2888 var activePanel = controller.state.animating ? (_a = camera.findNearestAnchor(camera.position)) === null || _a === void 0 ? void 0 : _a.panel : this._activePanel;
2889
2890 if (!activePanel) {
2891 controller.update(controlParams);
2892
2893 this._resetIndexRange();
2894
2895 return this;
2896 }
2897
2898 var cameraRange = controlParams.range;
2899 var currentPos = activePanel.position;
2900 var currentIndex = activePanel.index;
2901 var panelCount = renderer.panelCount;
2902 var prevPanelIndex = currentIndex - count;
2903 var nextPanelIndex = currentIndex + count;
2904
2905 if (prevPanelIndex < 0) {
2906 prevPanelIndex = flicking.circularEnabled ? getMinusCompensatedIndex((prevPanelIndex + 1) % panelCount - 1, panelCount) : clamp(prevPanelIndex, 0, panelCount - 1);
2907 }
2908
2909 if (nextPanelIndex >= panelCount) {
2910 nextPanelIndex = flicking.circularEnabled ? nextPanelIndex % panelCount : clamp(nextPanelIndex, 0, panelCount - 1);
2911 }
2912
2913 var prevPanel = renderer.panels[prevPanelIndex];
2914 var nextPanel = renderer.panels[nextPanelIndex];
2915 var prevPos = Math.max(prevPanel.position, cameraRange.min);
2916 var nextPos = Math.min(nextPanel.position, cameraRange.max);
2917
2918 if (prevPos > currentPos) {
2919 prevPos -= camera.rangeDiff;
2920 }
2921
2922 if (nextPos < currentPos) {
2923 nextPos += camera.rangeDiff;
2924 }
2925
2926 controlParams.range = {
2927 min: prevPos,
2928 max: nextPos
2929 };
2930
2931 if (controlParams.circular) {
2932 if (controlParams.position < prevPos) {
2933 controlParams.position += camera.rangeDiff;
2934 }
2935
2936 if (controlParams.position > nextPos) {
2937 controlParams.position -= camera.rangeDiff;
2938 }
2939 }
2940
2941 controlParams.circular = false;
2942 controller.update(controlParams);
2943 this._indexRange = {
2944 min: prevPanel.index,
2945 max: nextPanel.index
2946 };
2947 return this;
2948 };
2949 /**
2950 * Move {@link Camera} to the given position
2951 * @ko {@link Camera}를 주어진 좌표로 이동합니다
2952 * @param {number} position The target position to move<ko>이동할 좌표</ko>
2953 * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
2954 * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}
2955 * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
2956 * @fires Flicking#moveStart
2957 * @fires Flicking#move
2958 * @fires Flicking#moveEnd
2959 * @fires Flicking#willChange
2960 * @fires Flicking#changed
2961 * @fires Flicking#willRestore
2962 * @fires Flicking#restored
2963 * @fires Flicking#needPanel
2964 * @fires Flicking#visibleChange
2965 * @fires Flicking#reachEdge
2966 * @throws {FlickingError}
2967 * |code|condition|
2968 * |---|---|
2969 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
2970 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
2971 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
2972 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
2973 * <ko>
2974 *
2975 * |code|condition|
2976 * |---|---|
2977 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
2978 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
2979 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
2980 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
2981 *
2982 * </ko>
2983 * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
2984 */
2985
2986
2987 __proto.moveToPosition = function (position, duration, axesEvent) {
2988 return __awaiter(this, void 0, void 0, function () {
2989 var flicking, camera, activePanel, axesRange, indexRange, cameraRange, clampedPosition, anchorAtPosition, prevPos, isOverThreshold, adjacentAnchor, targetPos, targetPanel, anchors, firstAnchor, lastAnchor, shouldBounceToFirst, shouldBounceToLast, targetAnchor;
2990 return __generator(this, function (_a) {
2991 flicking = getFlickingAttached(this._flicking, "Control");
2992 camera = flicking.camera;
2993 activePanel = this._activePanel;
2994 axesRange = this._controller.range;
2995 indexRange = this._indexRange;
2996 cameraRange = camera.range;
2997 clampedPosition = clamp(camera.clampToReachablePosition(position), axesRange[0], axesRange[1]);
2998 anchorAtPosition = camera.findAnchorIncludePosition(clampedPosition);
2999
3000 if (!anchorAtPosition || !activePanel) {
3001 return [2
3002 /*return*/
3003 , Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE))];
3004 }
3005
3006 prevPos = activePanel.position;
3007 isOverThreshold = Math.abs(position - prevPos) >= flicking.threshold;
3008 adjacentAnchor = position > prevPos ? camera.getNextAnchor(anchorAtPosition) : camera.getPrevAnchor(anchorAtPosition);
3009 anchors = camera.anchorPoints;
3010 firstAnchor = anchors[0];
3011 lastAnchor = anchors[anchors.length - 1];
3012 shouldBounceToFirst = position <= cameraRange.min && isBetween(firstAnchor.panel.index, indexRange.min, indexRange.max);
3013 shouldBounceToLast = position >= cameraRange.max && isBetween(lastAnchor.panel.index, indexRange.min, indexRange.max);
3014
3015 if (shouldBounceToFirst || shouldBounceToLast) {
3016 targetAnchor = position < cameraRange.min ? firstAnchor : lastAnchor;
3017 targetPanel = targetAnchor.panel;
3018 targetPos = targetAnchor.position;
3019 } else if (isOverThreshold && anchorAtPosition.position !== activePanel.position) {
3020 // Move to anchor at position
3021 targetPanel = anchorAtPosition.panel;
3022 targetPos = anchorAtPosition.position;
3023 } else if (isOverThreshold && adjacentAnchor && isBetween(adjacentAnchor.index, indexRange.min, indexRange.max)) {
3024 // Move to adjacent anchor
3025 targetPanel = adjacentAnchor.panel;
3026 targetPos = adjacentAnchor.position;
3027 } else {
3028 // Restore to active panel
3029 targetPos = camera.clampToReachablePosition(activePanel.position);
3030 targetPanel = activePanel;
3031 }
3032
3033 this._triggerIndexChangeEvent(targetPanel, position, axesEvent);
3034
3035 return [2
3036 /*return*/
3037 , this._animateToPosition({
3038 position: targetPos,
3039 duration: duration,
3040 newActivePanel: targetPanel,
3041 axesEvent: axesEvent
3042 })];
3043 });
3044 });
3045 };
3046
3047 __proto._resetIndexRange = function () {
3048 this._indexRange = {
3049 min: 0,
3050 max: 0
3051 };
3052 };
3053
3054 return StrictControl;
3055}(Control);
3056
3057/**
3058 * A component that manages actual movement inside the viewport
3059 * @ko 뷰포트 내에서의 실제 움직임을 담당하는 컴포넌트
3060 */
3061
3062var Camera = function () {
3063 /** */
3064 function Camera(_a) {
3065 var _this = this;
3066
3067 var _b = _a === void 0 ? {} : _a,
3068 _c = _b.align,
3069 align = _c === void 0 ? ALIGN.CENTER : _c;
3070
3071 this._checkTranslateSupport = function () {
3072 var e_1, _a;
3073
3074 var transforms = ["webkitTransform", "msTransform", "MozTransform", "OTransform", "transform"];
3075 var supportedStyle = document.documentElement.style;
3076 var transformName = "";
3077
3078 try {
3079 for (var transforms_1 = __values(transforms), transforms_1_1 = transforms_1.next(); !transforms_1_1.done; transforms_1_1 = transforms_1.next()) {
3080 var prefixedTransform = transforms_1_1.value;
3081
3082 if (prefixedTransform in supportedStyle) {
3083 transformName = prefixedTransform;
3084 }
3085 }
3086 } catch (e_1_1) {
3087 e_1 = {
3088 error: e_1_1
3089 };
3090 } finally {
3091 try {
3092 if (transforms_1_1 && !transforms_1_1.done && (_a = transforms_1.return)) _a.call(transforms_1);
3093 } finally {
3094 if (e_1) throw e_1.error;
3095 }
3096 }
3097
3098 if (!transformName) {
3099 throw new FlickingError(MESSAGE.TRANSFORM_NOT_SUPPORTED, CODE.TRANSFORM_NOT_SUPPORTED);
3100 }
3101
3102 _this._transform = transformName;
3103 };
3104
3105 this._flicking = null;
3106
3107 this._resetInternalValues(); // Options
3108
3109
3110 this._align = align;
3111 }
3112
3113 var __proto = Camera.prototype;
3114 Object.defineProperty(__proto, "element", {
3115 // Internal states getter
3116
3117 /**
3118 * The camera(`.flicking-camera`) element
3119 * @ko 카메라(`.flicking-camera`) 엘리먼트
3120 * @type {HTMLElement}
3121 * @readonly
3122 */
3123 get: function () {
3124 return this._el;
3125 },
3126 enumerable: false,
3127 configurable: true
3128 });
3129 Object.defineProperty(__proto, "position", {
3130 /**
3131 * Current position of the camera
3132 * @ko Camera의 현재 좌표
3133 * @type {number}
3134 * @readonly
3135 */
3136 get: function () {
3137 return this._position;
3138 },
3139 enumerable: false,
3140 configurable: true
3141 });
3142 Object.defineProperty(__proto, "alignPosition", {
3143 /**
3144 * Align position inside the viewport where {@link Panel}'s {@link Panel#alignPosition alignPosition} should be located at
3145 * @ko 패널의 정렬 기준 위치. 뷰포트 내에서 {@link Panel}의 {@link Panel#alignPosition alignPosition}이 위치해야 하는 곳입니다
3146 * @type {number}
3147 * @readonly
3148 */
3149 get: function () {
3150 return this._alignPos;
3151 },
3152 enumerable: false,
3153 configurable: true
3154 });
3155 Object.defineProperty(__proto, "offset", {
3156 /**
3157 * Position offset, used for the {@link Flicking#renderOnlyVisible renderOnlyVisible} option
3158 * @ko Camera의 좌표 오프셋. {@link Flicking#renderOnlyVisible renderOnlyVisible} 옵션을 위해 사용됩니다.
3159 * @type {number}
3160 * @default 0
3161 * @readonly
3162 */
3163 get: function () {
3164 return this._offset;
3165 },
3166 enumerable: false,
3167 configurable: true
3168 });
3169 Object.defineProperty(__proto, "range", {
3170 /**
3171 * A range that Camera's {@link Camera#position position} can reach
3172 * @ko Camera의 {@link Camera#position position}이 도달 가능한 범위
3173 * @type {object}
3174 * @property {number} min A minimum position<ko>최소 위치</ko>
3175 * @property {number} min A maximum position<ko>최대 위치</ko>
3176 * @readonly
3177 */
3178 get: function () {
3179 return this._range;
3180 },
3181 enumerable: false,
3182 configurable: true
3183 });
3184 Object.defineProperty(__proto, "rangeDiff", {
3185 /**
3186 * A difference between Camera's minimum and maximum position that can reach
3187 * @ko Camera가 도달 가능한 최소/최대 좌표의 차이
3188 * @type {number}
3189 * @readonly
3190 */
3191 get: function () {
3192 return this._range.max - this._range.min;
3193 },
3194 enumerable: false,
3195 configurable: true
3196 });
3197 Object.defineProperty(__proto, "visiblePanels", {
3198 /**
3199 * An array of visible panels from the current position
3200 * @ko 현재 보이는 패널들의 배열
3201 * @type {Panel[]}
3202 * @readonly
3203 */
3204 get: function () {
3205 return this._visiblePanels;
3206 },
3207 enumerable: false,
3208 configurable: true
3209 });
3210 Object.defineProperty(__proto, "visibleRange", {
3211 /**
3212 * A range of the visible area from the current position
3213 * @ko 현재 위치에서 보이는 범위
3214 * @type {object}
3215 * @property {number} min A minimum position<ko>최소 위치</ko>
3216 * @property {number} min A maximum position<ko>최대 위치</ko>
3217 * @readonly
3218 */
3219 get: function () {
3220 return {
3221 min: this._position - this._alignPos,
3222 max: this._position - this._alignPos + this.size
3223 };
3224 },
3225 enumerable: false,
3226 configurable: true
3227 });
3228 Object.defineProperty(__proto, "anchorPoints", {
3229 /**
3230 * An array of {@link AnchorPoint}s that Camera can be stopped at
3231 * @ko 카메라가 도달 가능한 {@link AnchorPoint}의 목록
3232 * @type {AnchorPoint[]}
3233 * @readonly
3234 */
3235 get: function () {
3236 return this._anchors;
3237 },
3238 enumerable: false,
3239 configurable: true
3240 });
3241 Object.defineProperty(__proto, "controlParams", {
3242 /**
3243 * A current parameters of the Camera for updating {@link AxesController}
3244 * @ko {@link AxesController}를 업데이트하기 위한 현재 Camera 패러미터들
3245 * @type {ControlParams}
3246 * @readonly
3247 */
3248 get: function () {
3249 return {
3250 range: this._range,
3251 position: this._position,
3252 circular: false
3253 };
3254 },
3255 enumerable: false,
3256 configurable: true
3257 });
3258 Object.defineProperty(__proto, "atEdge", {
3259 /**
3260 * A Boolean value indicating whether Camera's over the minimum or maximum position reachable
3261 * @ko 현재 카메라가 도달 가능한 범위의 최소 혹은 최대점을 넘어섰는지를 나타냅니다
3262 * @type {boolean}
3263 * @readonly
3264 */
3265 get: function () {
3266 return this._position <= this._range.min || this._position >= this._range.max;
3267 },
3268 enumerable: false,
3269 configurable: true
3270 });
3271 Object.defineProperty(__proto, "size", {
3272 /**
3273 * Return the size of the viewport
3274 * @ko 뷰포트 크기를 반환합니다
3275 * @type {number}
3276 * @readonly
3277 */
3278 get: function () {
3279 var flicking = this._flicking;
3280 return flicking ? flicking.horizontal ? flicking.viewport.width : flicking.viewport.height : 0;
3281 },
3282 enumerable: false,
3283 configurable: true
3284 });
3285 Object.defineProperty(__proto, "progress", {
3286 /**
3287 * Return the camera's position progress from the first panel to last panel
3288 * Range is from 0 to last panel's index
3289 * @ko 첫번째 패널로부터 마지막 패널까지의 카메라 위치의 진행도를 반환합니다
3290 * 범위는 0부터 마지막 패널의 인덱스까지입니다
3291 * @type {number}
3292 * @readonly
3293 */
3294 get: function () {
3295 var flicking = this._flicking;
3296 var position = this._position + this._offset;
3297 var nearestAnchor = this.findNearestAnchor(this._position);
3298
3299 if (!flicking || !nearestAnchor) {
3300 return NaN;
3301 }
3302
3303 var nearestPanel = nearestAnchor.panel;
3304 var panelPos = nearestPanel.position + nearestPanel.offset;
3305 var bounceSize = flicking.control.controller.bounce;
3306 var _a = this.range,
3307 prevRange = _a.min,
3308 nextRange = _a.max;
3309 var rangeDiff = this.rangeDiff;
3310
3311 if (position === panelPos) {
3312 return nearestPanel.index;
3313 }
3314
3315 if (position < panelPos) {
3316 var prevPanel = nearestPanel.prev();
3317 var prevPosition = prevPanel ? prevPanel.position + prevPanel.offset : prevRange - bounceSize[0]; // Looped
3318
3319 if (prevPosition > panelPos) {
3320 prevPosition -= rangeDiff;
3321 }
3322
3323 return nearestPanel.index - 1 + getProgress(position, prevPosition, panelPos);
3324 } else {
3325 var nextPanel = nearestPanel.next();
3326 var nextPosition = nextPanel ? nextPanel.position + nextPanel.offset : nextRange + bounceSize[1]; // Looped
3327
3328 if (nextPosition < panelPos) {
3329 nextPosition += rangeDiff;
3330 }
3331
3332 return nearestPanel.index + getProgress(position, panelPos, nextPosition);
3333 }
3334 },
3335 enumerable: false,
3336 configurable: true
3337 });
3338 Object.defineProperty(__proto, "align", {
3339 // Options Getter
3340
3341 /**
3342 * A value indicating where the {@link Camera#alignPosition alignPosition} should be located at inside the viewport element
3343 * @ko {@link Camera#alignPosition alignPosition}이 뷰포트 엘리먼트 내의 어디에 위치해야 하는지를 나타내는 값
3344 * @type {ALIGN | string | number}
3345 */
3346 get: function () {
3347 return this._align;
3348 },
3349 // Options Setter
3350 set: function (val) {
3351 this._align = val;
3352 },
3353 enumerable: false,
3354 configurable: true
3355 });
3356 /**
3357 * Initialize Camera
3358 * @ko Camera를 초기화합니다
3359 * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>
3360 * @chainable
3361 * @throws {FlickingError}
3362 * {@link ERROR_CODE VAL_MUST_NOT_NULL} If the camera element(`.flicking-camera`) does not exist inside viewport element
3363 * <ko>{@link ERROR_CODE VAL_MUST_NOT_NULL} 뷰포트 엘리먼트 내부에 카메라 엘리먼트(`.flicking-camera`)가 존재하지 않을 경우</ko>
3364 * @return {this}
3365 */
3366
3367 __proto.init = function (flicking) {
3368 this._flicking = flicking;
3369 var viewportEl = flicking.viewport.element;
3370 checkExistence(viewportEl.firstElementChild, "First element child of the viewport element");
3371 this._el = viewportEl.firstElementChild;
3372
3373 this._checkTranslateSupport();
3374
3375 return this;
3376 };
3377 /**
3378 * Destroy Camera and return to initial state
3379 * @ko Camera를 초기 상태로 되돌립니다
3380 * @return {void}
3381 */
3382
3383
3384 __proto.destroy = function () {
3385 this._flicking = null;
3386
3387 this._resetInternalValues();
3388
3389 return this;
3390 };
3391 /**
3392 * Move to the given position and apply CSS transform
3393 * @ko 해당 좌표로 이동하고, CSS transform을 적용합니다
3394 * @param {number} pos A new position<ko>움직일 위치</ko>
3395 * @throws {FlickingError}
3396 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
3397 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
3398 * @return {this}
3399 */
3400
3401
3402 __proto.lookAt = function (pos) {
3403 var prevPos = this._position;
3404 this._position = pos;
3405
3406 this._refreshVisiblePanels();
3407
3408 this._checkNeedPanel();
3409
3410 this._checkReachEnd(prevPos, pos);
3411
3412 this._applyTransform();
3413 };
3414 /**
3415 * Return a previous {@link AnchorPoint} of given {@link AnchorPoint}
3416 * If it does not exist, return `null` instead
3417 * @ko 주어진 {@link AnchorPoint}의 이전 {@link AnchorPoint}를 반환합니다
3418 * 존재하지 않을 경우 `null`을 반환합니다
3419 * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>
3420 * @return {AnchorPoint | null} The previous {@link AnchorPoint}<ko>이전 {@link AnchorPoint}</ko>
3421 */
3422
3423
3424 __proto.getPrevAnchor = function (anchor) {
3425 return this._anchors[anchor.index - 1] || null;
3426 };
3427 /**
3428 * Return a next {@link AnchorPoint} of given {@link AnchorPoint}
3429 * If it does not exist, return `null` instead
3430 * @ko 주어진 {@link AnchorPoint}의 다음 {@link AnchorPoint}를 반환합니다
3431 * 존재하지 않을 경우 `null`을 반환합니다
3432 * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>
3433 * @return {AnchorPoint | null} The next {@link AnchorPoint}<ko>다음 {@link AnchorPoint}</ko>
3434 */
3435
3436
3437 __proto.getNextAnchor = function (anchor) {
3438 return this._anchors[anchor.index + 1] || null;
3439 };
3440 /**
3441 * Return the camera's position progress in the panel below
3442 * Value is from 0 to 1 when the camera's inside panel
3443 * Value can be lower than 0 or bigger than 1 when it's in the margin area
3444 * @ko 현재 카메라 아래 패널에서의 위치 진행도를 반환합니다
3445 * 반환값은 카메라가 패널 내부에 있을 경우 0부터 1까지의 값을 갖습니다
3446 * 패널의 margin 영역에 있을 경우 0보다 작거나 1보다 큰 값을 반환할 수 있습니다
3447 */
3448
3449
3450 __proto.getProgressInPanel = function (panel) {
3451 var panelRange = panel.range;
3452 return (this._position - panelRange.min) / (panelRange.max - panelRange.min);
3453 };
3454 /**
3455 * Return {@link AnchorPoint} that includes given position
3456 * If there's no {@link AnchorPoint} that includes the given position, return `null` instead
3457 * @ko 주어진 좌표를 포함하는 {@link AnchorPoint}를 반환합니다
3458 * 주어진 좌표를 포함하는 {@link AnchorPoint}가 없을 경우 `null`을 반환합니다
3459 * @param {number} position A position to check<ko>확인할 좌표</ko>
3460 * @return {AnchorPoint | null} The {@link AnchorPoint} that includes the given position<ko>해당 좌표를 포함하는 {@link AnchorPoint}</ko>
3461 */
3462
3463
3464 __proto.findAnchorIncludePosition = function (position) {
3465 var anchors = this._anchors;
3466 var anchorsIncludingPosition = anchors.filter(function (anchor) {
3467 return anchor.panel.includePosition(position, true);
3468 });
3469 return anchorsIncludingPosition.reduce(function (nearest, anchor) {
3470 if (!nearest) return anchor;
3471 return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
3472 }, null);
3473 };
3474 /**
3475 * Return {@link AnchorPoint} nearest to given position
3476 * If there're no {@link AnchorPoint}s, return `null` instead
3477 * @ko 해당 좌표에서 가장 가까운 {@link AnchorPoint}를 반환합니다
3478 * {@link AnchorPoint}가 하나도 없을 경우 `null`을 반환합니다
3479 * @param {number} position A position to check<ko>확인할 좌표</ko>
3480 * @return {AnchorPoint | null} The {@link AnchorPoint} nearest to the given position<ko>해당 좌표에 가장 인접한 {@link AnchorPoint}</ko>
3481 */
3482
3483
3484 __proto.findNearestAnchor = function (position) {
3485 var anchors = this._anchors;
3486 if (anchors.length <= 0) return null;
3487 var prevDist = Infinity;
3488
3489 for (var anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
3490 var anchor = anchors[anchorIdx];
3491 var dist = Math.abs(anchor.position - position);
3492
3493 if (dist > prevDist) {
3494 // Return previous anchor
3495 return anchors[anchorIdx - 1];
3496 }
3497
3498 prevDist = dist;
3499 } // Return last anchor
3500
3501
3502 return anchors[anchors.length - 1];
3503 };
3504 /**
3505 * Return {@link AnchorPoint} that matches {@link Flicking#currentPanel}
3506 * @ko 현재 {@link Flicking#currentPanel}에 해당하는 {@link AnchorPoint}를 반환합니다
3507 * @return {AnchorPoint | null}
3508 */
3509
3510
3511 __proto.findActiveAnchor = function () {
3512 var flicking = getFlickingAttached(this._flicking, "Camera");
3513 var activeIndex = flicking.control.activeIndex;
3514 return find(this._anchors, function (anchor) {
3515 return anchor.panel.index === activeIndex;
3516 });
3517 };
3518 /**
3519 * Clamp the given position between camera's range
3520 * @ko 주어진 좌표를 Camera가 도달 가능한 범위 사이의 값으로 만듭니다
3521 * @param {number} position A position to clamp<ko>범위를 제한할 좌표</ko>
3522 * @return {number} A clamped position<ko>범위 제한된 좌표</ko>
3523 */
3524
3525
3526 __proto.clampToReachablePosition = function (position) {
3527 var range = this._range;
3528 return clamp(position, range.min, range.max);
3529 };
3530 /**
3531 * Check whether the given panel is inside of the Camera's range
3532 * @ko 해당 {@link Panel}이 Camera가 도달 가능한 범위 내에 있는지를 반환합니다
3533 * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>
3534 * @return {boolean} Whether the panel's inside Camera's range<ko>도달 가능한 범위 내에 해당 패널이 존재하는지 여부</ko>
3535 */
3536
3537
3538 __proto.canReach = function (panel) {
3539 var range = this._range;
3540 if (panel.removed) return false;
3541 var panelPos = panel.position;
3542 return panelPos >= range.min && panelPos <= range.max;
3543 };
3544 /**
3545 * Check whether the given panel element is visible at the current position
3546 * @ko 현재 좌표에서 해당 패널 엘리먼트를 볼 수 있는지 여부를 반환합니다
3547 * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>
3548 * @return Whether the panel element is visible at the current position<ko>현재 위치에서 해당 패널 엘리먼트가 보이는지 여부</ko>
3549 */
3550
3551
3552 __proto.canSee = function (panel) {
3553 var visibleRange = this.visibleRange; // Should not include margin, as we don't declare what the margin is visible as what the panel is visible.
3554
3555 return panel.includeRange(visibleRange.min, visibleRange.max, false);
3556 };
3557 /**
3558 * Update Camera's {@link Camera#alignPosition alignPosition}
3559 * @ko Camera의 {@link Camera#alignPosition alignPosition}을 업데이트합니다
3560 * @chainable
3561 * @return {this}
3562 */
3563
3564
3565 __proto.updateAlignPos = function () {
3566 var align = this._align;
3567 var alignVal = typeof align === "object" ? align.camera : align;
3568 this._alignPos = parseAlign$1(alignVal, this.size);
3569 return this;
3570 };
3571 /**
3572 * Update Camera's {@link Camera#anchorPoints anchorPoints}
3573 * @ko Camera의 {@link Camera#anchorPoints anchorPoints}를 업데이트합니다
3574 * @throws {FlickingError}
3575 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
3576 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
3577 * @chainable
3578 * @return {this}
3579 */
3580
3581
3582 __proto.updateAnchors = function () {
3583 var flicking = getFlickingAttached(this._flicking, "Camera");
3584 var panels = flicking.renderer.panels;
3585 this._anchors = panels.map(function (panel, index) {
3586 return new AnchorPoint({
3587 index: index,
3588 position: panel.position,
3589 panel: panel
3590 });
3591 });
3592 return this;
3593 };
3594 /**
3595 * Update Viewport's height to active panel's height
3596 * @ko 현재 선택된 패널의 높이와 동일하도록 뷰포트의 높이를 업데이트합니다
3597 * @throws {FlickingError}
3598 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
3599 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
3600 * @chainable
3601 * @return {this}
3602 */
3603
3604
3605 __proto.updateAdaptiveHeight = function () {
3606 var flicking = getFlickingAttached(this._flicking, "Camera");
3607 var activePanel = flicking.control.activePanel;
3608 if (!flicking.horizontal || !flicking.adaptive || !activePanel) return;
3609 flicking.viewport.setSize({
3610 height: activePanel.height
3611 });
3612 };
3613
3614 __proto.updateOffset = function () {
3615 var flicking = getFlickingAttached(this._flicking, "Camera");
3616 var unRenderedPanels = flicking.panels.filter(function (panel) {
3617 return !panel.rendered;
3618 });
3619 var position = this._position;
3620 this._offset = unRenderedPanels.filter(function (panel) {
3621 return panel.position + panel.offset < position;
3622 }).reduce(function (offset, panel) {
3623 return offset + panel.sizeIncludingMargin;
3624 }, 0);
3625
3626 this._applyTransform();
3627 };
3628 /**
3629 * Reset the history of {@link Flicking#event:needPanel needPanel} events so it can be triggered again
3630 * @ko 발생한 {@link Flicking#event:needPanel needPanel} 이벤트들을 초기화하여 다시 발생할 수 있도록 합니다
3631 * @chainable
3632 * @return {this}
3633 */
3634
3635
3636 __proto.resetNeedPanelHistory = function () {
3637 this._needPanelTriggered = {
3638 prev: false,
3639 next: false
3640 };
3641 return this;
3642 };
3643
3644 __proto._resetInternalValues = function () {
3645 this._position = 0;
3646 this._alignPos = 0;
3647 this._offset = 0;
3648 this._range = {
3649 min: 0,
3650 max: 0
3651 };
3652 this._visiblePanels = [];
3653 this._anchors = [];
3654 this._needPanelTriggered = {
3655 prev: false,
3656 next: false
3657 };
3658 };
3659
3660 __proto._refreshVisiblePanels = function () {
3661 var _this = this;
3662
3663 var flicking = getFlickingAttached(this._flicking, "Camera");
3664 var panels = flicking.renderer.panels;
3665 var newVisiblePanels = panels.filter(function (panel) {
3666 return _this.canSee(panel);
3667 });
3668 var prevVisiblePanels = this._visiblePanels;
3669 this._visiblePanels = newVisiblePanels;
3670 var added = newVisiblePanels.filter(function (panel) {
3671 return !includes(prevVisiblePanels, panel);
3672 });
3673 var removed = prevVisiblePanels.filter(function (panel) {
3674 return !includes(newVisiblePanels, panel);
3675 });
3676
3677 if (added.length > 0 || removed.length > 0) {
3678 void flicking.renderer.render().then(function () {
3679 flicking.trigger(new ComponentEvent(EVENTS.VISIBLE_CHANGE, {
3680 added: added,
3681 removed: removed,
3682 visiblePanels: newVisiblePanels
3683 }));
3684 });
3685 }
3686 };
3687
3688 __proto._checkNeedPanel = function () {
3689 var needPanelTriggered = this._needPanelTriggered;
3690 if (needPanelTriggered.prev && needPanelTriggered.next) return;
3691 var flicking = getFlickingAttached(this._flicking, "Camera");
3692 var panels = flicking.renderer.panels;
3693
3694 if (panels.length <= 0) {
3695 if (!needPanelTriggered.prev) {
3696 flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
3697 direction: DIRECTION.PREV
3698 }));
3699 needPanelTriggered.prev = true;
3700 }
3701
3702 if (!needPanelTriggered.next) {
3703 flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
3704 direction: DIRECTION.NEXT
3705 }));
3706 needPanelTriggered.next = true;
3707 }
3708
3709 return;
3710 }
3711
3712 var cameraPosition = this._position;
3713 var cameraSize = this.size;
3714 var cameraRange = this._range;
3715 var needPanelThreshold = flicking.needPanelThreshold;
3716 var cameraPrev = cameraPosition - this._alignPos;
3717 var cameraNext = cameraPrev + cameraSize;
3718 var firstPanel = panels[0];
3719 var lastPanel = panels[panels.length - 1];
3720
3721 if (!needPanelTriggered.prev) {
3722 var firstPanelPrev = firstPanel.range.min;
3723
3724 if (cameraPrev <= firstPanelPrev + needPanelThreshold || cameraPosition <= cameraRange.min + needPanelThreshold) {
3725 flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
3726 direction: DIRECTION.PREV
3727 }));
3728 needPanelTriggered.prev = true;
3729 }
3730 }
3731
3732 if (!needPanelTriggered.next) {
3733 var lastPanelNext = lastPanel.range.max;
3734
3735 if (cameraNext >= lastPanelNext - needPanelThreshold || cameraPosition >= cameraRange.max - needPanelThreshold) {
3736 flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
3737 direction: DIRECTION.NEXT
3738 }));
3739 needPanelTriggered.next = true;
3740 }
3741 }
3742 };
3743
3744 __proto._checkReachEnd = function (prevPos, newPos) {
3745 var flicking = getFlickingAttached(this._flicking, "Camera");
3746 var range = this._range;
3747 var wasBetweenRange = prevPos > range.min && prevPos < range.max;
3748 var isBetweenRange = newPos > range.min && newPos < range.max;
3749 if (!wasBetweenRange || isBetweenRange) return;
3750 var direction = newPos <= range.min ? DIRECTION.PREV : DIRECTION.NEXT;
3751 flicking.trigger(new ComponentEvent(EVENTS.REACH_EDGE, {
3752 direction: direction
3753 }));
3754 };
3755
3756 __proto._applyTransform = function () {
3757 var el = this._el;
3758 var flicking = getFlickingAttached(this._flicking, "Camera");
3759 var actualPosition = this._position - this._alignPos - this._offset;
3760 el.style[this._transform] = flicking.horizontal ? "translate(" + -actualPosition + "px)" : "translate(0, " + -actualPosition + "px)";
3761 };
3762
3763 return Camera;
3764}();
3765
3766/**
3767 * A {@link Camera} that can move from the position of the first panel to the position of the last panel
3768 * @ko 첫번째 패널의 좌표로부터 마지막 패널의 좌표로까지 이동할 수 있는 종류의 {@link Camera}
3769 */
3770
3771var LinearCamera = function (_super) {
3772 __extends(LinearCamera, _super);
3773
3774 function LinearCamera() {
3775 return _super !== null && _super.apply(this, arguments) || this;
3776 }
3777 /**
3778 * Update {@link Camera#range range} of Camera
3779 * @ko Camera의 {@link Camera#range range}를 업데이트합니다
3780 * @chainable
3781 * @throws {FlickingError}
3782 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
3783 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
3784 * @return {this}
3785 */
3786
3787
3788 var __proto = LinearCamera.prototype;
3789
3790 __proto.updateRange = function () {
3791 var _a, _b;
3792
3793 var flicking = getFlickingAttached(this._flicking, "Camera");
3794 var renderer = flicking.renderer;
3795 var firstPanel = renderer.getPanel(0);
3796 var lastPanel = renderer.getPanel(renderer.panelCount - 1);
3797 this._range = {
3798 min: (_a = firstPanel === null || firstPanel === void 0 ? void 0 : firstPanel.position) !== null && _a !== void 0 ? _a : 0,
3799 max: (_b = lastPanel === null || lastPanel === void 0 ? void 0 : lastPanel.position) !== null && _b !== void 0 ? _b : 0
3800 };
3801 return this;
3802 };
3803
3804 return LinearCamera;
3805}(Camera);
3806
3807/**
3808 * A {@link Camera} that connects the last panel and the first panel, enabling continuous loop
3809 * @ko 첫번째 패널과 마지막 패널이 이어진 상태로, 무한히 회전할 수 있는 종류의 {@link Camera}
3810 */
3811
3812var CircularCamera = function (_super) {
3813 __extends(CircularCamera, _super);
3814
3815 function CircularCamera() {
3816 var _this = _super !== null && _super.apply(this, arguments) || this;
3817
3818 _this._circularOffset = 0;
3819 _this._circularEnabled = false;
3820 return _this;
3821 }
3822
3823 var __proto = CircularCamera.prototype;
3824 Object.defineProperty(__proto, "offset", {
3825 get: function () {
3826 return this._offset - this._circularOffset;
3827 },
3828 enumerable: false,
3829 configurable: true
3830 });
3831 Object.defineProperty(__proto, "controlParams", {
3832 get: function () {
3833 return {
3834 range: this._range,
3835 position: this._position,
3836 circular: this._circularEnabled
3837 };
3838 },
3839 enumerable: false,
3840 configurable: true
3841 });
3842
3843 __proto.getPrevAnchor = function (anchor) {
3844 if (!this._circularEnabled || anchor.index !== 0) return _super.prototype.getPrevAnchor.call(this, anchor);
3845 var anchors = this._anchors;
3846 var rangeDiff = this.rangeDiff;
3847 var lastAnchor = anchors[anchors.length - 1];
3848 return new AnchorPoint({
3849 index: lastAnchor.index,
3850 position: lastAnchor.position - rangeDiff,
3851 panel: lastAnchor.panel
3852 });
3853 };
3854
3855 __proto.getNextAnchor = function (anchor) {
3856 var anchors = this._anchors;
3857 if (!this._circularEnabled || anchor.index !== anchors.length - 1) return _super.prototype.getNextAnchor.call(this, anchor);
3858 var rangeDiff = this.rangeDiff;
3859 var firstAnchor = anchors[0];
3860 return new AnchorPoint({
3861 index: firstAnchor.index,
3862 position: firstAnchor.position + rangeDiff,
3863 panel: firstAnchor.panel
3864 });
3865 };
3866
3867 __proto.findAnchorIncludePosition = function (position) {
3868 if (!this._circularEnabled) return _super.prototype.findAnchorIncludePosition.call(this, position);
3869 var range = this._range;
3870 var positionInRange = circulatePosition(position, range.min, range.max);
3871
3872 var anchorInRange = _super.prototype.findAnchorIncludePosition.call(this, positionInRange);
3873
3874 if (!anchorInRange) return null;
3875 var rangeDiff = this.rangeDiff;
3876
3877 if (position < range.min) {
3878 var loopCount = -Math.floor((range.min - position) / rangeDiff) - 1;
3879 return new AnchorPoint({
3880 index: anchorInRange.index,
3881 position: anchorInRange.position + rangeDiff * loopCount,
3882 panel: anchorInRange.panel
3883 });
3884 } else if (position > range.max) {
3885 var loopCount = Math.floor((position - range.max) / rangeDiff) + 1;
3886 return new AnchorPoint({
3887 index: anchorInRange.index,
3888 position: anchorInRange.position + rangeDiff * loopCount,
3889 panel: anchorInRange.panel
3890 });
3891 }
3892
3893 return anchorInRange;
3894 };
3895
3896 __proto.clampToReachablePosition = function (position) {
3897 // Basically all position is reachable for circular camera
3898 return this._circularEnabled ? position : _super.prototype.clampToReachablePosition.call(this, position);
3899 };
3900
3901 __proto.canReach = function (panel) {
3902 if (panel.removed) return false;
3903 return this._circularEnabled // Always reachable on circular mode
3904 ? true : _super.prototype.canReach.call(this, panel);
3905 };
3906
3907 __proto.canSee = function (panel) {
3908 var range = this._range;
3909 var rangeDiff = this.rangeDiff;
3910 var visibleRange = this.visibleRange;
3911
3912 var visibleInCurrentRange = _super.prototype.canSee.call(this, panel);
3913
3914 if (!this._circularEnabled) {
3915 return visibleInCurrentRange;
3916 } // Check looped visible area for circular case
3917
3918
3919 if (visibleRange.min < range.min) {
3920 return visibleInCurrentRange || panel.includeRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff, false);
3921 } else if (visibleRange.max > range.max) {
3922 return visibleInCurrentRange || panel.includeRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff, false);
3923 }
3924
3925 return visibleInCurrentRange;
3926 };
3927 /**
3928 * Update {@link Camera#range range} of Camera
3929 * @ko Camera의 {@link Camera#range range}를 업데이트합니다
3930 * @chainable
3931 * @throws {FlickingError}
3932 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
3933 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
3934 * @return {this}
3935 */
3936
3937
3938 __proto.updateRange = function () {
3939 var flicking = getFlickingAttached(this._flicking, "Camera");
3940 var renderer = flicking.renderer;
3941 var panels = renderer.panels;
3942
3943 if (panels.length <= 0) {
3944 this._resetInternalValues();
3945
3946 return this;
3947 }
3948
3949 var firstPanel = panels[0];
3950 var lastPanel = panels[panels.length - 1];
3951 var firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
3952 var lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
3953 var visibleSize = this.size;
3954 var panelSizeSum = lastPanelNext - firstPanelPrev;
3955 var canSetCircularMode = panels.every(function (panel) {
3956 return panelSizeSum - panel.size >= visibleSize;
3957 });
3958 this._circularEnabled = canSetCircularMode;
3959
3960 if (canSetCircularMode) {
3961 this._range = {
3962 min: firstPanelPrev,
3963 max: lastPanelNext
3964 };
3965 panels.forEach(function (panel) {
3966 return panel.updateCircularToggleDirection();
3967 });
3968 } else {
3969 this._range = {
3970 min: firstPanel.position,
3971 max: lastPanel.position
3972 };
3973 }
3974
3975 this._updateCircularOffset();
3976
3977 return this;
3978 };
3979
3980 __proto.lookAt = function (pos) {
3981 var flicking = getFlickingAttached(this._flicking, "Camera");
3982 var prevPos = this._position;
3983 if (pos === prevPos) return _super.prototype.lookAt.call(this, pos);
3984 var panels = flicking.renderer.panels;
3985 var toggled = panels.map(function (panel) {
3986 return panel.toggle(prevPos, pos);
3987 });
3988 this._position = pos;
3989
3990 if (toggled.some(function (isToggled) {
3991 return isToggled;
3992 })) {
3993 this._updateCircularOffset();
3994
3995 void flicking.renderer.render();
3996 }
3997
3998 return _super.prototype.lookAt.call(this, pos);
3999 };
4000
4001 __proto._applyTransform = function () {
4002 var el = this._el;
4003 var flicking = getFlickingAttached(this._flicking, "Camera");
4004 var actualPosition = this._position - this._alignPos - this._offset + this._circularOffset;
4005 el.style[this._transform] = flicking.horizontal ? "translate(" + -actualPosition + "px)" : "translate(0, " + -actualPosition + "px)";
4006 };
4007
4008 __proto._resetInternalValues = function () {
4009 _super.prototype._resetInternalValues.call(this);
4010
4011 this._circularOffset = 0;
4012 this._circularEnabled = false;
4013 };
4014
4015 __proto._calcPanelAreaSum = function (panels) {
4016 return panels.reduce(function (sum, panel) {
4017 return sum + panel.sizeIncludingMargin;
4018 }, 0);
4019 };
4020
4021 __proto._updateCircularOffset = function () {
4022 if (!this._circularEnabled) {
4023 this._circularOffset = 0;
4024 return;
4025 }
4026
4027 var flicking = getFlickingAttached(this._flicking, "Camera");
4028 var toggledPrev = [];
4029 var toggledNext = [];
4030 flicking.panels.filter(function (panel) {
4031 return panel.toggled;
4032 }).forEach(function (panel) {
4033 if (panel.toggleDirection === DIRECTION.PREV) {
4034 toggledPrev.push(panel);
4035 } else {
4036 toggledNext.push(panel);
4037 }
4038 });
4039 this._circularOffset = this._calcPanelAreaSum(toggledPrev) - this._calcPanelAreaSum(toggledNext);
4040 };
4041
4042 return CircularCamera;
4043}(Camera);
4044
4045/**
4046 * A {@link Camera} that set range not to go out of the first/last panel, so it won't show empty spaces before/after the first/last panel
4047 * @ko 첫번째와 마지막 패널 밖으로 넘어가지 못하도록 범위를 설정하여, 첫번째/마지막 패널 전/후의 빈 공간을 보이지 않도록 하는 종류의 {@link Camera}
4048 */
4049
4050var BoundCamera = function (_super) {
4051 __extends(BoundCamera, _super);
4052
4053 function BoundCamera() {
4054 return _super !== null && _super.apply(this, arguments) || this;
4055 }
4056 /**
4057 * Update {@link Camera#range range} of Camera
4058 * @ko Camera의 {@link Camera#range range}를 업데이트합니다
4059 * @chainable
4060 * @throws {FlickingError}
4061 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
4062 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
4063 * @return {this}
4064 */
4065
4066
4067 var __proto = BoundCamera.prototype;
4068
4069 __proto.updateRange = function () {
4070 var flicking = getFlickingAttached(this._flicking, "Camera");
4071 var renderer = flicking.renderer;
4072 var alignPos = this._alignPos;
4073 var firstPanel = renderer.getPanel(0);
4074 var lastPanel = renderer.getPanel(renderer.panelCount - 1);
4075
4076 if (!firstPanel || !lastPanel) {
4077 this._range = {
4078 min: 0,
4079 max: 0
4080 };
4081 return this;
4082 }
4083
4084 var viewportSize = this.size;
4085 var firstPanelPrev = firstPanel.range.min;
4086 var lastPanelNext = lastPanel.range.max;
4087 var panelAreaSize = lastPanelNext - firstPanelPrev;
4088 var isBiggerThanViewport = viewportSize < panelAreaSize;
4089 var firstPos = firstPanelPrev + alignPos;
4090 var lastPos = lastPanelNext - viewportSize + alignPos;
4091
4092 if (isBiggerThanViewport) {
4093 this._range = {
4094 min: firstPos,
4095 max: lastPos
4096 };
4097 } else {
4098 var align = this._align;
4099 var alignVal = typeof align === "object" ? align.camera : align;
4100 var pos = firstPos + parseAlign$1(alignVal, lastPos - firstPos);
4101 this._range = {
4102 min: pos,
4103 max: pos
4104 };
4105 }
4106
4107 return this;
4108 };
4109
4110 __proto.updateAnchors = function () {
4111 var _this = this;
4112
4113 var flicking = getFlickingAttached(this._flicking, "Camera");
4114 var panels = flicking.renderer.panels;
4115
4116 if (panels.length <= 0) {
4117 this._anchors = [];
4118 return this;
4119 }
4120
4121 var range = this._range;
4122 var reachablePanels = panels.filter(function (panel) {
4123 return _this.canReach(panel);
4124 });
4125
4126 if (reachablePanels.length > 0) {
4127 var shouldPrependBoundAnchor = reachablePanels[0].position !== range.min;
4128 var shouldAppendBoundAnchor = reachablePanels[reachablePanels.length - 1].position !== range.max;
4129 var indexOffset_1 = shouldPrependBoundAnchor ? 1 : 0;
4130 var newAnchors = reachablePanels.map(function (panel, idx) {
4131 return new AnchorPoint({
4132 index: idx + indexOffset_1,
4133 position: panel.position,
4134 panel: panel
4135 });
4136 });
4137
4138 if (shouldPrependBoundAnchor) {
4139 newAnchors.splice(0, 0, new AnchorPoint({
4140 index: 0,
4141 position: range.min,
4142 panel: panels[reachablePanels[0].index - 1]
4143 }));
4144 }
4145
4146 if (shouldAppendBoundAnchor) {
4147 newAnchors.push(new AnchorPoint({
4148 index: newAnchors.length,
4149 position: range.max,
4150 panel: panels[reachablePanels[reachablePanels.length - 1].index + 1]
4151 }));
4152 }
4153
4154 this._anchors = newAnchors;
4155 } else if (range.min !== range.max) {
4156 // There're more than 2 panels
4157 var nearestPanelAtMin = this._findNearestPanel(range.min, panels);
4158
4159 var panelAtMin = nearestPanelAtMin.index === panels.length - 1 ? nearestPanelAtMin.prev() : nearestPanelAtMin;
4160 var panelAtMax = panelAtMin.next();
4161 this._anchors = [new AnchorPoint({
4162 index: 0,
4163 position: range.min,
4164 panel: panelAtMin
4165 }), new AnchorPoint({
4166 index: 1,
4167 position: range.max,
4168 panel: panelAtMax
4169 })];
4170 } else {
4171 this._anchors = [new AnchorPoint({
4172 index: 0,
4173 position: range.min,
4174 panel: this._findNearestPanel(range.min, panels)
4175 })];
4176 }
4177
4178 return this;
4179 };
4180
4181 __proto.findAnchorIncludePosition = function (position) {
4182 var range = this._range;
4183 var anchors = this._anchors;
4184 if (anchors.length <= 0) return null;
4185
4186 if (position <= range.min) {
4187 return anchors[0];
4188 } else if (position >= range.max) {
4189 return anchors[anchors.length - 1];
4190 } else {
4191 return _super.prototype.findAnchorIncludePosition.call(this, position);
4192 }
4193 };
4194
4195 __proto._findNearestPanel = function (pos, panels) {
4196 var prevDist = Infinity;
4197
4198 for (var panelIdx = 0; panelIdx < panels.length; panelIdx++) {
4199 var panel = panels[panelIdx];
4200 var dist = Math.abs(panel.position - pos);
4201
4202 if (dist > prevDist) {
4203 // Return previous anchor
4204 return panels[panelIdx - 1];
4205 }
4206
4207 prevDist = dist;
4208 } // Return last anchor
4209
4210
4211 return panels[panels.length - 1];
4212 };
4213
4214 return BoundCamera;
4215}(Camera);
4216
4217/**
4218 * A component that manages {@link Panel} and its elements
4219 * @ko {@link Panel}과 그 엘리먼트들을 관리하는 컴포넌트
4220 */
4221
4222var Renderer = function () {
4223 /**
4224 * @param {object} options An options object<ko>옵션 오브젝트</ko>
4225 * @param {Constants.ALIGN | string | number} [options.align] An {@link Flicking#align align} value that will be applied to all panels<ko>전체 패널에 적용될 {@link Flicking#align align} 값</ko>
4226 */
4227 function Renderer(_a) {
4228 var _b = _a === void 0 ? {} : _a,
4229 _c = _b.align,
4230 align = _c === void 0 ? ALIGN.CENTER : _c;
4231
4232 this._flicking = null;
4233 this._panels = []; // Bind options
4234
4235 this._align = align;
4236 }
4237
4238 var __proto = Renderer.prototype;
4239 Object.defineProperty(__proto, "panels", {
4240 // Internal states Getter
4241
4242 /**
4243 * Array of panels
4244 * @ko 전체 패널들의 배열
4245 * @type {Panel[]}
4246 * @readonly
4247 * @see Panel
4248 */
4249 get: function () {
4250 return this._panels;
4251 },
4252 enumerable: false,
4253 configurable: true
4254 });
4255 Object.defineProperty(__proto, "panelCount", {
4256 /**
4257 * Count of panels
4258 * @ko 전체 패널의 개수
4259 * @type {number}
4260 * @readonly
4261 */
4262 get: function () {
4263 return this._panels.length;
4264 },
4265 enumerable: false,
4266 configurable: true
4267 });
4268 Object.defineProperty(__proto, "align", {
4269 // Options Getter
4270
4271 /**
4272 * A {@link Panel}'s {@link Panel#align align} value that applied to all panels
4273 * @ko {@link Panel}에 공통적으로 적용할 {@link Panel#align align} 값
4274 * @type {Constants.ALIGN | string | number}
4275 */
4276 get: function () {
4277 return this._align;
4278 },
4279 // Options Setter
4280 set: function (val) {
4281 this._align = val;
4282
4283 var panelAlign = this._getPanelAlign();
4284
4285 this._panels.forEach(function (panel) {
4286 panel.align = panelAlign;
4287 });
4288 },
4289 enumerable: false,
4290 configurable: true
4291 });
4292 /**
4293 * Initialize Renderer
4294 * @ko Renderer를 초기화합니다
4295 * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>
4296 * @chainable
4297 * @return {this}
4298 */
4299
4300 __proto.init = function (flicking) {
4301 this._flicking = flicking;
4302
4303 this._collectPanels();
4304
4305 return this;
4306 };
4307 /**
4308 * Destroy Renderer and return to initial state
4309 * @ko Renderer를 초기 상태로 되돌립니다
4310 * @return {void}
4311 */
4312
4313
4314 __proto.destroy = function () {
4315 this._flicking = null;
4316 this._panels = [];
4317 };
4318 /**
4319 * Return the {@link Panel} at the given index. `null` if it doesn't exists.
4320 * @ko 주어진 인덱스에 해당하는 {@link Panel}을 반환합니다. 주어진 인덱스에 해당하는 패널이 존재하지 않을 경우 `null`을 반환합니다.
4321 * @return {Panel | null} Panel at the given index<ko>주어진 인덱스에 해당하는 패널</ko>
4322 * @see Panel
4323 */
4324
4325
4326 __proto.getPanel = function (index) {
4327 return this._panels[index] || null;
4328 };
4329 /**
4330 * Update all panel sizes
4331 * @ko 모든 패널의 크기를 업데이트합니다
4332 * @chainable
4333 * @return {this}
4334 */
4335
4336
4337 __proto.updatePanelSize = function () {
4338 var flicking = getFlickingAttached(this._flicking, "Renderer");
4339
4340 if (flicking.panelsPerView > 0) {
4341 this._updatePanelSizeByGrid(flicking);
4342 } else {
4343 flicking.panels.forEach(function (panel) {
4344 return panel.resize();
4345 });
4346 }
4347
4348 return this;
4349 };
4350 /**
4351 * Insert new panels at given index
4352 * This will increase index of panels after by the number of panels added
4353 * @ko 주어진 인덱스에 새로운 패널들을 추가합니다
4354 * 해당 인덱스보다 같거나 큰 인덱스를 가진 기존 패널들은 추가한 패널의 개수만큼 인덱스가 증가합니다.
4355 * @param {number} index Index to insert new panels at<ko>새로 패널들을 추가할 인덱스</ko>
4356 * @param {any[]} elements An array of element or framework component with element in it<ko>엘리먼트의 배열 혹은 프레임워크에서 엘리먼트를 포함한 컴포넌트들의 배열</ko>
4357 * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>
4358 */
4359
4360
4361 __proto.batchInsert = function () {
4362 var _this = this;
4363
4364 var items = [];
4365
4366 for (var _i = 0; _i < arguments.length; _i++) {
4367 items[_i] = arguments[_i];
4368 }
4369
4370 var panels = this._panels;
4371 var flicking = getFlickingAttached(this._flicking, "Renderer");
4372 var control = flicking.control;
4373
4374 var align = this._getPanelAlign();
4375
4376 var allPanelsInserted = items.reduce(function (addedPanels, item) {
4377 var _a;
4378
4379 var insertingIdx = getMinusCompensatedIndex(item.index, panels.length);
4380 var panelsPushed = panels.slice(insertingIdx);
4381 var panelsInserted = item.elements.map(function (el, idx) {
4382 return _this._createPanel(el, {
4383 index: insertingIdx + idx,
4384 align: align,
4385 flicking: flicking
4386 });
4387 });
4388 panels.splice.apply(panels, __spreadArray([insertingIdx, 0], __read(panelsInserted))); // Insert the actual elements as camera element's children
4389
4390 _this._insertPanelElements(panelsInserted, (_a = panelsPushed[0]) !== null && _a !== void 0 ? _a : null); // Resize the newly added panels
4391
4392
4393 panelsInserted.forEach(function (panel) {
4394 return panel.resize();
4395 }); // Update panel indexes & positions
4396
4397 panelsPushed.forEach(function (panel) {
4398 panel.increaseIndex(panelsInserted.length);
4399 panel.updatePosition();
4400 });
4401 return __spreadArray(__spreadArray([], __read(addedPanels)), __read(panelsInserted));
4402 }, []);
4403 if (allPanelsInserted.length <= 0) return []; // Update camera & control
4404
4405 this._updateCameraAndControl();
4406
4407 void this.render(); // Move to the first panel added if no panels existed
4408 // FIXME: fix for animating case
4409
4410 if (allPanelsInserted.length > 0 && !control.animating) {
4411 void control.moveToPanel(control.activePanel || allPanelsInserted[0], {
4412 duration: 0
4413 }).catch(function () {
4414 return void 0;
4415 });
4416 }
4417
4418 flicking.camera.updateOffset();
4419 flicking.trigger(new ComponentEvent(EVENTS.PANEL_CHANGE, {
4420 added: allPanelsInserted,
4421 removed: []
4422 }));
4423 this.checkPanelContentsReady(allPanelsInserted);
4424 return allPanelsInserted;
4425 };
4426 /**
4427 * Remove the panel at the given index
4428 * This will decrease index of panels after by the number of panels removed
4429 * @ko 주어진 인덱스의 패널을 제거합니다
4430 * 해당 인덱스보다 큰 인덱스를 가진 기존 패널들은 제거한 패널의 개수만큼 인덱스가 감소합니다
4431 * @param {number} index Index of panel to remove<ko>제거할 패널의 인덱스</ko>
4432 * @param {number} [deleteCount=1] Number of panels to remove from index<ko>`index` 이후로 제거할 패널의 개수</ko>
4433 * @return An array of removed panels<ko>제거된 패널들의 배열</ko>
4434 */
4435
4436
4437 __proto.batchRemove = function () {
4438 var _this = this;
4439
4440 var items = [];
4441
4442 for (var _i = 0; _i < arguments.length; _i++) {
4443 items[_i] = arguments[_i];
4444 }
4445
4446 var panels = this._panels;
4447 var flicking = getFlickingAttached(this._flicking, "Renderer");
4448 var camera = flicking.camera,
4449 control = flicking.control;
4450 var activePanel = control.activePanel;
4451 var activeIndex = control.activeIndex;
4452 var allPanelsRemoved = items.reduce(function (removed, item) {
4453 var index = item.index,
4454 deleteCount = item.deleteCount;
4455 var removingIdx = getMinusCompensatedIndex(index, panels.length);
4456 var panelsPulled = panels.slice(removingIdx + deleteCount);
4457 var panelsRemoved = panels.splice(removingIdx, deleteCount);
4458 if (panelsRemoved.length <= 0) return []; // Update panel indexes & positions
4459
4460 panelsPulled.forEach(function (panel) {
4461 panel.decreaseIndex(panelsRemoved.length);
4462 panel.updatePosition();
4463 });
4464
4465 _this._removePanelElements(panelsRemoved); // Remove panel elements
4466
4467
4468 panelsRemoved.forEach(function (panel) {
4469 return panel.destroy();
4470 }); // Update camera & control
4471
4472 _this._updateCameraAndControl();
4473
4474 if (includes(panelsRemoved, activePanel)) {
4475 control.resetActive();
4476 }
4477
4478 return __spreadArray(__spreadArray([], __read(removed)), __read(panelsRemoved));
4479 }, []);
4480 void this.render(); // FIXME: fix for animating case
4481
4482 if (allPanelsRemoved.length > 0 && !control.animating) {
4483 var targetPanel = includes(allPanelsRemoved, activePanel) ? panels[activeIndex] || panels[panels.length - 1] : activePanel;
4484
4485 if (targetPanel) {
4486 void control.moveToPanel(targetPanel, {
4487 duration: 0
4488 }).catch(function () {
4489 return void 0;
4490 });
4491 } else {
4492 // All panels removed
4493 camera.lookAt(0);
4494 }
4495 }
4496
4497 flicking.camera.updateOffset();
4498 flicking.trigger(new ComponentEvent(EVENTS.PANEL_CHANGE, {
4499 added: [],
4500 removed: allPanelsRemoved
4501 }));
4502 return allPanelsRemoved;
4503 };
4504 /**
4505 * @internal
4506 */
4507
4508
4509 __proto.checkPanelContentsReady = function (checkingPanels) {
4510 var _this = this;
4511
4512 var resizeOnContentsReady = getFlickingAttached(this._flicking, "Renderer").resizeOnContentsReady;
4513 var panels = this._panels;
4514 if (!resizeOnContentsReady) return;
4515
4516 var hasContents = function (panel) {
4517 return !!panel.element.querySelector("img, video");
4518 };
4519
4520 checkingPanels = checkingPanels.filter(function (panel) {
4521 return hasContents(panel);
4522 });
4523 if (checkingPanels.length <= 0) return;
4524 var contentsReadyChecker = new ImReady();
4525 checkingPanels.forEach(function (panel) {
4526 panel.loading = true;
4527 });
4528 contentsReadyChecker.on("readyElement", function (e) {
4529 var flicking = _this._flicking;
4530
4531 if (!flicking) {
4532 // Renderer's destroy() is called before
4533 contentsReadyChecker.destroy();
4534 return;
4535 }
4536
4537 var panel = checkingPanels[e.index];
4538 var camera = flicking.camera;
4539 var control = flicking.control;
4540 var prevProgressInPanel = control.activePanel ? camera.getProgressInPanel(control.activePanel) : 0;
4541 panel.loading = false;
4542 panel.resize();
4543 panels.slice(panel.index + 1).forEach(function (panelBehind) {
4544 return panelBehind.updatePosition();
4545 });
4546 if (!flicking.initialized) return;
4547 camera.updateRange();
4548 camera.updateAnchors();
4549
4550 if (control.animating) ; else {
4551 control.updatePosition(prevProgressInPanel);
4552 control.updateInput();
4553 }
4554 });
4555 contentsReadyChecker.on("preReady", function (e) {
4556 if (_this._flicking) {
4557 void _this.render();
4558 }
4559
4560 if (e.readyCount === e.totalCount) {
4561 contentsReadyChecker.destroy();
4562 }
4563 });
4564 contentsReadyChecker.on("ready", function () {
4565 if (_this._flicking) {
4566 void _this.render();
4567 }
4568
4569 contentsReadyChecker.destroy();
4570 });
4571 contentsReadyChecker.check(checkingPanels.map(function (panel) {
4572 return panel.element;
4573 }));
4574 };
4575
4576 __proto._getPanelAlign = function () {
4577 var align = this._align;
4578 return typeof align === "object" ? align.panel : align;
4579 };
4580
4581 __proto._updateCameraAndControl = function () {
4582 var flicking = getFlickingAttached(this._flicking, "Renderer");
4583 var camera = flicking.camera,
4584 control = flicking.control;
4585 camera.updateRange();
4586 camera.updateAnchors();
4587 camera.resetNeedPanelHistory();
4588 control.updateInput();
4589 };
4590
4591 __proto._updateRenderingPanels = function () {
4592 var flicking = getFlickingAttached(this._flicking, "Renderer");
4593
4594 if (flicking.renderOnlyVisible) {
4595 this._showOnlyVisiblePanels(flicking);
4596 } else {
4597 flicking.panels.forEach(function (panel) {
4598 return panel.markForShow();
4599 });
4600 }
4601 };
4602
4603 __proto._showOnlyVisiblePanels = function (flicking) {
4604 var panels = flicking.renderer.panels;
4605 var camera = flicking.camera;
4606 var visibleIndexes = camera.visiblePanels.reduce(function (visibles, panel) {
4607 visibles[panel.index] = true;
4608 return visibles;
4609 }, {});
4610 panels.forEach(function (panel) {
4611 if (panel.index in visibleIndexes || panel.loading) {
4612 panel.markForShow();
4613 } else if (!flicking.holding) {
4614 // During the input sequence,
4615 // Do not remove panel elements as it won't trigger touchend event.
4616 panel.markForHide();
4617 }
4618 });
4619 camera.updateOffset();
4620 };
4621
4622 __proto._updatePanelSizeByGrid = function (flicking) {
4623 var panels = flicking.panels;
4624 var panelsPerView = flicking.panelsPerView;
4625
4626 if (panelsPerView <= 0) {
4627 throw new FlickingError(MESSAGE.WRONG_OPTION("panelsPerView", panelsPerView), CODE.WRONG_OPTION);
4628 }
4629
4630 if (panels.length <= 0) return; // resize only the first panel
4631
4632 var firstPanel = panels[0];
4633 firstPanel.resize();
4634 var viewportSize = flicking.camera.size;
4635 var gap = firstPanel.margin.prev + firstPanel.margin.next;
4636 var panelSize = (viewportSize - gap * (panelsPerView - 1)) / panelsPerView;
4637 var panelSizeObj = flicking.horizontal ? {
4638 width: panelSize
4639 } : {
4640 height: panelSize
4641 };
4642 var firstPanelSizeObj = {
4643 size: panelSize,
4644 height: firstPanel.height,
4645 margin: firstPanel.margin
4646 };
4647
4648 if (!flicking.noPanelStyleOverride) {
4649 flicking.panels.forEach(function (panel) {
4650 return panel.setSize(panelSizeObj);
4651 });
4652 }
4653
4654 flicking.panels.forEach(function (panel) {
4655 return panel.resize(firstPanelSizeObj);
4656 });
4657 };
4658
4659 return Renderer;
4660}();
4661
4662var Panel = function () {
4663 /**
4664 * @param {object} options An options object<ko>옵션 오브젝트</ko>
4665 * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>
4666 * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>
4667 * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>
4668 */
4669 function Panel(_a) {
4670 var index = _a.index,
4671 align = _a.align,
4672 flicking = _a.flicking;
4673 this._index = index;
4674 this._flicking = flicking;
4675 this._align = align;
4676 this._removed = false;
4677 this._loading = false;
4678
4679 this._resetInternalStates();
4680 }
4681
4682 var __proto = Panel.prototype;
4683 Object.defineProperty(__proto, "index", {
4684 /**
4685 * Index of the panel
4686 * @ko 패널의 인덱스
4687 * @type {number}
4688 * @readonly
4689 */
4690 get: function () {
4691 return this._index;
4692 },
4693 enumerable: false,
4694 configurable: true
4695 });
4696 Object.defineProperty(__proto, "position", {
4697 /**
4698 * Position of the panel, including {@link Panel#alignPosition alignPosition}
4699 * @ko 패널의 현재 좌표, {@link Panel#alignPosition alignPosition}을 포함하고 있습니다
4700 * @type {number}
4701 * @readonly
4702 */
4703 get: function () {
4704 return this._pos + this._alignPos;
4705 },
4706 enumerable: false,
4707 configurable: true
4708 });
4709 Object.defineProperty(__proto, "size", {
4710 /**
4711 * Cached size of the panel element
4712 * This is equal to {@link Panel#element element}'s `offsetWidth` if {@link Flicking#horizontal horizontal} is `true`, and `offsetHeight` else
4713 * @ko 패널 엘리먼트의 캐시된 크기
4714 * 이 값은 {@link Flicking#horizontal horizontal}이 `true`일 경우 {@link Panel#element element}의 `offsetWidth`와 동일하고, `false`일 경우 `offsetHeight`와 동일합니다
4715 * @type {number}
4716 * @readonly
4717 */
4718 get: function () {
4719 return this._size;
4720 },
4721 enumerable: false,
4722 configurable: true
4723 });
4724 Object.defineProperty(__proto, "sizeIncludingMargin", {
4725 /**
4726 * Panel's size including CSS `margin`
4727 * This value includes {@link Panel#element element}'s margin left/right if {@link Flicking#horizontal horizontal} is `true`, and margin top/bottom else
4728 * @ko CSS `margin`을 포함한 패널의 크기
4729 * 이 값은 {@link Flicking#horizontal horizontal}이 `true`일 경우 margin left/right을 포함하고, `false`일 경우 margin top/bottom을 포함합니다
4730 * @type {number}
4731 * @readonly
4732 */
4733 get: function () {
4734 return this._size + this._margin.prev + this._margin.next;
4735 },
4736 enumerable: false,
4737 configurable: true
4738 });
4739 Object.defineProperty(__proto, "height", {
4740 /**
4741 * Height of the panel element
4742 * @ko 패널 엘리먼트의 높이
4743 * @type {number}
4744 * @readonly
4745 */
4746 get: function () {
4747 return this._height;
4748 },
4749 enumerable: false,
4750 configurable: true
4751 });
4752 Object.defineProperty(__proto, "margin", {
4753 /**
4754 * Cached CSS `margin` value of the panel element
4755 * @ko 패널 엘리먼트의 CSS `margin` 값
4756 * @type {object}
4757 * @property {number} prev CSS `margin-left` when the {@link Flicking#horizontal horizontal} is `true`, and `margin-top` else
4758 * <ko>{@link Flicking#horizontal horizontal}이 `true`일 경우 `margin-left`, `false`일 경우 `margin-top`에 해당하는 값</ko>
4759 * @property {number} next CSS `margin-right` when the {@link Flicking#horizontal horizontal} is `true`, and `margin-bottom` else
4760 * <ko>{@link Flicking#horizontal horizontal}이 `true`일 경우 `margin-right`, `false`일 경우 `margin-bottom`에 해당하는 값</ko>
4761 * @readonly
4762 */
4763 get: function () {
4764 return this._margin;
4765 },
4766 enumerable: false,
4767 configurable: true
4768 });
4769 Object.defineProperty(__proto, "alignPosition", {
4770 /**
4771 * Align position inside the panel where {@link Camera}'s {@link Camera#alignPosition alignPosition} inside viewport should be located at
4772 * @ko 패널의 정렬 기준 위치. {@link Camera}의 뷰포트 내에서의 {@link Camera#alignPosition alignPosition}이 위치해야 하는 곳입니다
4773 * @type {number}
4774 * @readonly
4775 */
4776 get: function () {
4777 return this._alignPos;
4778 },
4779 enumerable: false,
4780 configurable: true
4781 });
4782 Object.defineProperty(__proto, "removed", {
4783 /**
4784 * A value indicating whether the panel's {@link Flicking#remove remove}d
4785 * @ko 패널이 {@link Flicking#remove remove}되었는지 여부를 나타내는 값
4786 * @type {boolean}
4787 * @readonly
4788 */
4789 get: function () {
4790 return this._removed;
4791 },
4792 enumerable: false,
4793 configurable: true
4794 });
4795 Object.defineProperty(__proto, "loading", {
4796 /**
4797 * A value indicating whether the panel's image/video is not loaded and waiting for resize
4798 * @ko 패널 내부의 이미지/비디오가 아직 로드되지 않아 {@link Panel#resize resize}될 것인지를 나타내는 값
4799 * @type {boolean}
4800 * @readonly
4801 */
4802 get: function () {
4803 return this._loading;
4804 },
4805 set: function (val) {
4806 this._loading = val;
4807 },
4808 enumerable: false,
4809 configurable: true
4810 });
4811 Object.defineProperty(__proto, "range", {
4812 /**
4813 * Panel element's range of the bounding box
4814 * @ko 패널 엘리먼트의 Bounding box 범위
4815 * @type {object}
4816 * @property {number} [min] Bounding box's left({@link Flicking#horizontal horizontal}: true) / top({@link Flicking#horizontal horizontal}: false)
4817 * @property {number} [max] Bounding box's right({@link Flicking#horizontal horizontal}: true) / bottom({@link Flicking#horizontal horizontal}: false)
4818 * @readonly
4819 */
4820 get: function () {
4821 return {
4822 min: this._pos,
4823 max: this._pos + this._size
4824 };
4825 },
4826 enumerable: false,
4827 configurable: true
4828 });
4829 Object.defineProperty(__proto, "toggled", {
4830 /**
4831 * A value indicating whether the panel's position is toggled by circular behavior
4832 * @ko 패널의 위치가 circular 동작에 의해 토글되었는지 여부를 나타내는 값
4833 * @type {boolean}
4834 * @readonly
4835 */
4836 get: function () {
4837 return this._toggled;
4838 },
4839 enumerable: false,
4840 configurable: true
4841 });
4842 Object.defineProperty(__proto, "toggleDirection", {
4843 /**
4844 * A direction where the panel's position is toggled
4845 * @ko 패널의 위치가 circular 동작에 의해 토글되는 방향
4846 * @type {DIRECTION}
4847 * @readonly
4848 */
4849 get: function () {
4850 return this._toggleDirection;
4851 },
4852 enumerable: false,
4853 configurable: true
4854 });
4855 Object.defineProperty(__proto, "offset", {
4856 /**
4857 * Actual position offset determined by {@link Panel#order}
4858 * @ko {@link Panel#order}에 의한 실제 위치 변경값
4859 * @type {number}
4860 * @readonly
4861 */
4862 get: function () {
4863 var toggleDirection = this._toggleDirection;
4864 var cameraRangeDiff = this._flicking.camera.rangeDiff;
4865 return toggleDirection === DIRECTION.NONE || !this._toggled ? 0 : toggleDirection === DIRECTION.PREV ? -cameraRangeDiff : cameraRangeDiff;
4866 },
4867 enumerable: false,
4868 configurable: true
4869 });
4870 Object.defineProperty(__proto, "progress", {
4871 /**
4872 * Progress of movement between previous or next panel relative to current panel
4873 * @ko 이 패널로부터 이전/다음 패널으로의 이동 진행률
4874 * @type {number}
4875 * @readonly
4876 */
4877 get: function () {
4878 var flicking = this._flicking;
4879 return this.index - flicking.camera.progress;
4880 },
4881 enumerable: false,
4882 configurable: true
4883 });
4884 Object.defineProperty(__proto, "outsetProgress", {
4885 /**
4886 * Progress of movement between points that panel is completely invisible outside of viewport(prev direction: -1, selected point: 0, next direction: 1)
4887 * @ko 현재 패널이 뷰포트 영역 밖으로 완전히 사라지는 지점을 기준으로 하는 진행도(prev방향: -1, 선택 지점: 0, next방향: 1)
4888 * @type {number}
4889 * @readonly
4890 */
4891 get: function () {
4892 var position = this.position + this.offset;
4893 var alignPosition = this._alignPos;
4894 var camera = this._flicking.camera;
4895 var camPos = camera.position;
4896
4897 if (camPos === position) {
4898 return 0;
4899 }
4900
4901 if (camPos < position) {
4902 var disappearPosNext = position + (camera.size - camera.alignPosition) + alignPosition;
4903 return -getProgress(camPos, position, disappearPosNext);
4904 } else {
4905 var disappearPosPrev = position - (camera.alignPosition + this._size - alignPosition);
4906 return 1 - getProgress(camPos, disappearPosPrev, position);
4907 }
4908 },
4909 enumerable: false,
4910 configurable: true
4911 });
4912 Object.defineProperty(__proto, "visibleRatio", {
4913 /**
4914 * Percentage of area where panel is visible in the viewport
4915 * @ko 뷰포트 안에서 패널이 보이는 영역의 비율
4916 * @type {number}
4917 * @readonly
4918 */
4919 get: function () {
4920 var range = this.range;
4921 var size = this._size;
4922 var offset = this.offset;
4923 var visibleRange = this._flicking.camera.visibleRange;
4924 var checkingRange = {
4925 min: range.min + offset,
4926 max: range.max + offset
4927 };
4928
4929 if (checkingRange.max <= visibleRange.min || checkingRange.min >= visibleRange.max) {
4930 return 0;
4931 }
4932
4933 var visibleSize = size;
4934
4935 if (visibleRange.min > checkingRange.min) {
4936 visibleSize -= visibleRange.min - checkingRange.min;
4937 }
4938
4939 if (visibleRange.max < checkingRange.max) {
4940 visibleSize -= checkingRange.max - visibleRange.max;
4941 }
4942
4943 return visibleSize / size;
4944 },
4945 enumerable: false,
4946 configurable: true
4947 });
4948 Object.defineProperty(__proto, "align", {
4949 // Options Getter
4950
4951 /**
4952 * A value indicating where the {@link Panel#alignPosition alignPosition} should be located at inside the panel element
4953 * @ko {@link Panel#alignPosition alignPosition}이 패널 내의 어디에 위치해야 하는지를 나타내는 값
4954 * @type {Constants.ALIGN | string | number}
4955 */
4956 get: function () {
4957 return this._align;
4958 },
4959 // Options Setter
4960 set: function (val) {
4961 this._align = val;
4962 },
4963 enumerable: false,
4964 configurable: true
4965 });
4966 /**
4967 * Update size of the panel
4968 * @ko 패널의 크기를 갱신합니다
4969 * @param {object} cached Predefined cached size of the panel<ko>사전에 캐시된 패널의 크기 정보</ko>
4970 * @chainable
4971 * @return {this}
4972 */
4973
4974 __proto.resize = function (cached) {
4975 var el = this.element;
4976 var elStyle = getStyle(el);
4977 var flicking = this._flicking;
4978 var horizontal = flicking.horizontal;
4979
4980 if (cached) {
4981 this._size = cached.size;
4982 this._margin = __assign({}, cached.margin);
4983 this._height = cached.height;
4984 } else {
4985 this._size = horizontal ? el.offsetWidth : el.offsetHeight;
4986 this._margin = horizontal ? {
4987 prev: parseFloat(elStyle.marginLeft || "0"),
4988 next: parseFloat(elStyle.marginRight || "0")
4989 } : {
4990 prev: parseFloat(elStyle.marginTop || "0"),
4991 next: parseFloat(elStyle.marginBottom || "0")
4992 };
4993 this._height = horizontal ? el.offsetHeight : this._size;
4994 }
4995
4996 this.updatePosition();
4997
4998 this._updateAlignPos();
4999
5000 return this;
5001 };
5002 /**
5003 * Change panel's size. This will change the actual size of the panel element by changing its CSS width/height property
5004 * @ko 패널 크기를 변경합니다. 패널 엘리먼트에 해당 크기의 CSS width/height를 적용합니다
5005 * @param {object} [size] New panel size<ko>새 패널 크기</ko>
5006 * @param {number|string} [size.width] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>
5007 * @param {number|string} [size.height] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>
5008 * @chainable
5009 * @return {this}
5010 */
5011
5012
5013 __proto.setSize = function (_a) {
5014 var width = _a.width,
5015 height = _a.height;
5016 var el = this.element;
5017
5018 if (width != null) {
5019 if (isString(width)) {
5020 el.style.width = width;
5021 } else {
5022 el.style.width = width + "px";
5023 }
5024 }
5025
5026 if (height != null) {
5027 if (isString(height)) {
5028 el.style.height = height;
5029 } else {
5030 el.style.height = height + "px";
5031 }
5032 }
5033
5034 return this;
5035 };
5036 /**
5037 * Check whether the given element is inside of this panel's {@link Panel#element element}
5038 * @ko 해당 엘리먼트가 이 패널의 {@link Panel#element element} 내에 포함되어 있는지를 반환합니다
5039 * @param {HTMLElement} element The HTMLElement to check<ko>확인하고자 하는 HTMLElement</ko>
5040 * @return {boolean} A Boolean value indicating the element is inside of this panel {@link Panel#element element}<ko>패널의 {@link Panel#element element}내에 해당 엘리먼트 포함 여부</ko>
5041 */
5042
5043
5044 __proto.contains = function (element) {
5045 var _a;
5046
5047 return !!((_a = this.element) === null || _a === void 0 ? void 0 : _a.contains(element));
5048 };
5049 /**
5050 * Reset internal state and set {@link Panel#removed removed} to `true`
5051 * @ko 내부 상태를 초기화하고 {@link Panel#removed removed}를 `true`로 설정합니다.
5052 * @return {void}
5053 */
5054
5055
5056 __proto.destroy = function () {
5057 this._resetInternalStates();
5058
5059 this._removed = true;
5060 };
5061 /**
5062 * Check whether the given position is inside of this panel's {@link Panel#range range}
5063 * @ko 주어진 좌표가 현재 패널의 {@link Panel#range range}내에 속해있는지를 반환합니다.
5064 * @param {number} pos A position to check<ko>확인하고자 하는 좌표</ko>
5065 * @param {boolean} [includeMargin=false] Include {@link Panel#margin margin} to the range<ko>패널 영역에 {@link Panel#margin margin}값을 포함시킵니다</ko>
5066 * @return {boolean} A Boolean value indicating whether the given position is included in the panel range<ko>해당 좌표가 패널 영역 내에 속해있는지 여부</ko>
5067 */
5068
5069
5070 __proto.includePosition = function (pos, includeMargin) {
5071 if (includeMargin === void 0) {
5072 includeMargin = false;
5073 }
5074
5075 return this.includeRange(pos, pos, includeMargin);
5076 };
5077 /**
5078 * Check whether the given range is fully included in this panel's area
5079 * @ko 주어진 범위가 이 패널 내부에 완전히 포함되는지를 반환합니다
5080 * @param {number} min Minimum value of the range to check<ko>확인하고자 하는 최소 범위</ko>
5081 * @param {number} max Maximum value of the range to check<ko>확인하고자 하는 최대 범위</ko>
5082 * @param {boolean} [includeMargin=false] Include {@link Panel#margin margin} to the range<ko>패널 영역에 {@link Panel#margin margin}값을 포함시킵니다</ko>
5083 * @returns {boolean} A Boolean value indicating whether the given range is fully included in the panel range<ko>해당 범위가 패널 영역 내에 완전히 속해있는지 여부</ko>
5084 */
5085
5086
5087 __proto.includeRange = function (min, max, includeMargin) {
5088 if (includeMargin === void 0) {
5089 includeMargin = false;
5090 }
5091
5092 var margin = this._margin;
5093 var panelRange = this.range;
5094
5095 if (includeMargin) {
5096 panelRange.min -= margin.prev;
5097 panelRange.max += margin.next;
5098 }
5099
5100 return max >= panelRange.min && min <= panelRange.max;
5101 };
5102 /**
5103 * Move {@link Camera} to this panel
5104 * @ko {@link Camera}를 이 패널로 이동합니다
5105 * @param {number} [duration] Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>
5106 * @returns {Promise<void>} A Promise which will be resolved after reaching the panel<ko>패널 도달시에 resolve되는 Promise</ko>
5107 */
5108
5109
5110 __proto.focus = function (duration) {
5111 return this._flicking.moveTo(this._index, duration);
5112 };
5113 /**
5114 * Get previous(`index - 1`) panel. When the previous panel does not exist, this will return `null` instead
5115 * If the {@link Flicking#circularEnabled circular} is enabled, this will return the last panel if called from the first panel
5116 * @ko 이전(`index - 1`) 패널을 반환합니다. 이전 패널이 없을 경우 `null`을 반환합니다
5117 * {@link Flicking#circularEnabled circular} 모드가 활성화되었을 때 첫번째 패널에서 이 메소드를 호출할 경우 마지막 패널을 반환합니다
5118 * @returns {Panel | null} The previous panel<ko>이전 패널</ko>
5119 */
5120
5121
5122 __proto.prev = function () {
5123 var index = this._index;
5124 var flicking = this._flicking;
5125 var renderer = flicking.renderer;
5126 var panelCount = renderer.panelCount;
5127 if (panelCount === 1) return null;
5128 return flicking.circularEnabled ? renderer.getPanel(index === 0 ? panelCount - 1 : index - 1) : renderer.getPanel(index - 1);
5129 };
5130 /**
5131 * Get next(`index + 1`) panel. When the next panel does not exist, this will return `null` instead
5132 * If the {@link Flicking#circularEnabled circular} is enabled, this will return the first panel if called from the last panel
5133 * @ko 다음(`index + 1`) 패널을 반환합니다. 다음 패널이 없을 경우 `null`을 반환합니다
5134 * {@link Flicking#circularEnabled circular} 모드가 활성화되었을 때 마지막 패널에서 이 메소드를 호출할 경우 첫번째 패널을 반환합니다
5135 * @returns {Panel | null} The previous panel<ko>다음 패널</ko>
5136 */
5137
5138
5139 __proto.next = function () {
5140 var index = this._index;
5141 var flicking = this._flicking;
5142 var renderer = flicking.renderer;
5143 var panelCount = renderer.panelCount;
5144 if (panelCount === 1) return null;
5145 return flicking.circularEnabled ? renderer.getPanel(index === panelCount - 1 ? 0 : index + 1) : renderer.getPanel(index + 1);
5146 };
5147 /**
5148 * Increase panel's index by the given value
5149 * @ko 패널의 인덱스를 주어진 값만큼 증가시킵니다
5150 * @internal
5151 * @chainable
5152 * @param val An integer greater than or equal to 0<ko>0보다 같거나 큰 정수</ko>
5153 * @returns {this}
5154 */
5155
5156
5157 __proto.increaseIndex = function (val) {
5158 this._index += Math.max(val, 0);
5159 return this;
5160 };
5161 /**
5162 * Decrease panel's index by the given value
5163 * @ko 패널의 인덱스를 주어진 값만큼 감소시킵니다
5164 * @internal
5165 * @chainable
5166 * @param val An integer greater than or equal to 0<ko>0보다 같거나 큰 정수</ko>
5167 * @returns {this}
5168 */
5169
5170
5171 __proto.decreaseIndex = function (val) {
5172 this._index -= Math.max(val, 0);
5173 return this;
5174 };
5175 /**
5176 * @internal
5177 */
5178
5179
5180 __proto.updatePosition = function () {
5181 var prevPanel = this._flicking.renderer.panels[this._index - 1];
5182 this._pos = prevPanel ? prevPanel.range.max + prevPanel.margin.next + this._margin.prev : this._margin.prev;
5183 return this;
5184 };
5185 /**
5186 * @internal
5187 * @return {boolean} toggled
5188 */
5189
5190
5191 __proto.toggle = function (prevPos, newPos) {
5192 var toggleDirection = this._toggleDirection;
5193 var togglePosition = this._togglePosition;
5194 if (toggleDirection === DIRECTION.NONE || newPos === prevPos) return false;
5195 var prevToggled = this._toggled;
5196
5197 if (newPos > prevPos) {
5198 if (togglePosition >= prevPos && togglePosition <= newPos) {
5199 this._toggled = toggleDirection === DIRECTION.NEXT;
5200 }
5201 } else {
5202 if (togglePosition <= prevPos && togglePosition >= newPos) {
5203 this._toggled = toggleDirection !== DIRECTION.NEXT;
5204 }
5205 }
5206
5207 return prevToggled !== this._toggled;
5208 };
5209 /**
5210 * @internal
5211 */
5212
5213
5214 __proto.updateCircularToggleDirection = function () {
5215 var flicking = this._flicking;
5216
5217 if (!flicking.circularEnabled) {
5218 this._toggleDirection = DIRECTION.NONE;
5219 this._toggled = false;
5220 return this;
5221 }
5222
5223 var camera = flicking.camera;
5224 var camRange = camera.range;
5225 var camAlignPosition = camera.alignPosition;
5226 var camVisibleRange = camera.visibleRange;
5227 var camVisibleSize = camVisibleRange.max - camVisibleRange.min;
5228 var minimumVisible = camRange.min - camAlignPosition;
5229 var maximumVisible = camRange.max - camAlignPosition + camVisibleSize;
5230 var shouldBeVisibleAtMin = this.includeRange(maximumVisible - camVisibleSize, maximumVisible, false);
5231 var shouldBeVisibleAtMax = this.includeRange(minimumVisible, minimumVisible + camVisibleSize, false);
5232 this._toggled = false;
5233
5234 if (shouldBeVisibleAtMin) {
5235 this._toggleDirection = DIRECTION.PREV;
5236 this._togglePosition = this.range.max + camRange.min - camRange.max + camAlignPosition;
5237 this.toggle(Infinity, camera.position);
5238 } else if (shouldBeVisibleAtMax) {
5239 this._toggleDirection = DIRECTION.NEXT;
5240 this._togglePosition = this.range.min + camRange.max - camVisibleSize + camAlignPosition;
5241 this.toggle(-Infinity, camera.position);
5242 } else {
5243 this._toggleDirection = DIRECTION.NONE;
5244 this._togglePosition = 0;
5245 }
5246
5247 return this;
5248 };
5249
5250 __proto._updateAlignPos = function () {
5251 this._alignPos = parseAlign$1(this._align, this._size);
5252 };
5253
5254 __proto._resetInternalStates = function () {
5255 this._size = 0;
5256 this._pos = 0;
5257 this._margin = {
5258 prev: 0,
5259 next: 0
5260 };
5261 this._height = 0;
5262 this._alignPos = 0;
5263 this._toggled = false;
5264 this._togglePosition = 0;
5265 this._toggleDirection = DIRECTION.NONE;
5266 };
5267
5268 return Panel;
5269}();
5270
5271/**
5272 * An slide data component that holds information of a single HTMLElement
5273 * @ko 슬라이드 데이터 컴포넌트로, 단일 HTMLElement의 정보를 갖고 있습니다
5274 */
5275
5276var ElementPanel = function (_super) {
5277 __extends(ElementPanel, _super);
5278 /**
5279 * @param {object} options An options object<ko>옵션 오브젝트</ko>
5280 * @param {HTMLElement} [options.el] A `HTMLElement` panel's referencing<ko>패널이 참조하는 `HTMLElement`</ko>
5281 * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>
5282 * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>
5283 * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>
5284 */
5285
5286
5287 function ElementPanel(options) {
5288 var _this = _super.call(this, options) || this;
5289
5290 _this._el = options.el;
5291 _this._rendered = true;
5292 return _this;
5293 }
5294
5295 var __proto = ElementPanel.prototype;
5296 Object.defineProperty(__proto, "element", {
5297 /**
5298 * `HTMLElement` that panel's referencing
5299 * @ko 패널이 참조하고 있는 `HTMLElement`
5300 * @type {HTMLElement}
5301 * @readonly
5302 */
5303 get: function () {
5304 return this._el;
5305 },
5306 enumerable: false,
5307 configurable: true
5308 });
5309 Object.defineProperty(__proto, "rendered", {
5310 get: function () {
5311 return this._rendered;
5312 },
5313 enumerable: false,
5314 configurable: true
5315 });
5316
5317 __proto.markForShow = function () {
5318 this._rendered = true;
5319 };
5320
5321 __proto.markForHide = function () {
5322 this._rendered = false;
5323 };
5324
5325 return ElementPanel;
5326}(Panel);
5327
5328/**
5329 *
5330 */
5331
5332var VanillaRenderer = function (_super) {
5333 __extends(VanillaRenderer, _super);
5334
5335 function VanillaRenderer() {
5336 return _super !== null && _super.apply(this, arguments) || this;
5337 } // eslint-disable-next-line @typescript-eslint/require-await
5338
5339
5340 var __proto = VanillaRenderer.prototype;
5341
5342 __proto.render = function () {
5343 return __awaiter(this, void 0, void 0, function () {
5344 var flicking, cameraEl, wasRenderedPanels, renderingPanels;
5345 return __generator(this, function (_a) {
5346 flicking = getFlickingAttached(this._flicking, "Renderer");
5347 cameraEl = flicking.camera.element;
5348 wasRenderedPanels = this._panels.filter(function (panel) {
5349 return panel.element.parentElement === cameraEl;
5350 });
5351
5352 this._updateRenderingPanels();
5353
5354 renderingPanels = this._getRenderingPanelsByOrder();
5355
5356 this._removePanelElements(wasRenderedPanels.filter(function (panel) {
5357 return !panel.rendered;
5358 }));
5359
5360 this._insertPanelElements(renderingPanels.filter(function (panel) {
5361 return panel.element.parentElement !== cameraEl;
5362 }), null);
5363
5364 this._resetPanelElementOrder(renderingPanels);
5365
5366 return [2
5367 /*return*/
5368 ];
5369 });
5370 });
5371 }; // eslint-disable-next-line @typescript-eslint/require-await
5372
5373
5374 __proto.forceRenderAllPanels = function () {
5375 return __awaiter(this, void 0, void 0, function () {
5376 var flicking, camera, cameraElement, fragment;
5377 return __generator(this, function (_a) {
5378 flicking = getFlickingAttached(this._flicking, "Renderer");
5379 camera = flicking.camera;
5380 cameraElement = camera.element;
5381 fragment = document.createDocumentFragment();
5382
5383 this._panels.forEach(function (panel) {
5384 return fragment.appendChild(panel.element);
5385 });
5386
5387 this._removeAllChildsFromCamera();
5388
5389 cameraElement.appendChild(fragment);
5390 return [2
5391 /*return*/
5392 ];
5393 });
5394 });
5395 };
5396
5397 __proto._collectPanels = function () {
5398 var flicking = getFlickingAttached(this._flicking, "Renderer");
5399 var cameraElement = flicking.camera.element; // Remove all text nodes in the camera element
5400
5401 toArray(cameraElement.childNodes).forEach(function (node) {
5402 if (node.nodeType === Node.TEXT_NODE) {
5403 cameraElement.removeChild(node);
5404 }
5405 });
5406
5407 var align = this._getPanelAlign();
5408
5409 var cameraChilds = toArray(cameraElement.children);
5410 this._panels = cameraChilds.map(function (el, index) {
5411 return new ElementPanel({
5412 flicking: flicking,
5413 el: el,
5414 index: index,
5415 align: align
5416 });
5417 });
5418 };
5419
5420 __proto._createPanel = function (el, options) {
5421 return new ElementPanel(__assign({
5422 el: el
5423 }, options));
5424 };
5425
5426 __proto._insertPanelElements = function (panels, nextSibling) {
5427 var flicking = getFlickingAttached(this._flicking, "Renderer");
5428 var camera = flicking.camera;
5429 var cameraElement = camera.element;
5430 var nextSiblingElement = (nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.element) || null;
5431 var fragment = document.createDocumentFragment();
5432 panels.forEach(function (panel) {
5433 return fragment.appendChild(panel.element);
5434 });
5435 cameraElement.insertBefore(fragment, nextSiblingElement);
5436 return this;
5437 };
5438
5439 __proto._removePanelElements = function (panels) {
5440 var flicking = getFlickingAttached(this._flicking, "Renderer");
5441 var cameraElement = flicking.camera.element;
5442 panels.forEach(function (panel) {
5443 cameraElement.removeChild(panel.element);
5444 });
5445 return this;
5446 };
5447
5448 __proto._resetPanelElementOrder = function (panels) {
5449 var flicking = getFlickingAttached(this._flicking, "Renderer");
5450 var cameraEl = flicking.camera.element; // We're using reversed panels here as last panel should be the last element of camera element
5451
5452 var reversedPanels = __spreadArray([], __read(panels)).reverse();
5453
5454 reversedPanels.forEach(function (panel, idx) {
5455 var nextPanel = reversedPanels[idx - 1];
5456 var nextPanelEl = nextPanel ? nextPanel.element : null;
5457
5458 if (panel.element.nextElementSibling !== nextPanelEl) {
5459 cameraEl.insertBefore(panel.element, nextPanelEl);
5460 }
5461 });
5462 };
5463
5464 __proto._removeAllChildsFromCamera = function () {
5465 var flicking = getFlickingAttached(this._flicking, "Renderer");
5466 var cameraElement = flicking.camera.element; // Remove other elements
5467
5468 while (cameraElement.firstChild) {
5469 cameraElement.removeChild(cameraElement.firstChild);
5470 }
5471 };
5472
5473 __proto._getRenderingPanelsByOrder = function () {
5474 var flicking = getFlickingAttached(this._flicking, "Renderer");
5475 var panels = flicking.renderer.panels;
5476 return panels.filter(function (panel) {
5477 return panel.rendered;
5478 }).sort(function (a, b) {
5479 return a.position + a.offset - (b.position + b.offset);
5480 });
5481 };
5482
5483 return VanillaRenderer;
5484}(Renderer);
5485
5486/**
5487 *
5488 */
5489
5490var ExternalRenderer = function (_super) {
5491 __extends(ExternalRenderer, _super);
5492
5493 function ExternalRenderer() {
5494 return _super !== null && _super.apply(this, arguments) || this;
5495 } // eslint-disable-next-line @typescript-eslint/no-unused-vars
5496
5497
5498 var __proto = ExternalRenderer.prototype;
5499
5500 __proto._insertPanelElements = function (panels, nextSibling) {// DO NOTHING
5501 }; // eslint-disable-next-line @typescript-eslint/no-unused-vars
5502
5503
5504 __proto._removePanelElements = function (panels) {// DO NOTHING
5505 };
5506
5507 return ExternalRenderer;
5508}(Renderer);
5509
5510/**
5511 * @extends Component
5512 * @support {"ie": "9+(with polyfill)", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "4.X+"}
5513 * @requires {@link https://github.com/naver/egjs-component|@egjs/component}
5514 * @requires {@link https://github.com/naver/egjs-axes|@egjs/axes}
5515 */
5516
5517var Flicking = function (_super) {
5518 __extends(Flicking, _super);
5519 /**
5520 * @param root A root HTMLElement to initialize Flicking on it. When it's a typeof `string`, it should be a css selector string
5521 * <ko>Flicking을 초기화할 HTMLElement로, `string` 타입으로 지정시 css 선택자 문자열을 지정해야 합니다.</ko>
5522 * @param {object} [options={}] An options object for Flicking.<ko>Flicking에 적용할 옵션 오브젝트</ko>
5523 * @throws {FlickingError}
5524 * |code|condition|
5525 * |---|---|
5526 * |{@link ERROR_CODE WRONG_TYPE}|When the root is not either string or HTMLElement|
5527 * |{@link ERROR_CODE ELEMENT_NOT_FOUND}|When the element with given CSS selector does not exist|
5528 * <ko>
5529 *
5530 * |code|조건|
5531 * |---|---|
5532 * |{@link ERROR_CODE WRONG_TYPE}|루트 엘리먼트가 string이나 HTMLElement가 아닐 경우|
5533 * |{@link ERROR_CODE ELEMENT_NOT_FOUND}|주어진 CSS selector로 엘리먼트를 찾지 못했을 경우|
5534 *
5535 * </ko>
5536 * @example
5537 * ```ts
5538 * import Flicking from "@egjs/flicking";
5539 *
5540 * // Creating new instance of Flicking with HTMLElement
5541 * const flicking = new Flicking(document.querySelector(".flicking-viewport"), { circular: true });
5542 *
5543 * // Creating new instance of Flicking with CSS selector
5544 * const flicking2 = new Flicking(".flicking-viewport", { circular: true });
5545 * ```
5546 */
5547
5548
5549 function Flicking(root, _a) {
5550 var _b = _a === void 0 ? {} : _a,
5551 _c = _b.align,
5552 align = _c === void 0 ? ALIGN.CENTER : _c,
5553 _d = _b.defaultIndex,
5554 defaultIndex = _d === void 0 ? 0 : _d,
5555 _e = _b.horizontal,
5556 horizontal = _e === void 0 ? true : _e,
5557 _f = _b.circular,
5558 circular = _f === void 0 ? false : _f,
5559 _g = _b.bound,
5560 bound = _g === void 0 ? false : _g,
5561 _h = _b.adaptive,
5562 adaptive = _h === void 0 ? false : _h,
5563 _j = _b.panelsPerView,
5564 panelsPerView = _j === void 0 ? -1 : _j,
5565 _k = _b.noPanelStyleOverride,
5566 noPanelStyleOverride = _k === void 0 ? false : _k,
5567 _l = _b.resizeOnContentsReady,
5568 resizeOnContentsReady = _l === void 0 ? false : _l,
5569 _m = _b.needPanelThreshold,
5570 needPanelThreshold = _m === void 0 ? 0 : _m,
5571 _o = _b.preventEventsBeforeInit,
5572 preventEventsBeforeInit = _o === void 0 ? true : _o,
5573 _p = _b.deceleration,
5574 deceleration = _p === void 0 ? 0.0075 : _p,
5575 _q = _b.duration,
5576 duration = _q === void 0 ? 500 : _q,
5577 _r = _b.easing,
5578 easing = _r === void 0 ? function (x) {
5579 return 1 - Math.pow(1 - x, 3);
5580 } : _r,
5581 _s = _b.inputType,
5582 inputType = _s === void 0 ? ["mouse", "touch"] : _s,
5583 _t = _b.moveType,
5584 moveType = _t === void 0 ? "snap" : _t,
5585 _u = _b.threshold,
5586 threshold = _u === void 0 ? 40 : _u,
5587 _v = _b.interruptable,
5588 interruptable = _v === void 0 ? true : _v,
5589 _w = _b.bounce,
5590 bounce = _w === void 0 ? "20%" : _w,
5591 _x = _b.iOSEdgeSwipeThreshold,
5592 iOSEdgeSwipeThreshold = _x === void 0 ? 30 : _x,
5593 _y = _b.preventClickOnDrag,
5594 preventClickOnDrag = _y === void 0 ? true : _y,
5595 _z = _b.disableOnInit,
5596 disableOnInit = _z === void 0 ? false : _z,
5597 _0 = _b.renderOnlyVisible,
5598 renderOnlyVisible = _0 === void 0 ? false : _0,
5599 _1 = _b.autoInit,
5600 autoInit = _1 === void 0 ? true : _1,
5601 _2 = _b.autoResize,
5602 autoResize = _2 === void 0 ? true : _2,
5603 _3 = _b.renderExternal,
5604 renderExternal = _3 === void 0 ? null : _3;
5605
5606 var _this = _super.call(this) || this; // Internal states
5607
5608
5609 _this._initialized = false;
5610 _this._plugins = []; // Bind options
5611
5612 _this._align = align;
5613 _this._defaultIndex = defaultIndex;
5614 _this._horizontal = horizontal;
5615 _this._circular = circular;
5616 _this._bound = bound;
5617 _this._adaptive = adaptive;
5618 _this._panelsPerView = panelsPerView;
5619 _this._noPanelStyleOverride = noPanelStyleOverride;
5620 _this._resizeOnContentsReady = resizeOnContentsReady;
5621 _this._needPanelThreshold = needPanelThreshold;
5622 _this._preventEventsBeforeInit = preventEventsBeforeInit;
5623 _this._deceleration = deceleration;
5624 _this._duration = duration;
5625 _this._easing = easing;
5626 _this._inputType = inputType;
5627 _this._moveType = moveType;
5628 _this._threshold = threshold;
5629 _this._interruptable = interruptable;
5630 _this._bounce = bounce;
5631 _this._iOSEdgeSwipeThreshold = iOSEdgeSwipeThreshold;
5632 _this._preventClickOnDrag = preventClickOnDrag;
5633 _this._disableOnInit = disableOnInit;
5634 _this._renderOnlyVisible = renderOnlyVisible;
5635 _this._autoResize = autoResize;
5636 _this._autoInit = autoInit;
5637 _this._renderExternal = renderExternal; // Create core components
5638
5639 _this._viewport = new Viewport(getElement(root));
5640 _this._renderer = _this._createRenderer();
5641 _this._camera = _this._createCamera();
5642 _this._control = _this._createControl();
5643 _this.resize = _this.resize.bind(_this);
5644
5645 if (_this._autoInit) {
5646 void _this.init();
5647 }
5648
5649 return _this;
5650 }
5651
5652 var __proto = Flicking.prototype;
5653 Object.defineProperty(__proto, "control", {
5654 // Components
5655
5656 /**
5657 * {@link Control} instance of the Flicking
5658 * @ko 현재 Flicking에 활성화된 {@link Control} 인스턴스
5659 * @type {Control}
5660 * @default SnapControl
5661 * @readonly
5662 * @see Control
5663 * @see SnapControl
5664 * @see FreeControl
5665 */
5666 get: function () {
5667 return this._control;
5668 },
5669 enumerable: false,
5670 configurable: true
5671 });
5672 Object.defineProperty(__proto, "camera", {
5673 /**
5674 * {@link Camera} instance of the Flicking
5675 * @ko 현재 Flicking에 활성화된 {@link Camera} 인스턴스
5676 * @type {Camera}
5677 * @default LinearCamera
5678 * @readonly
5679 * @see Camera
5680 * @see LinearCamera
5681 * @see BoundCamera
5682 * @see CircularCamera
5683 */
5684 get: function () {
5685 return this._camera;
5686 },
5687 enumerable: false,
5688 configurable: true
5689 });
5690 Object.defineProperty(__proto, "renderer", {
5691 /**
5692 * {@link Renderer} instance of the Flicking
5693 * @ko 현재 Flicking에 활성화된 {@link Renderer} 인스턴스
5694 * @type {Renderer}
5695 * @default VanillaRenderer
5696 * @readonly
5697 * @see Renderer
5698 * @see VanillaRenderer
5699 * @see ExternalRenderer
5700 */
5701 get: function () {
5702 return this._renderer;
5703 },
5704 enumerable: false,
5705 configurable: true
5706 });
5707 Object.defineProperty(__proto, "viewport", {
5708 /**
5709 * A component that manages viewport size
5710 * @ko 뷰포트 크기 정보를 담당하는 컴포넌트
5711 * @type {Viewport}
5712 * @readonly
5713 * @see Viewport
5714 */
5715 get: function () {
5716 return this._viewport;
5717 },
5718 enumerable: false,
5719 configurable: true
5720 });
5721 Object.defineProperty(__proto, "initialized", {
5722 // Internal States
5723
5724 /**
5725 * Whether Flicking's {@link Flicking#init init()} is called.
5726 * This is `true` when {@link Flicking#init init()} is called, and is `false` after calling {@link Flicking#destroy destroy()}.
5727 * @ko Flicking의 {@link Flicking#init init()}이 호출되었는지를 나타내는 멤버 변수.
5728 * 이 값은 {@link Flicking#init init()}이 호출되었으면 `true`로 변하고, {@link Flicking#destroy destroy()}호출 이후에 다시 `false`로 변경됩니다.
5729 * @type {boolean}
5730 * @default false
5731 * @readonly
5732 */
5733 get: function () {
5734 return this._initialized;
5735 },
5736 enumerable: false,
5737 configurable: true
5738 });
5739 Object.defineProperty(__proto, "circularEnabled", {
5740 /**
5741 * Whether the `circular` option is enabled.
5742 * The {@link Flicking#circular circular} option can't be enabled when sum of the panel sizes are too small.
5743 * @ko {@link Flicking#circular circular} 옵션이 활성화되었는지 여부를 나타내는 멤버 변수.
5744 * {@link Flicking#circular circular} 옵션은 패널의 크기의 합이 충분하지 않을 경우 비활성화됩니다.
5745 * @type {boolean}
5746 * @default false
5747 * @readonly
5748 */
5749 get: function () {
5750 return this._camera.controlParams.circular;
5751 },
5752 enumerable: false,
5753 configurable: true
5754 });
5755 Object.defineProperty(__proto, "index", {
5756 /**
5757 * Index number of the {@link Flicking#currentPanel currentPanel}
5758 * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호
5759 * @type {number}
5760 * @default 0
5761 * @readonly
5762 */
5763 get: function () {
5764 return this._control.activeIndex;
5765 },
5766 enumerable: false,
5767 configurable: true
5768 });
5769 Object.defineProperty(__proto, "element", {
5770 /**
5771 * The root(`.flicking-viewport`) element
5772 * @ko root(`.flicking-viewport`) 엘리먼트
5773 * @type {HTMLElement}
5774 * @readonly
5775 */
5776 get: function () {
5777 return this._viewport.element;
5778 },
5779 enumerable: false,
5780 configurable: true
5781 });
5782 Object.defineProperty(__proto, "currentPanel", {
5783 /**
5784 * Currently active panel
5785 * @ko 현재 선택된 패널
5786 * @type {Panel}
5787 * @readonly
5788 * @see Panel
5789 */
5790 get: function () {
5791 return this._control.activePanel;
5792 },
5793 enumerable: false,
5794 configurable: true
5795 });
5796 Object.defineProperty(__proto, "panels", {
5797 /**
5798 * Array of panels
5799 * @ko 전체 패널들의 배열
5800 * @type {Panel[]}
5801 * @readonly
5802 * @see Panel
5803 */
5804 get: function () {
5805 return this._renderer.panels;
5806 },
5807 enumerable: false,
5808 configurable: true
5809 });
5810 Object.defineProperty(__proto, "panelCount", {
5811 /**
5812 * Count of panels
5813 * @ko 전체 패널의 개수
5814 * @type {number}
5815 * @readonly
5816 */
5817 get: function () {
5818 return this._renderer.panelCount;
5819 },
5820 enumerable: false,
5821 configurable: true
5822 });
5823 Object.defineProperty(__proto, "visiblePanels", {
5824 /**
5825 * Array of panels that is visible at the current position
5826 * @ko 현재 보이는 패널의 배열
5827 * @type {Panel[]}
5828 * @readonly
5829 * @see Panel
5830 */
5831 get: function () {
5832 return this._camera.visiblePanels;
5833 },
5834 enumerable: false,
5835 configurable: true
5836 });
5837 Object.defineProperty(__proto, "animating", {
5838 /**
5839 * Whether Flicking's animating
5840 * @ko 현재 애니메이션 동작 여부
5841 * @type {boolean}
5842 * @readonly
5843 */
5844 get: function () {
5845 return this._control.animating;
5846 },
5847 enumerable: false,
5848 configurable: true
5849 });
5850 Object.defineProperty(__proto, "holding", {
5851 /**
5852 * Whether user is clicking or touching
5853 * @ko 현재 사용자가 클릭/터치중인지 여부
5854 * @type {boolean}
5855 * @readonly
5856 */
5857 get: function () {
5858 return this._control.holding;
5859 },
5860 enumerable: false,
5861 configurable: true
5862 });
5863 Object.defineProperty(__proto, "activePlugins", {
5864 /**
5865 * A current list of activated plugins
5866 * @ko 현재 활성화된 플러그인 목록
5867 * @type {Plugin[]}
5868 * @readonly
5869 */
5870 get: function () {
5871 return this._plugins;
5872 },
5873 enumerable: false,
5874 configurable: true
5875 });
5876 Object.defineProperty(__proto, "align", {
5877 // Options Getter
5878 // UI / LAYOUT
5879
5880 /**
5881 * Align position of the panels within viewport. You can set different values each for the panel and camera
5882 * @ko 뷰포트 내에서 패널 정렬방식을 설정하는 옵션. 카메라와 패널 개별로 옵션을 설정할 수도 있습니다
5883 * @type {ALIGN | string | number | { panel: string | number, camera: string | number }}
5884 * @property {ALIGN | string | number} panel The align value for each {@link Panel}s<ko>개개의 {@link Panel}에 적용할 값</ko>
5885 * @property {ALIGN | string | number} camera The align value for {@link Camera}<ko>{@link Camera}에 적용할 값</ko>
5886 * @default "center"
5887 * @example
5888 * ```ts
5889 * const possibleOptions = [
5890 * // Literal strings
5891 * "prev", "center", "next",
5892 * // % values, applied to both panel & camera
5893 * "0%", "25%", "42%",
5894 * // px values, arithmetic calculation with (+/-) is also allowed.
5895 * "0px", "100px", "50% - 25px",
5896 * // numbers, same to number + px ("0px", "100px")
5897 * 0, 100, 1000,
5898 * // Setting a different value for panel & camera
5899 * { panel: "10%", camera: "25%" }
5900 * ];
5901 *
5902 * possibleOptions.forEach(align => {
5903 * new Flicking("#el", { align });
5904 * });
5905 * ```
5906 */
5907 get: function () {
5908 return this._align;
5909 },
5910 // Options Setter
5911 // UI / LAYOUT
5912 set: function (val) {
5913 this._align = val;
5914 this._renderer.align = val;
5915 this._camera.align = val;
5916 },
5917 enumerable: false,
5918 configurable: true
5919 });
5920 Object.defineProperty(__proto, "defaultIndex", {
5921 /**
5922 * Index of the panel to move when Flicking's {@link Flicking#init init()} is called. A zero-based integer
5923 * @ko Flicking의 {@link Flicking#init init()}이 호출될 때 이동할 디폴트 패널의 인덱스로, 0부터 시작하는 정수입니다
5924 * @type {number}
5925 * @default 0
5926 */
5927 get: function () {
5928 return this._defaultIndex;
5929 },
5930 set: function (val) {
5931 this._defaultIndex = val;
5932 },
5933 enumerable: false,
5934 configurable: true
5935 });
5936 Object.defineProperty(__proto, "horizontal", {
5937 /**
5938 * Direction of panel movement (true: horizontal, false: vertical)
5939 * @ko 패널 이동 방향 (true: 가로방향, false: 세로방향)
5940 * @type {boolean}
5941 * @default true
5942 */
5943 get: function () {
5944 return this._horizontal;
5945 },
5946 set: function (val) {
5947 this._horizontal = val;
5948 },
5949 enumerable: false,
5950 configurable: true
5951 });
5952 Object.defineProperty(__proto, "circular", {
5953 /**
5954 * Enables circular(continuous loop) mode, which connects first/last panel for continuous scrolling.
5955 * @ko 순환 모드를 활성화합니다. 순환 모드에서는 양 끝의 패널이 서로 연결되어 끊김없는 스크롤이 가능합니다.
5956 * @type {boolean}
5957 * @default false
5958 */
5959 get: function () {
5960 return this._circular;
5961 },
5962 set: function (val) {
5963 this._circular = val;
5964 },
5965 enumerable: false,
5966 configurable: true
5967 });
5968 Object.defineProperty(__proto, "bound", {
5969 /**
5970 * Prevent the view(camera element) from going out of the first/last panel, so it won't show empty spaces before/after the first/last panel
5971 * Only can be enabled when `circular=false`
5972 * @ko 뷰(카메라 엘리먼트)가 첫번째와 마지막 패널 밖으로 넘어가지 못하게 하여, 첫번째/마지막 패널 전/후의 빈 공간을 보이지 않도록 하는 옵션입니다
5973 * `circular=false`인 경우에만 사용할 수 있습니다
5974 * @type {boolean}
5975 * @default false
5976 */
5977 get: function () {
5978 return this._bound;
5979 },
5980 set: function (val) {
5981 this._bound = val;
5982 },
5983 enumerable: false,
5984 configurable: true
5985 });
5986 Object.defineProperty(__proto, "adaptive", {
5987 /**
5988 * Update height of the viewport element after movement same to the height of the panel below. This can be only enabled when `horizontal=true`
5989 * @ko 이동한 후 뷰포트 엘리먼트의 크기를 현재 패널의 높이와 동일하게 설정합니다. `horizontal=true`인 경우에만 사용할 수 있습니다.
5990 * @type {boolean}
5991 * @default false
5992 */
5993 get: function () {
5994 return this._adaptive;
5995 },
5996 set: function (val) {
5997 this._adaptive = val;
5998 },
5999 enumerable: false,
6000 configurable: true
6001 });
6002 Object.defineProperty(__proto, "panelsPerView", {
6003 /**
6004 * A visible number of panels on viewport. Enabling this option will automatically resize panel size
6005 * @ko 한 화면에 보이는 패널의 개수. 이 옵션을 활성화할 경우 패널의 크기를 강제로 재조정합니다
6006 * @type {number}
6007 * @default -1
6008 */
6009 get: function () {
6010 return this._panelsPerView;
6011 },
6012 set: function (val) {
6013 this._panelsPerView = val;
6014 },
6015 enumerable: false,
6016 configurable: true
6017 });
6018 Object.defineProperty(__proto, "noPanelStyleOverride", {
6019 /**
6020 * Enabling this option will not change `width/height` style of the panels if {@link Flicking#panelsPerView} is enabled.
6021 * This behavior can be useful in terms of performance when you're manually managing all panel sizes
6022 * @ko 이 옵션을 활성화할 경우, {@link Flicking#panelsPerView} 옵션이 활성화되었을 때 패널의 `width/height` 스타일을 변경하지 않도록 설정합니다.
6023 * 모든 패널들의 크기를 직접 관리하고 있을 경우, 이 옵션을 활성화하면 성능면에서 유리할 수 있습니다
6024 * @type {boolean}
6025 * @default false
6026 */
6027 get: function () {
6028 return this._noPanelStyleOverride;
6029 },
6030 set: function (val) {
6031 this._noPanelStyleOverride = val;
6032 },
6033 enumerable: false,
6034 configurable: true
6035 });
6036 Object.defineProperty(__proto, "resizeOnContentsReady", {
6037 /**
6038 * Enabling this option will automatically call {@link Flicking#resize} when all image/video inside panels are loaded.
6039 * This can be useful when you have contents inside Flicking that changes its size when it's loaded
6040 * @ko 이 옵션을 활성화할 경우, Flicking 패널 내부의 이미지/비디오들이 로드되었을 때 자동으로 {@link Flicking#resize}를 호출합니다.
6041 * 이 동작은 Flicking 내부에 로드 전/후로 크기가 변하는 콘텐츠를 포함하고 있을 때 유용하게 사용하실 수 있습니다.
6042 * @type {boolean}
6043 * @default false
6044 */
6045 get: function () {
6046 return this._resizeOnContentsReady;
6047 },
6048 set: function (val) {
6049 this._resizeOnContentsReady = val;
6050 },
6051 enumerable: false,
6052 configurable: true
6053 });
6054 Object.defineProperty(__proto, "needPanelThreshold", {
6055 // EVENTS
6056
6057 /**
6058 * A Threshold from viewport edge before triggering `needPanel` event
6059 * @ko `needPanel`이벤트가 발생하기 위한 뷰포트 끝으로부터의 최대 거리
6060 * @type {number}
6061 * @default 0
6062 */
6063 get: function () {
6064 return this._needPanelThreshold;
6065 },
6066 // EVENTS
6067 set: function (val) {
6068 this._needPanelThreshold = val;
6069 },
6070 enumerable: false,
6071 configurable: true
6072 });
6073 Object.defineProperty(__proto, "preventEventsBeforeInit", {
6074 /**
6075 * When enabled, events are not triggered before `ready` when initializing
6076 * @ko 활성화할 경우 초기화시 `ready` 이벤트 이전의 이벤트가 발생하지 않습니다.
6077 * @type {boolean}
6078 * @default true
6079 */
6080 get: function () {
6081 return this._preventEventsBeforeInit;
6082 },
6083 set: function (val) {
6084 this._preventEventsBeforeInit = val;
6085 },
6086 enumerable: false,
6087 configurable: true
6088 });
6089 Object.defineProperty(__proto, "deceleration", {
6090 // ANIMATION
6091
6092 /**
6093 * Deceleration value for panel movement animation which is triggered by user input. A higher value means a shorter animation time
6094 * @ko 사용자의 동작으로 가속도가 적용된 패널 이동 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아집니다
6095 * @type {number}
6096 * @default 0.0075
6097 */
6098 get: function () {
6099 return this._deceleration;
6100 },
6101 // ANIMATION
6102 set: function (val) {
6103 this._deceleration = val;
6104 },
6105 enumerable: false,
6106 configurable: true
6107 });
6108 Object.defineProperty(__proto, "easing", {
6109 /**
6110 * An easing function applied to the panel movement animation. Default value is `easeOutCubic`
6111 * @ko 패널 이동 애니메이션에 적용할 easing 함수. 기본값은 `easeOutCubic`이다
6112 * @type {function}
6113 * @default x => 1 - Math.pow(1 - x, 3)
6114 * @see Easing Functions Cheat Sheet {@link http://easings.net/} <ko>이징 함수 Cheat Sheet {@link http://easings.net/}</ko>
6115 */
6116 get: function () {
6117 return this._easing;
6118 },
6119 set: function (val) {
6120 this._easing = val;
6121 },
6122 enumerable: false,
6123 configurable: true
6124 });
6125 Object.defineProperty(__proto, "duration", {
6126 /**
6127 * Default duration of the animation (ms)
6128 * @ko 디폴트 애니메이션 재생 시간 (ms)
6129 * @type {number}
6130 * @default 500
6131 */
6132 get: function () {
6133 return this._duration;
6134 },
6135 set: function (val) {
6136 this._duration = val;
6137 },
6138 enumerable: false,
6139 configurable: true
6140 });
6141 Object.defineProperty(__proto, "inputType", {
6142 // INPUT
6143
6144 /**
6145 * Types of input devices to enable
6146 * @ko 활성화할 입력 장치 종류
6147 * @type {string[]}
6148 * @default ["touch", "mouse"]
6149 * @see {@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption Possible values (PanInputOption#inputType)}
6150 * <ko>{@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption 가능한 값들 (PanInputOption#inputType)}</ko>
6151 */
6152 get: function () {
6153 return this._inputType;
6154 },
6155 // INPUT
6156 set: function (val) {
6157 this._inputType = val;
6158 },
6159 enumerable: false,
6160 configurable: true
6161 });
6162 Object.defineProperty(__proto, "moveType", {
6163 /**
6164 * Movement style by user input. This will change instance type of {@link Flicking#control}
6165 * You can use the values of the constant {@link MOVE_TYPE}
6166 * @ko 사용자 입력에 의한 이동 방식. 이 값에 따라 {@link Flicking#control}의 인스턴스 타입이 결정됩니다
6167 * 상수 {@link MOVE_TYPE}에 정의된 값들을 이용할 수 있습니다
6168 * @type {MOVE_TYPE | Pair<string, object>}
6169 * @default "snap"
6170 * @example
6171 * |moveType|control|options|
6172 * |:---:|:---:|:---:|
6173 * |"snap"|{@link SnapControl}||
6174 * |"freeScroll"|{@link FreeControl}|{@link FreeControlOptions}|
6175 *
6176 * ```ts
6177 * import Flicking, { MOVE_TYPE } from "@egjs/flicking";
6178 *
6179 * const flicking = new Flicking({
6180 * moveType: MOVE_TYPE.SNAP
6181 * });
6182 * ```
6183 *
6184 * ```ts
6185 * const flicking = new Flicking({
6186 * // If you want more specific settings for the moveType
6187 * // [moveType, options for that moveType]
6188 * // In this case, it's ["freeScroll", FreeControlOptions]
6189 * moveType: [MOVE_TYPE.FREE_SCROLL, { stopAtEdge: true }]
6190 * });
6191 * ```
6192 */
6193 get: function () {
6194 return this._moveType;
6195 },
6196 set: function (val) {
6197 this._moveType = val;
6198 },
6199 enumerable: false,
6200 configurable: true
6201 });
6202 Object.defineProperty(__proto, "threshold", {
6203 /**
6204 * Movement threshold to change panel (unit: px). It should be dragged above the threshold to change the current panel.
6205 * @ko 패널 변경을 위한 이동 임계값 (단위: px). 주어진 값 이상으로 스크롤해야만 패널 변경이 가능하다.
6206 * @type {number}
6207 * @default 40
6208 */
6209 get: function () {
6210 return this._threshold;
6211 },
6212 set: function (val) {
6213 this._threshold = val;
6214 },
6215 enumerable: false,
6216 configurable: true
6217 });
6218 Object.defineProperty(__proto, "interruptable", {
6219 /**
6220 * Set animation to be interruptable by click/touch.
6221 * @ko 사용자의 클릭/터치로 인해 애니메이션을 도중에 멈출 수 있도록 설정합니다.
6222 * @type {boolean}
6223 * @default true
6224 */
6225 get: function () {
6226 return this._interruptable;
6227 },
6228 set: function (val) {
6229 this._interruptable = val;
6230 },
6231 enumerable: false,
6232 configurable: true
6233 });
6234 Object.defineProperty(__proto, "bounce", {
6235 /**
6236 * The size value of the bounce area. Only can be enabled when `circular=false`.
6237 * You can set different bounce value for prev/next direction by using array.
6238 * `number` for px value, and `string` for px, and % value relative to viewport size.
6239 * You have to call {@link Control#updateInput} after changing this to take effect.
6240 * @ko Flicking이 최대 영역을 넘어서 갈 수 있는 최대 크기. `circular=false`인 경우에만 사용할 수 있습니다.
6241 * 배열을 통해 prev/next 방향에 대해 서로 다른 바운스 값을 지정할 수 있습니다.
6242 * `number`를 통해 px값을, `stirng`을 통해 px 혹은 뷰포트 크기 대비 %값을 사용할 수 있습니다.
6243 * 이 값을 변경시 {@link Control#updateInput}를 호출해야 합니다.
6244 * @type {string | number | Array<string | number>}
6245 * @default "20%"
6246 * @example
6247 * ```ts
6248 * const possibleOptions = [
6249 * // % values, relative to viewport element(".flicking-viewport")'s size
6250 * "0%", "25%", "42%",
6251 * // px values, arithmetic calculation with (+/-) is also allowed.
6252 * "0px", "100px", "50% - 25px",
6253 * // numbers, same to number + px ("0px", "100px")
6254 * 0, 100, 1000
6255 * ];
6256 * ```
6257 *
6258 * @example
6259 * ```ts
6260 * const flicking = new Flicking("#el", { bounce: "20%" });
6261 *
6262 * flicking.bounce = "100%";
6263 * flicking.control.updateInput(); // Call this to update!
6264 * ```
6265 */
6266 get: function () {
6267 return this._bounce;
6268 },
6269 set: function (val) {
6270 this._bounce = val;
6271 },
6272 enumerable: false,
6273 configurable: true
6274 });
6275 Object.defineProperty(__proto, "iOSEdgeSwipeThreshold", {
6276 /**
6277 * Size of the area from the right edge in iOS safari (in px) which enables swipe-back or swipe-forward
6278 * @ko iOS Safari에서 swipe를 통한 뒤로가기/앞으로가기를 활성화하는 오른쪽 끝으로부터의 영역의 크기 (px)
6279 * @type {number}
6280 * @default 30
6281 */
6282 get: function () {
6283 return this._iOSEdgeSwipeThreshold;
6284 },
6285 set: function (val) {
6286 this._iOSEdgeSwipeThreshold = val;
6287 },
6288 enumerable: false,
6289 configurable: true
6290 });
6291 Object.defineProperty(__proto, "preventClickOnDrag", {
6292 /**
6293 * Automatically prevent `click` event if the user has dragged at least a single pixel on the viewport element
6294 * @ko 사용자가 뷰포트 영역을 1픽셀이라도 드래그했을 경우 자동으로 {@link https://developer.mozilla.org/ko/docs/Web/API/Element/click_event click} 이벤트를 취소합니다
6295 * @type {boolean}
6296 * @default true
6297 */
6298 get: function () {
6299 return this._preventClickOnDrag;
6300 },
6301 set: function (val) {
6302 var prevVal = this._preventClickOnDrag;
6303 if (val === prevVal) return;
6304 var controller = this._control.controller;
6305
6306 if (val) {
6307 controller.addPreventClickHandler();
6308 } else {
6309 controller.removePreventClickHandler();
6310 }
6311
6312 this._preventClickOnDrag = val;
6313 },
6314 enumerable: false,
6315 configurable: true
6316 });
6317 Object.defineProperty(__proto, "disableOnInit", {
6318 /**
6319 * Automatically call {@link Flicking#disableInput disableInput()} on initialization
6320 * @ko Flicking init시에 {@link Flicking#disableInput disableInput()}을 바로 호출합니다
6321 * @type {boolean}
6322 * @default false
6323 */
6324 get: function () {
6325 return this._disableOnInit;
6326 },
6327 set: function (val) {
6328 this._disableOnInit = val;
6329 },
6330 enumerable: false,
6331 configurable: true
6332 });
6333 Object.defineProperty(__proto, "renderOnlyVisible", {
6334 // PERFORMANCE
6335
6336 /**
6337 * Whether to render visible panels only. This can dramatically increase performance when there're many panels.
6338 * @ko 보이는 패널만 렌더링할지 여부를 설정합니다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있습니다.
6339 * @type {boolean}
6340 * @default false
6341 */
6342 get: function () {
6343 return this._renderOnlyVisible;
6344 },
6345 // PERFORMANCE
6346 set: function (val) {
6347 this._renderOnlyVisible = val;
6348 },
6349 enumerable: false,
6350 configurable: true
6351 });
6352 Object.defineProperty(__proto, "autoInit", {
6353 // OTHERS
6354
6355 /**
6356 * Call {@link Flicking#init init()} automatically when creating Flicking's instance
6357 * @ko Flicking 인스턴스를 생성할 때 자동으로 {@link Flicking#init init()}를 호출합니다
6358 * @type {boolean}
6359 * @default true
6360 * @readonly
6361 */
6362 get: function () {
6363 return this._autoInit;
6364 },
6365 enumerable: false,
6366 configurable: true
6367 });
6368 Object.defineProperty(__proto, "autoResize", {
6369 /**
6370 * Attach Flicking's {@link Flicking#resize resize} method to window's resize event.
6371 * Flicking will automatically call {@link Flicking#resize resize} window size and orientation change.
6372 * @ko Flicking의 {@link Flicking#resize resize} 메소드를 window의 resize 이벤트 핸들러로 등록합니다.
6373 * 설정시 window 창 크기 및 orientation 변경에 의해 자동으로 {@link Flicking#resize resize}를 호출합니다.
6374 * @type {boolean}
6375 * @default true
6376 */
6377 get: function () {
6378 return this._autoResize;
6379 },
6380 // OTHERS
6381 set: function (val) {
6382 this._autoResize = val;
6383 },
6384 enumerable: false,
6385 configurable: true
6386 });
6387 Object.defineProperty(__proto, "renderExternal", {
6388 /**
6389 * This is an option for the frameworks(React, Vue, Angular, ...). Don't set it as it's automatically managed by Flicking.
6390 * @ko 프레임워크(React, Vue, Angular, ...)에서만 사용하는 옵션으로, 자동으로 설정되므로 따로 사용하실 필요 없습니다!
6391 * @type {boolean}
6392 * @default false
6393 * @internal
6394 * @readonly
6395 */
6396 get: function () {
6397 return this._renderExternal;
6398 },
6399 enumerable: false,
6400 configurable: true
6401 });
6402 /**
6403 * Initialize Flicking and move to the default index
6404 * This is automatically called on Flicking's constructor when `autoInit` is true(default)
6405 * @ko Flicking을 초기화하고, 디폴트 인덱스로 이동합니다
6406 * 이 메소드는 `autoInit` 옵션이 true(default)일 경우 Flicking이 생성될 때 자동으로 호출됩니다
6407 * @fires Flicking#ready
6408 * @return {this}
6409 */
6410
6411 __proto.init = function () {
6412 return __awaiter(this, void 0, void 0, function () {
6413 var camera, renderer, control, originalTrigger, preventEventsBeforeInit;
6414
6415 var _this = this;
6416
6417 return __generator(this, function (_a) {
6418 switch (_a.label) {
6419 case 0:
6420 if (this._initialized) return [2
6421 /*return*/
6422 ];
6423 camera = this._camera;
6424 renderer = this._renderer;
6425 control = this._control;
6426 originalTrigger = this.trigger;
6427 preventEventsBeforeInit = this._preventEventsBeforeInit;
6428 camera.init(this);
6429 renderer.init(this);
6430 control.init(this);
6431
6432 if (preventEventsBeforeInit) {
6433 this.trigger = function () {
6434 return _this;
6435 };
6436 }
6437
6438 return [4
6439 /*yield*/
6440 , this.resize()];
6441
6442 case 1:
6443 _a.sent(); // Look at initial panel
6444
6445
6446 return [4
6447 /*yield*/
6448 , this._moveToInitialPanel()];
6449
6450 case 2:
6451 // Look at initial panel
6452 _a.sent();
6453
6454 if (this._autoResize) {
6455 window.addEventListener("resize", this.resize);
6456 }
6457
6458 if (this._preventClickOnDrag) {
6459 control.controller.addPreventClickHandler();
6460 }
6461
6462 if (this._disableOnInit) {
6463 this.disableInput();
6464 }
6465
6466 renderer.checkPanelContentsReady(renderer.panels);
6467
6468 this._plugins.forEach(function (plugin) {
6469 return plugin.init(_this);
6470 }); // Done initializing & emit ready event
6471
6472
6473 this._initialized = true;
6474
6475 if (preventEventsBeforeInit) {
6476 this.trigger = originalTrigger;
6477 }
6478
6479 this.trigger(new ComponentEvent(EVENTS.READY));
6480 return [2
6481 /*return*/
6482 ];
6483 }
6484 });
6485 });
6486 };
6487 /**
6488 * Destroy Flicking and remove all event handlers
6489 * @ko Flicking과 하위 컴포넌트들을 초기 상태로 되돌리고, 부착된 모든 이벤트 핸들러를 제거합니다
6490 * @return {void}
6491 */
6492
6493
6494 __proto.destroy = function () {
6495 this.off();
6496 window.removeEventListener("resize", this.resize);
6497
6498 this._control.destroy();
6499
6500 this._camera.destroy();
6501
6502 this._renderer.destroy();
6503
6504 this._plugins.forEach(function (plugin) {
6505 return plugin.destroy();
6506 });
6507
6508 this._initialized = false;
6509 };
6510 /**
6511 * Move to the previous panel (current index - 1)
6512 * @ko 이전 패널로 이동합니다 (현재 인덱스 - 1)
6513 * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the panel movement animation (unit: ms)<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
6514 * @async
6515 * @fires Flicking#moveStart
6516 * @fires Flicking#move
6517 * @fires Flicking#moveEnd
6518 * @fires Flicking#willChange
6519 * @fires Flicking#changed
6520 * @fires Flicking#willRestore
6521 * @fires Flicking#restored
6522 * @fires Flicking#needPanel
6523 * @fires Flicking#visibleChange
6524 * @fires Flicking#reachEdge
6525 * @throws {FlickingError}
6526 * |code|condition|
6527 * |---|---|
6528 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the previous panel does not exist|
6529 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|
6530 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
6531 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|
6532 * <ko>
6533 *
6534 * |code|condition|
6535 * |---|---|
6536 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|이전 패널이 존재하지 않을 경우|
6537 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|
6538 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
6539 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
6540 * </ko>
6541 * @return {Promise<void>} A Promise which will be resolved after reaching the previous panel<ko>이전 패널 도달시에 resolve되는 Promise</ko>
6542 */
6543
6544
6545 __proto.prev = function (duration) {
6546 var _a, _b, _c;
6547
6548 if (duration === void 0) {
6549 duration = this._duration;
6550 }
6551
6552 return this.moveTo((_c = (_b = (_a = this._control.activePanel) === null || _a === void 0 ? void 0 : _a.prev()) === null || _b === void 0 ? void 0 : _b.index) !== null && _c !== void 0 ? _c : -1, duration, DIRECTION.PREV);
6553 };
6554 /**
6555 * Move to the next panel (current index + 1)
6556 * @ko 다음 패널로 이동합니다 (현재 인덱스 + 1)
6557 * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
6558 * @async
6559 * @fires Flicking#moveStart
6560 * @fires Flicking#move
6561 * @fires Flicking#moveEnd
6562 * @fires Flicking#willChange
6563 * @fires Flicking#changed
6564 * @fires Flicking#willRestore
6565 * @fires Flicking#restored
6566 * @fires Flicking#needPanel
6567 * @fires Flicking#visibleChange
6568 * @fires Flicking#reachEdge
6569 * @throws {FlickingError}
6570 * |code|condition|
6571 * |---|---|
6572 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the next panel does not exist|
6573 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|
6574 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
6575 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|
6576 * <ko>
6577 *
6578 * |code|condition|
6579 * |---|---|
6580 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|다음 패널이 존재하지 않을 경우|
6581 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|
6582 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
6583 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
6584 *
6585 * </ko>
6586 * @return {Promise<void>} A Promise which will be resolved after reaching the next panel<ko>다음 패널 도달시에 resolve되는 Promise</ko>
6587 */
6588
6589
6590 __proto.next = function (duration) {
6591 var _a, _b, _c;
6592
6593 if (duration === void 0) {
6594 duration = this._duration;
6595 }
6596
6597 return this.moveTo((_c = (_b = (_a = this._control.activePanel) === null || _a === void 0 ? void 0 : _a.next()) === null || _b === void 0 ? void 0 : _b.index) !== null && _c !== void 0 ? _c : this._renderer.panelCount, duration, DIRECTION.NEXT);
6598 };
6599 /**
6600 * Move to the panel with given index
6601 * @ko 주어진 인덱스에 해당하는 패널로 이동합니다
6602 * @param {number} index The index of the panel to move<ko>이동할 패널의 인덱스</ko>
6603 * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>
6604 * @param {DIRECTION} [direction=DIRECTION.NONE] Direction to move, only available in the {@link Flicking#circular circular} mode<ko>이동할 방향. {@link Flicking#circular circular} 옵션 활성화시에만 사용 가능합니다</ko>
6605 * @async
6606 * @fires Flicking#moveStart
6607 * @fires Flicking#move
6608 * @fires Flicking#moveEnd
6609 * @fires Flicking#willChange
6610 * @fires Flicking#changed
6611 * @fires Flicking#willRestore
6612 * @fires Flicking#restored
6613 * @fires Flicking#needPanel
6614 * @fires Flicking#visibleChange
6615 * @fires Flicking#reachEdge
6616 * @throws {FlickingError}
6617 * |code|condition|
6618 * |---|---|
6619 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the root is not either string or HTMLElement|
6620 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|
6621 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
6622 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|
6623 * <ko>
6624 *
6625 * |code|condition|
6626 * |---|---|
6627 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|해당 인덱스를 가진 패널이 존재하지 않을 경우|
6628 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|
6629 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
6630 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
6631 *
6632 * </ko>
6633 * @return {Promise<void>} A Promise which will be resolved after reaching the target panel<ko>해당 패널 도달시에 resolve되는 Promise</ko>
6634 */
6635
6636
6637 __proto.moveTo = function (index, duration, direction) {
6638 if (duration === void 0) {
6639 duration = this._duration;
6640 }
6641
6642 if (direction === void 0) {
6643 direction = DIRECTION.NONE;
6644 }
6645
6646 var renderer = this._renderer;
6647 var panelCount = renderer.panelCount;
6648 var panel = renderer.getPanel(index);
6649
6650 if (!panel) {
6651 return Promise.reject(new FlickingError(MESSAGE.INDEX_OUT_OF_RANGE(index, 0, panelCount - 1), CODE.INDEX_OUT_OF_RANGE));
6652 }
6653
6654 if (this._control.animating) {
6655 return Promise.reject(new FlickingError(MESSAGE.ANIMATION_ALREADY_PLAYING, CODE.ANIMATION_ALREADY_PLAYING));
6656 }
6657
6658 return this._control.moveToPanel(panel, {
6659 duration: duration,
6660 direction: direction
6661 });
6662 };
6663 /**
6664 * Return the {@link Panel} at the given index. `null` if it doesn't exists.
6665 * @ko 주어진 인덱스에 해당하는 {@link Panel}을 반환합니다. 주어진 인덱스에 해당하는 패널이 존재하지 않을 경우 `null`을 반환합니다.
6666 * @return {Panel | null} Panel at the given index<ko>주어진 인덱스에 해당하는 패널</ko>
6667 * @see Panel
6668 * @example
6669 * ```ts
6670 * const panel = flicking.getPanel(0);
6671 * // Which is a shorthand to...
6672 * const samePanel = flicking.panels[0];
6673 * ```
6674 */
6675
6676
6677 __proto.getPanel = function (index) {
6678 return this._renderer.getPanel(index);
6679 };
6680 /**
6681 * Enable input from the user (mouse/touch)
6682 * @ko 사용자의 입력(마우스/터치)를 활성화합니다
6683 * @return {this}
6684 */
6685
6686
6687 __proto.enableInput = function () {
6688 this._control.enable();
6689
6690 return this;
6691 };
6692 /**
6693 * Disable input from the user (mouse/touch)
6694 * @ko 사용자의 입력(마우스/터치)를 막습니다
6695 * @return {this}
6696 */
6697
6698
6699 __proto.disableInput = function () {
6700 this._control.disable();
6701
6702 return this;
6703 };
6704 /**
6705 * Get current flicking status. You can restore current state by giving returned value to {@link Flicking#setStatus setStatus()}
6706 * @ko 현재 상태를 반환합니다. 반환받은 값을 {@link Flicking#setStatus setStatus()} 메소드의 인자로 지정하면 현재 상태를 복원할 수 있습니다
6707 * @param {object} options Status retrieving options<ko>Status 반환 옵션</ko>
6708 * @param {boolean} [options.index=true] Include current panel index to the returning status. Camera will automatically move to the given index when the {@link Flicking#setStatus setStatus} is called<ko>현재 패널 인덱스를 반환값에 포함시킵니다. {@link Flicking#setStatus setStatus} 호출시 자동으로 해당 인덱스로 카메라를 움직입니다</ko>
6709 * @param {boolean} [options.position=true] Include camera position to the returning status. This works only when the {@link Flicking#moveType moveType} is `freeScroll`<ko>카메라의 현재 위치를 반환값에 포함시킵니다. 이 옵션은 {@link Flicking#moveType moveType}이 `freeScroll`일 경우에만 동작합니다</ko>
6710 * @param {boolean} [options.includePanelHTML=false] Include panel's `outerHTML` to the returning status<ko>패널의 `outerHTML`을 반환값에 포함시킵니다</ko>
6711 * @param {boolean} [options.visiblePanelsOnly=false] Include only {@link Flicking#visiblePanel visiblePanel}'s HTML. This option is available only when the `includePanelHTML` is true
6712 * <ko>현재 보이는 패널({@link Flicking#visiblePanel visiblePanel})의 HTML만 반환합니다. `includePanelHTML`이 `true`일 경우에만 동작합니다.</ko>
6713 * @return {Partial<Status>} An object with current status value information<ko>현재 상태값 정보를 가진 객체.</ko>
6714 */
6715
6716
6717 __proto.getStatus = function (_a) {
6718 var _b, _c;
6719
6720 var _d = _a === void 0 ? {} : _a,
6721 _e = _d.index,
6722 index = _e === void 0 ? true : _e,
6723 _f = _d.position,
6724 position = _f === void 0 ? true : _f,
6725 _g = _d.includePanelHTML,
6726 includePanelHTML = _g === void 0 ? false : _g,
6727 _h = _d.visiblePanelsOnly,
6728 visiblePanelsOnly = _h === void 0 ? false : _h;
6729
6730 var camera = this._camera;
6731 var panels = visiblePanelsOnly ? this.visiblePanels : this.panels;
6732 var status = {
6733 panels: panels.map(function (panel) {
6734 var panelInfo = {
6735 index: panel.index
6736 };
6737
6738 if (includePanelHTML) {
6739 panelInfo.html = panel.element.outerHTML;
6740 }
6741
6742 return panelInfo;
6743 })
6744 };
6745
6746 if (index) {
6747 status.index = this.index;
6748 }
6749
6750 if (position) {
6751 var nearestAnchor = camera.findNearestAnchor(camera.position);
6752
6753 if (nearestAnchor) {
6754 status.position = {
6755 panel: nearestAnchor.panel.index,
6756 progressInPanel: camera.getProgressInPanel(nearestAnchor.panel)
6757 };
6758 }
6759 }
6760
6761 if (visiblePanelsOnly) {
6762 var visiblePanels = this.visiblePanels;
6763 status.visibleOffset = (_c = (_b = visiblePanels[0]) === null || _b === void 0 ? void 0 : _b.index) !== null && _c !== void 0 ? _c : 0;
6764 }
6765
6766 return status;
6767 };
6768 /**
6769 * Restore to the state of the given {@link Status}
6770 * @ko 주어진 {@link Status}의 상태로 복원합니다
6771 * @param {Partial<Status>} status Status value to be restored. You should use the return value of the {@link Flicking#getStatus getStatus()} method<ko>복원할 상태 값. {@link Flicking#getStatus getStatus()} 메서드의 반환값을 지정하면 됩니다</ko>
6772 * @return {void}
6773 */
6774
6775
6776 __proto.setStatus = function (status) {
6777 var _a;
6778
6779 if (!this._initialized) {
6780 throw new FlickingError(MESSAGE.NOT_INITIALIZED, CODE.NOT_INITIALIZED);
6781 }
6782
6783 var index = status.index,
6784 position = status.position,
6785 visibleOffset = status.visibleOffset,
6786 panels = status.panels;
6787 var renderer = this._renderer;
6788 var control = this._control; // Can't add/remove panels on external rendering
6789
6790 if (((_a = panels[0]) === null || _a === void 0 ? void 0 : _a.html) && !this._renderExternal) {
6791 renderer.batchRemove({
6792 index: 0,
6793 deleteCount: this.panels.length
6794 });
6795 renderer.batchInsert({
6796 index: 0,
6797 elements: parseElement(panels.map(function (panel) {
6798 return panel.html;
6799 }))
6800 });
6801 }
6802
6803 if (index) {
6804 var panelIndex = visibleOffset ? index - visibleOffset : index;
6805 void this.moveTo(panelIndex, 0).catch(function () {
6806 return void 0;
6807 });
6808 }
6809
6810 if (position && this._moveType === MOVE_TYPE.FREE_SCROLL) {
6811 var panel = position.panel,
6812 progressInPanel = position.progressInPanel;
6813 var panelIndex = visibleOffset ? panel - visibleOffset : panel;
6814 var panelRange = renderer.panels[panelIndex].range;
6815 var newCameraPos = panelRange.min + (panelRange.max - panelRange.min) * progressInPanel;
6816 void control.moveToPosition(newCameraPos, 0).catch(function () {
6817 return void 0;
6818 });
6819 }
6820 };
6821 /**
6822 * Add plugins that can have different effects on Flicking
6823 * @ko 플리킹에 다양한 효과를 부여할 수 있는 플러그인을 추가합니다
6824 * @param {...Plugin} plugins The plugin(s) to add<ko>추가할 플러그인(들)</ko>
6825 * @return {this}
6826 * @see https://github.com/naver/egjs-flicking-plugins
6827 */
6828
6829
6830 __proto.addPlugins = function () {
6831 var _a;
6832
6833 var _this = this;
6834
6835 var plugins = [];
6836
6837 for (var _i = 0; _i < arguments.length; _i++) {
6838 plugins[_i] = arguments[_i];
6839 }
6840
6841 if (this._initialized) {
6842 plugins.forEach(function (item) {
6843 return item.init(_this);
6844 });
6845 }
6846
6847 (_a = this._plugins).push.apply(_a, __spreadArray([], __read(plugins)));
6848
6849 return this;
6850 };
6851 /**
6852 * Remove plugins from Flicking.
6853 * @ko 플리킹으로부터 플러그인들을 제거합니다.
6854 * @param {...Plugin} plugin The plugin(s) to remove.<ko>제거 플러그인(들).</ko>
6855 * @return {this}
6856 * @see https://github.com/naver/egjs-flicking-plugins
6857 */
6858
6859
6860 __proto.removePlugins = function () {
6861 var _this = this;
6862
6863 var plugins = [];
6864
6865 for (var _i = 0; _i < arguments.length; _i++) {
6866 plugins[_i] = arguments[_i];
6867 }
6868
6869 plugins.forEach(function (item) {
6870 var foundIndex = findIndex(_this._plugins, function (val) {
6871 return val === item;
6872 });
6873
6874 if (foundIndex >= 0) {
6875 item.destroy();
6876
6877 _this._plugins.splice(foundIndex, 1);
6878 }
6879 });
6880 return this;
6881 };
6882 /**
6883 * Update viewport/panel sizes
6884 * @ko 패널 및 뷰포트의 크기를 갱신합니다
6885 * @method
6886 * @fires Flicking#beforeResize
6887 * @fires Flicking#afterResize
6888 * @return {this}
6889 */
6890
6891
6892 __proto.resize = function () {
6893 return __awaiter(this, void 0, void 0, function () {
6894 var viewport, renderer, camera, control, activePanel, prevWidth, prevHeight, prevProgressInPanel, newWidth, newHeight, sizeChanged;
6895 return __generator(this, function (_a) {
6896 switch (_a.label) {
6897 case 0:
6898 viewport = this._viewport;
6899 renderer = this._renderer;
6900 camera = this._camera;
6901 control = this._control;
6902 activePanel = control.activePanel;
6903 prevWidth = viewport.width;
6904 prevHeight = viewport.height;
6905 prevProgressInPanel = activePanel ? camera.getProgressInPanel(activePanel) : 0;
6906 this.trigger(new ComponentEvent(EVENTS.BEFORE_RESIZE, {
6907 width: prevWidth,
6908 height: prevHeight,
6909 element: viewport.element
6910 }));
6911 viewport.resize();
6912 return [4
6913 /*yield*/
6914 , renderer.forceRenderAllPanels()];
6915
6916 case 1:
6917 _a.sent(); // Render all panel elements, to update sizes
6918
6919
6920 renderer.updatePanelSize();
6921 camera.updateAlignPos();
6922 camera.updateRange();
6923 camera.updateAnchors();
6924 return [4
6925 /*yield*/
6926 , renderer.render()];
6927
6928 case 2:
6929 _a.sent();
6930
6931 if (control.animating) ; else {
6932 control.updatePosition(prevProgressInPanel);
6933 control.updateInput();
6934 }
6935
6936 newWidth = viewport.width;
6937 newHeight = viewport.height;
6938 sizeChanged = newWidth !== prevWidth || newHeight !== prevHeight;
6939 this.trigger(new ComponentEvent(EVENTS.AFTER_RESIZE, {
6940 width: viewport.width,
6941 height: viewport.height,
6942 prev: {
6943 width: prevWidth,
6944 height: prevHeight
6945 },
6946 sizeChanged: sizeChanged,
6947 element: viewport.element
6948 }));
6949 return [2
6950 /*return*/
6951 ];
6952 }
6953 });
6954 });
6955 };
6956 /**
6957 * Add new panels after the last panel
6958 * @ko 패널 목록의 제일 끝에 새로운 패널들을 추가합니다
6959 * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both
6960 * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>
6961 * @return {Panel[]} An array of appended panels<ko>추가된 패널들의 배열</ko>
6962 * @see Panel
6963 * @see ElementLike
6964 * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)
6965 * @example
6966 * ```ts
6967 * const flicking = new Flicking("#flick");
6968 * // These are possible parameters
6969 * flicking.append(document.createElement("div"));
6970 * flicking.append("\<div\>Panel\</div\>");
6971 * flicking.append(["\<div\>Panel\</div\>", document.createElement("div")]);
6972 * // Even this is possible
6973 * flicking.append("\<div\>Panel 1\</div\>\<div\>Panel 2\</div\>");
6974 * ```
6975 */
6976
6977
6978 __proto.append = function (element) {
6979 return this.insert(this._renderer.panelCount, element);
6980 };
6981 /**
6982 * Add new panels before the first panel
6983 * This will increase index of panels after by the number of panels added
6984 * @ko 패널 목록의 제일 앞(index 0)에 새로운 패널들을 추가합니다
6985 * 추가한 패널의 개수만큼 기존 패널들의 인덱스가 증가합니다.
6986 * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both
6987 * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>
6988 * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>
6989 * @see Panel
6990 * @see ElementLike
6991 * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)
6992 * @example
6993 * ```ts
6994 * const flicking = new eg.Flicking("#flick");
6995 * flicking.prepend(document.createElement("div"));
6996 * flicking.prepend("\<div\>Panel\</div\>");
6997 * flicking.prepend(["\<div\>Panel\</div\>", document.createElement("div")]);
6998 * // Even this is possible
6999 * flicking.prepend("\<div\>Panel 1\</div\>\<div\>Panel 2\</div\>");
7000 * ```
7001 */
7002
7003
7004 __proto.prepend = function (element) {
7005 return this.insert(0, element);
7006 };
7007 /**
7008 * Insert new panels at given index
7009 * This will increase index of panels after by the number of panels added
7010 * @ko 주어진 인덱스에 새로운 패널들을 추가합니다
7011 * 해당 인덱스보다 같거나 큰 인덱스를 가진 기존 패널들은 추가한 패널의 개수만큼 인덱스가 증가합니다.
7012 * @param {number} index Index to insert new panels at<ko>새로 패널들을 추가할 인덱스</ko>
7013 * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both
7014 * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>
7015 * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>
7016 * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)
7017 * @example
7018 * ```ts
7019 * const flicking = new eg.Flicking("#flick");
7020 * flicking.insert(0, document.createElement("div"));
7021 * flicking.insert(2, "\<div\>Panel\</div\>");
7022 * flicking.insert(1, ["\<div\>Panel\</div\>", document.createElement("div")]);
7023 * // Even this is possible
7024 * flicking.insert(3, "\<div\>Panel 1\</div\>\<div\>Panel 2\</div\>");
7025 * ```
7026 */
7027
7028
7029 __proto.insert = function (index, element) {
7030 if (this._renderExternal) {
7031 throw new FlickingError(MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, CODE.NOT_ALLOWED_IN_FRAMEWORK);
7032 }
7033
7034 return this._renderer.batchInsert({
7035 index: index,
7036 elements: parseElement(element)
7037 });
7038 };
7039 /**
7040 * Remove the panel at the given index
7041 * This will decrease index of panels after by the number of panels removed
7042 * @ko 주어진 인덱스의 패널을 제거합니다
7043 * 해당 인덱스보다 큰 인덱스를 가진 기존 패널들은 제거한 패널의 개수만큼 인덱스가 감소합니다
7044 * @param {number} index Index of panel to remove<ko>제거할 패널의 인덱스</ko>
7045 * @param {number} [deleteCount=1] Number of panels to remove from index<ko>`index` 이후로 제거할 패널의 개수</ko>
7046 * @return {Panel[]} An array of removed panels<ko>제거된 패널들의 배열</ko>
7047 */
7048
7049
7050 __proto.remove = function (index, deleteCount) {
7051 if (deleteCount === void 0) {
7052 deleteCount = 1;
7053 }
7054
7055 if (this._renderExternal) {
7056 throw new FlickingError(MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, CODE.NOT_ALLOWED_IN_FRAMEWORK);
7057 }
7058
7059 return this._renderer.batchRemove({
7060 index: index,
7061 deleteCount: deleteCount
7062 });
7063 };
7064
7065 __proto._createControl = function () {
7066 var _a;
7067
7068 var moveType = this._moveType;
7069 var moveTypes = Object.keys(MOVE_TYPE).map(function (key) {
7070 return MOVE_TYPE[key];
7071 });
7072 var moveTypeStr = Array.isArray(moveType) ? moveType[0] : moveType;
7073 var moveTypeOptions = Array.isArray(moveType) ? (_a = moveType[1]) !== null && _a !== void 0 ? _a : {} : {};
7074
7075 if (!includes(moveTypes, moveTypeStr)) {
7076 throw new FlickingError(MESSAGE.WRONG_OPTION("moveType", JSON.stringify(moveType)), CODE.WRONG_OPTION);
7077 }
7078
7079 switch (moveTypeStr) {
7080 case MOVE_TYPE.SNAP:
7081 return new SnapControl(moveTypeOptions);
7082
7083 case MOVE_TYPE.FREE_SCROLL:
7084 return new FreeControl(moveTypeOptions);
7085
7086 case MOVE_TYPE.STRICT:
7087 return new StrictControl(moveTypeOptions);
7088 }
7089 };
7090
7091 __proto._createCamera = function () {
7092 var cameraOption = {
7093 align: this._align
7094 };
7095
7096 if (this._circular) {
7097 if (this._bound) {
7098 // eslint-disable-next-line no-console
7099 console.warn("\"circular\" and \"bound\" option cannot be used together, ignoring bound.");
7100 }
7101
7102 return new CircularCamera(cameraOption);
7103 } else if (this._bound) {
7104 return new BoundCamera(cameraOption);
7105 } else {
7106 return new LinearCamera(cameraOption);
7107 }
7108 };
7109
7110 __proto._createRenderer = function () {
7111 var rendererOptions = {
7112 align: this._align
7113 };
7114 var renderExternal = this._renderExternal;
7115 return renderExternal ? new renderExternal.renderer(__assign(__assign({}, rendererOptions), renderExternal.rendererOptions)) : new VanillaRenderer(rendererOptions);
7116 };
7117
7118 __proto._moveToInitialPanel = function () {
7119 return __awaiter(this, void 0, void 0, function () {
7120 var renderer, control, initialPanel;
7121 return __generator(this, function (_a) {
7122 renderer = this._renderer;
7123 control = this._control;
7124 initialPanel = renderer.getPanel(this._defaultIndex) || renderer.getPanel(0);
7125 if (!initialPanel) return [2
7126 /*return*/
7127 ];
7128 control.setActive(initialPanel, null, false);
7129 return [2
7130 /*return*/
7131 , control.moveToPanel(initialPanel, {
7132 duration: 0
7133 })];
7134 });
7135 });
7136 };
7137 /**
7138 * Version info string
7139 * @ko 버전정보 문자열
7140 * @type {string}
7141 * @readonly
7142 * @example
7143 * ```ts
7144 * Flicking.VERSION; // ex) 4.0.0
7145 * ```
7146 */
7147
7148
7149 Flicking.VERSION = "4.3.0";
7150 return Flicking;
7151}(Component);
7152
7153/**
7154 * An slide data component that holds information of a single HTMLElement
7155 * @ko 슬라이드 데이터 컴포넌트로, 단일 HTMLElement의 정보를 갖고 있습니다
7156 */
7157
7158var ExternalPanel = function (_super) {
7159 __extends(ExternalPanel, _super);
7160 /**
7161 * @param {object} options An options object<ko>옵션 오브젝트</ko>
7162 * @param {HTMLElement} [options.el] A `HTMLElement` panel's referencing<ko>패널이 참조하는 `HTMLElement`</ko>
7163 * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>
7164 * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>
7165 * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>
7166 */
7167
7168
7169 function ExternalPanel(options) {
7170 var _this = _super.call(this, options) || this;
7171
7172 _this._externalComponent = options.externalComponent;
7173 return _this;
7174 }
7175
7176 return ExternalPanel;
7177}(Panel);
7178
7179/**
7180 * Decorator that makes the method of flicking available in the framework.
7181 * @ko 프레임워크에서 플리킹의 메소드를 사용할 수 있게 하는 데코레이터.
7182 * @memberof eg.Flicking
7183 * @private
7184 * @example
7185 * ```js
7186 * import Flicking, { withFlickingMethods } from "@egjs/flicking";
7187 *
7188 * class Flicking extends React.Component<Partial<FlickingProps & FlickingOptions>> {
7189 * &#64;withFlickingMethods
7190 * private flicking: Flicking;
7191 * }
7192 * ```
7193 */
7194
7195var withFlickingMethods = function (prototype, flickingName) {
7196 [Component.prototype, Flicking.prototype].forEach(function (proto) {
7197 Object.getOwnPropertyNames(proto).filter(function (name) {
7198 return !prototype[name] && !name.startsWith("_") && name !== "constructor";
7199 }).forEach(function (name) {
7200 var descriptor = Object.getOwnPropertyDescriptor(proto, name);
7201
7202 if (descriptor.value) {
7203 // Public Function
7204 Object.defineProperty(prototype, name, {
7205 value: function () {
7206 var _a;
7207
7208 var args = [];
7209
7210 for (var _i = 0; _i < arguments.length; _i++) {
7211 args[_i] = arguments[_i];
7212 }
7213
7214 return (_a = descriptor.value).call.apply(_a, __spreadArray([this[flickingName]], __read(args)));
7215 }
7216 });
7217 } else {
7218 var getterDescriptor = {};
7219
7220 if (descriptor.get) {
7221 getterDescriptor.get = function () {
7222 var _a;
7223
7224 return (_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[flickingName]);
7225 };
7226 }
7227
7228 if (descriptor.set) {
7229 getterDescriptor.set = function () {
7230 var _a;
7231
7232 var args = [];
7233
7234 for (var _i = 0; _i < arguments.length; _i++) {
7235 args[_i] = arguments[_i];
7236 }
7237
7238 return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spreadArray([this[flickingName]], __read(args)));
7239 };
7240 }
7241
7242 Object.defineProperty(prototype, name, getterDescriptor);
7243 }
7244 });
7245 });
7246};
7247
7248var sync = (function (flicking, diffResult, rendered) {
7249 var renderer = flicking.renderer;
7250 var panels = renderer.panels;
7251
7252 if (diffResult.removed.length > 0) {
7253 var endIdx_1 = -1;
7254 var prevIdx_1 = -1;
7255 diffResult.removed.forEach(function (removedIdx) {
7256 if (endIdx_1 < 0) {
7257 endIdx_1 = removedIdx;
7258 }
7259
7260 if (prevIdx_1 >= 0 && removedIdx !== prevIdx_1 - 1) {
7261 batchRemove(renderer, prevIdx_1, endIdx_1 + 1);
7262 endIdx_1 = removedIdx;
7263 prevIdx_1 = removedIdx;
7264 } else {
7265 prevIdx_1 = removedIdx;
7266 }
7267 });
7268 batchRemove(renderer, prevIdx_1, endIdx_1 + 1);
7269 }
7270
7271 diffResult.ordered.forEach(function (_a) {
7272 var _b = __read(_a, 2),
7273 prevIdx = _b[0],
7274 newIdx = _b[1];
7275
7276 var prevPanel = panels[prevIdx];
7277 var indexDiff = newIdx - prevIdx;
7278
7279 if (indexDiff > 0) {
7280 var middlePanels = panels.slice(prevIdx + 1, newIdx + 1);
7281 prevPanel.increaseIndex(indexDiff);
7282 middlePanels.forEach(function (panel) {
7283 return panel.decreaseIndex(1);
7284 });
7285 } else {
7286 var middlePanels = panels.slice(newIdx, prevIdx);
7287 prevPanel.decreaseIndex(-indexDiff);
7288 middlePanels.forEach(function (panel) {
7289 return panel.increaseIndex(1);
7290 });
7291 } // Update position
7292
7293
7294 prevPanel.resize();
7295 });
7296
7297 if (diffResult.ordered.length > 0) {
7298 panels.sort(function (panel1, panel2) {
7299 return panel1.index - panel2.index;
7300 });
7301 }
7302
7303 if (diffResult.added.length > 0) {
7304 var startIdx_1 = -1;
7305 var prevIdx_2 = -1;
7306 diffResult.added.forEach(function (addedIdx, idx) {
7307 if (startIdx_1 < 0) {
7308 startIdx_1 = idx;
7309 }
7310
7311 if (prevIdx_2 >= 0 && addedIdx !== prevIdx_2 + 1) {
7312 batchInsert(renderer, diffResult, rendered, startIdx_1, idx + 1);
7313 startIdx_1 = -1;
7314 prevIdx_2 = -1;
7315 } else {
7316 prevIdx_2 = addedIdx;
7317 }
7318 });
7319
7320 if (startIdx_1 >= 0) {
7321 batchInsert(renderer, diffResult, rendered, startIdx_1);
7322 }
7323 }
7324});
7325
7326var batchInsert = function (renderer, diffResult, rendered, startIdx, endIdx) {
7327 renderer.batchInsert.apply(renderer, __spreadArray([], __read(diffResult.added.slice(startIdx, endIdx).map(function (index, elIdx) {
7328 return {
7329 index: index,
7330 elements: [rendered[elIdx + diffResult.prevList.length]]
7331 };
7332 }))));
7333};
7334
7335var batchRemove = function (renderer, startIdx, endIdx) {
7336 var removed = renderer.panels.slice(startIdx, endIdx);
7337 renderer.batchRemove({
7338 index: startIdx,
7339 deleteCount: removed.length
7340 });
7341};
7342
7343var getRenderingPanels = (function (flicking, diffResult) {
7344 var removedPanels = diffResult.removed.reduce(function (map, idx) {
7345 map[idx] = true;
7346 return map;
7347 }, {});
7348 var maintainedMap = diffResult.maintained.reduce(function (map, _a) {
7349 var _b = __read(_a, 2),
7350 prev = _b[0],
7351 current = _b[1];
7352
7353 map[prev] = current;
7354 return map;
7355 }, {});
7356 return __spreadArray(__spreadArray([], __read(flicking.panels.filter(function (panel) {
7357 return !removedPanels[panel.index];
7358 }) // Sort panels by position
7359 .sort(function (panel1, panel2) {
7360 return panel1.position + panel1.offset - (panel2.position + panel2.offset);
7361 }).map(function (panel) {
7362 return diffResult.list[maintainedMap[panel.index]];
7363 }))), __read(diffResult.added.map(function (idx) {
7364 return diffResult.list[idx];
7365 })));
7366});
7367
7368var getDefaultCameraTransform = (function (align, horizontal, firstPanelSize) {
7369 if (align === void 0) {
7370 align = ALIGN.CENTER;
7371 }
7372
7373 if (horizontal === void 0) {
7374 horizontal = true;
7375 }
7376
7377 var cameraAlign = getCameraAlign(align);
7378 var panelAlign = getPanelAlign(align);
7379 if (panelAlign == null) return "";
7380 var camPosition = "calc(" + cameraAlign + " - (" + (firstPanelSize || "0px") + " * " + panelAlign.percentage + ") - " + panelAlign.absolute + "px)";
7381 return horizontal ? "translate(" + camPosition + ")" : "translate(0, " + camPosition + ")";
7382});
7383
7384var getCameraAlign = function (align) {
7385 var alignVal = typeof align === "object" ? align.camera : align;
7386 return parseAlign(alignVal);
7387};
7388
7389var getPanelAlign = function (align) {
7390 var alignVal = typeof align === "object" ? align.panel : align;
7391 return parseArithmeticExpression(parseAlign(alignVal));
7392};
7393
7394var parseAlign = function (alignVal) {
7395 if (typeof alignVal === "number") {
7396 return alignVal + "px";
7397 }
7398
7399 switch (alignVal) {
7400 case ALIGN.CENTER:
7401 return "50%";
7402
7403 case ALIGN.NEXT:
7404 return "100%";
7405
7406 case ALIGN.PREV:
7407 return "0%";
7408
7409 default:
7410 return alignVal;
7411 }
7412};
7413
7414/*
7415 * Copyright (c) 2015 NAVER Corp.
7416 * egjs projects are licensed under the MIT license
7417 */
7418
7419export { ALIGN, AnchorPoint, AnimatingState, AxesController, BoundCamera, Camera, CircularCamera, Control, DIRECTION, DisabledState, DraggingState, CODE as ERROR_CODE, EVENTS, ElementPanel, ExternalPanel, ExternalRenderer, FlickingError, FreeControl, HoldingState, IdleState, LinearCamera, MOVE_TYPE, Panel, Renderer, SnapControl, State, StateMachine, StrictControl, VanillaRenderer, Viewport, Flicking as default, getDefaultCameraTransform, getRenderingPanels, sync, withFlickingMethods };
7420//# sourceMappingURL=flicking.esm.js.map