UNPKG

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