@egjs/flicking 4.3.1 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +1 -2
  2. package/declaration/Flicking.d.ts +30 -12
  3. package/declaration/camera/Camera.d.ts +29 -26
  4. package/declaration/camera/index.d.ts +2 -4
  5. package/declaration/camera/mode/BoundCameraMode.d.ts +13 -0
  6. package/declaration/camera/mode/CameraMode.d.ts +19 -0
  7. package/declaration/camera/mode/CircularCameraMode.d.ts +18 -0
  8. package/declaration/camera/mode/LinearCameraMode.d.ts +9 -0
  9. package/declaration/camera/mode/index.d.ts +6 -0
  10. package/declaration/const/error.d.ts +3 -1
  11. package/declaration/const/external.d.ts +9 -0
  12. package/declaration/core/AutoResizer.d.ts +13 -0
  13. package/declaration/core/VirtualManager.d.ts +37 -0
  14. package/declaration/core/index.d.ts +2 -1
  15. package/declaration/core/panel/Panel.d.ts +13 -7
  16. package/declaration/core/panel/VirtualPanel.d.ts +19 -0
  17. package/declaration/core/panel/index.d.ts +4 -4
  18. package/declaration/core/panel/provider/ElementProvider.d.ts +8 -0
  19. package/declaration/core/panel/provider/VanillaElementProvider.d.ts +12 -0
  20. package/declaration/core/panel/provider/VirtualElementProvider.d.ts +15 -0
  21. package/declaration/core/panel/provider/index.d.ts +5 -0
  22. package/declaration/index.d.ts +11 -1
  23. package/declaration/renderer/ExternalRenderer.d.ts +1 -1
  24. package/declaration/renderer/Renderer.d.ts +17 -12
  25. package/declaration/renderer/VanillaRenderer.d.ts +2 -7
  26. package/declaration/renderer/index.d.ts +1 -0
  27. package/declaration/renderer/strategy/NormalRenderingStrategy.d.ts +23 -0
  28. package/declaration/renderer/strategy/RenderingStrategy.d.ts +15 -0
  29. package/declaration/renderer/strategy/VirtualRenderingStrategy.d.ts +17 -0
  30. package/declaration/renderer/strategy/index.d.ts +5 -0
  31. package/declaration/type/external.d.ts +1 -3
  32. package/declaration/utils.d.ts +7 -1
  33. package/dist/flicking.esm.js +2526 -1475
  34. package/dist/flicking.esm.js.map +1 -1
  35. package/dist/flicking.js +2561 -1485
  36. package/dist/flicking.js.map +1 -1
  37. package/dist/flicking.min.js +2 -2
  38. package/dist/flicking.min.js.map +1 -1
  39. package/dist/flicking.pkgd.js +9006 -8312
  40. package/dist/flicking.pkgd.js.map +1 -1
  41. package/dist/flicking.pkgd.min.js +2 -2
  42. package/dist/flicking.pkgd.min.js.map +1 -1
  43. package/package.json +12 -24
  44. package/src/Flicking.ts +172 -45
  45. package/src/camera/Camera.ts +201 -93
  46. package/src/camera/index.ts +3 -7
  47. package/src/camera/{BoundCamera.ts → mode/BoundCameraMode.ts} +46 -43
  48. package/src/camera/mode/CameraMode.ts +77 -0
  49. package/src/camera/mode/CircularCameraMode.ts +171 -0
  50. package/src/camera/mode/LinearCameraMode.ts +23 -0
  51. package/src/camera/mode/index.ts +14 -0
  52. package/src/cfc/sync.ts +10 -5
  53. package/src/const/error.ts +6 -3
  54. package/src/const/external.ts +18 -0
  55. package/src/control/AxesController.ts +11 -6
  56. package/src/control/Control.ts +6 -6
  57. package/src/control/FreeControl.ts +2 -2
  58. package/src/control/SnapControl.ts +3 -3
  59. package/src/control/StrictControl.ts +2 -2
  60. package/src/core/AutoResizer.ts +81 -0
  61. package/src/core/Viewport.ts +4 -4
  62. package/src/core/VirtualManager.ts +188 -0
  63. package/src/core/index.ts +3 -1
  64. package/src/core/panel/Panel.ts +54 -34
  65. package/src/core/panel/VirtualPanel.ts +110 -0
  66. package/src/core/panel/index.ts +5 -7
  67. package/src/core/panel/provider/ElementProvider.ts +14 -0
  68. package/src/core/panel/provider/VanillaElementProvider.ts +45 -0
  69. package/src/core/panel/provider/VirtualElementProvider.ts +48 -0
  70. package/src/core/panel/provider/index.ts +16 -0
  71. package/src/index.ts +12 -1
  72. package/src/index.umd.ts +2 -0
  73. package/src/renderer/ExternalRenderer.ts +7 -7
  74. package/src/renderer/Renderer.ts +106 -65
  75. package/src/renderer/VanillaRenderer.ts +28 -86
  76. package/src/renderer/index.ts +2 -0
  77. package/src/renderer/strategy/NormalRenderingStrategy.ts +106 -0
  78. package/src/renderer/strategy/RenderingStrategy.ts +21 -0
  79. package/src/renderer/strategy/VirtualRenderingStrategy.ts +110 -0
  80. package/src/renderer/strategy/index.ts +17 -0
  81. package/src/utils.ts +36 -2
  82. package/declaration/camera/BoundCamera.d.ts +0 -9
  83. package/declaration/camera/CircularCamera.d.ts +0 -36
  84. package/declaration/camera/LinearCamera.d.ts +0 -5
  85. package/declaration/core/panel/ElementPanel.d.ts +0 -14
  86. package/declaration/core/panel/ExternalPanel.d.ts +0 -9
  87. package/declaration/exports.d.ts +0 -10
  88. package/src/camera/CircularCamera.ts +0 -269
  89. package/src/camera/LinearCamera.ts +0 -35
  90. package/src/core/panel/ElementPanel.ts +0 -52
  91. package/src/core/panel/ExternalPanel.ts +0 -32
  92. package/src/exports.ts +0 -16
@@ -0,0 +1,188 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import Flicking from "../Flicking";
6
+ import { range } from "../utils";
7
+ import { CLASS } from "../const/external";
8
+
9
+ import VirtualPanel from "./panel/VirtualPanel";
10
+
11
+ export interface VirtualOptions {
12
+ renderPanel: (panel: VirtualPanel, index: number) => string;
13
+ initialPanelCount: number;
14
+ cache?: boolean;
15
+ panelClass?: string;
16
+ }
17
+
18
+ /**
19
+ * A manager class to add / remove virtual panels
20
+ */
21
+ class VirtualManager {
22
+ private _flicking: Flicking;
23
+
24
+ private _renderPanel: (panel: VirtualPanel, index: number) => string;
25
+ private _initialPanelCount: number;
26
+ private _cache: boolean;
27
+ private _panelClass: string;
28
+
29
+ private _elements: Array<{ nativeElement: HTMLElement; visible: boolean }>;
30
+
31
+ public get elements() { return this._elements; }
32
+
33
+ // Options
34
+ /**
35
+ * A rendering function for the panel element's innerHTML
36
+ * @ko 패널 엘리먼트의 innerHTML을 렌더링하는 함수
37
+ * @type {function}
38
+ * @param {VirtualPanel} panel Instance of the panel<ko>패널 인스턴스</ko>
39
+ * @param {number} index Index of the panel<ko>패널 인덱스</ko>
40
+ * @default "() => {}"
41
+ */
42
+ public get renderPanel() { return this._renderPanel; }
43
+ /**
44
+ * Initial panel count to render
45
+ * @ko 최초로 렌더링할 패널의 개수
46
+ * @readonly
47
+ * @type {number}
48
+ * @default -1
49
+ */
50
+ public get initialPanelCount() { return this._initialPanelCount; }
51
+ /**
52
+ * Whether to cache rendered panel's innerHTML
53
+ * @ko 렌더링된 패널의 innerHTML 정보를 캐시할지 여부
54
+ * @type {boolean}
55
+ * @default false
56
+ */
57
+ public get cache() { return this._cache; }
58
+ /**
59
+ * The class name that will be applied to rendered panel elements
60
+ * @ko 렌더링되는 패널 엘리먼트에 적용될 클래스 이름
61
+ * @type {string}
62
+ * @default "flicking-panel"
63
+ */
64
+ public get panelClass() { return this._panelClass; }
65
+
66
+ public set renderPanel(val: VirtualOptions["renderPanel"]) {
67
+ this._renderPanel = val;
68
+ this._flicking.renderer.panels.forEach((panel: VirtualPanel) => panel.uncacheRenderResult());
69
+ }
70
+
71
+ public set cache(val: NonNullable<VirtualOptions["cache"]>) { this._cache = val; }
72
+ public set panelClass(val: NonNullable<VirtualOptions["panelClass"]>) { this._panelClass = val; }
73
+
74
+ public constructor(flicking: Flicking, options: VirtualOptions | null) {
75
+ this._flicking = flicking;
76
+
77
+ this._renderPanel = options?.renderPanel ?? (() => "");
78
+ this._initialPanelCount = options?.initialPanelCount ?? -1;
79
+ this._cache = options?.cache ?? false;
80
+ this._panelClass = options?.panelClass ?? CLASS.DEFAULT_VIRTUAL;
81
+
82
+ this._elements = [];
83
+ }
84
+
85
+ public init() {
86
+ const flicking = this._flicking;
87
+
88
+ if (!flicking.virtualEnabled) return;
89
+
90
+ if (!flicking.externalRenderer && !flicking.renderExternal) {
91
+ this._initVirtualElements();
92
+ }
93
+
94
+ const virtualElements = flicking.camera.children;
95
+ this._elements = virtualElements.map(el => ({ nativeElement: el, visible: true }));
96
+ }
97
+
98
+ public show(index: number) {
99
+ const el = this._elements[index];
100
+ const nativeEl = el.nativeElement;
101
+
102
+ el.visible = true;
103
+
104
+ if (nativeEl.style.display) {
105
+ nativeEl.style.display = "";
106
+ }
107
+ }
108
+
109
+ public hide(index: number) {
110
+ const el = this._elements[index];
111
+ const nativeEl = el.nativeElement;
112
+
113
+ el.visible = false;
114
+ nativeEl.style.display = "none";
115
+ }
116
+
117
+ /**
118
+ * Add new virtual panels at the end of the list
119
+ * @ko 새로운 가상 패널들을 리스트의 끝에 추가합니다
120
+ * @param {number} count The number of panels to add<ko>추가할 패널의 개수</ko>
121
+ * @returns {Array<VirtualPanel>} The new panels added<ko>새롭게 추가된 패널들</ko>
122
+ */
123
+ public append(count: number = 1): VirtualPanel[] {
124
+ const flicking = this._flicking;
125
+
126
+ return this.insert(flicking.panels.length, count);
127
+ }
128
+
129
+ /**
130
+ * Add new virtual panels at the start of the list
131
+ * @ko 새로운 가상 패널들을 리스트의 시작에 추가합니다
132
+ * @param {number} count The number of panels to add<ko>추가할 패널의 개수</ko>
133
+ * @returns {Array<VirtualPanel>} The new panels added<ko>새롭게 추가된 패널들</ko>
134
+ */
135
+ public prepend(count: number = 1): VirtualPanel[] {
136
+ return this.insert(0, count);
137
+ }
138
+
139
+ /**
140
+ * Add new virtual panels at the given index
141
+ * @ko 새로운 가상 패널들을 주어진 인덱스에 추가합니다
142
+ * @param {number} count The number of panels to add<ko>추가할 패널의 개수</ko>
143
+ * @returns {Array<VirtualPanel>} The new panels added<ko>새롭게 추가된 패널들</ko>
144
+ */
145
+ public insert(index: number, count: number = 1): VirtualPanel[] {
146
+ if (count <= 0) return [];
147
+
148
+ const flicking = this._flicking;
149
+
150
+ return flicking.renderer.batchInsert({ index, elements: range(count), hasDOMInElements: false }) as VirtualPanel[];
151
+ }
152
+
153
+ /**
154
+ * Remove panels at the given index
155
+ * @ko 주어진 인덱스에서 패널들을 삭제합니다
156
+ * @param {number} count The number of panels to remove<ko>삭제할 패널의 개수</ko>
157
+ * @returns {Array<VirtualPanel>} The panels removed<ko>삭제된 패널들</ko>
158
+ */
159
+ public remove(index: number, count: number): VirtualPanel[] {
160
+ if (count <= 0) return [];
161
+
162
+ const flicking = this._flicking;
163
+
164
+ return flicking.renderer.batchRemove({ index, deleteCount: count, hasDOMInElements: false }) as VirtualPanel[];
165
+ }
166
+
167
+ private _initVirtualElements() {
168
+ const flicking = this._flicking;
169
+ const cameraElement = flicking.camera.element;
170
+ const panelsPerView = flicking.panelsPerView;
171
+ const fragment = document.createDocumentFragment();
172
+
173
+ const newElements = range(panelsPerView + 1).map(idx => {
174
+ const panelEl = document.createElement("div");
175
+ panelEl.className = this._panelClass;
176
+ panelEl.dataset.elementIndex = idx.toString();
177
+ return panelEl;
178
+ });
179
+
180
+ newElements.forEach(el => {
181
+ fragment.appendChild(el);
182
+ });
183
+
184
+ cameraElement.appendChild(fragment);
185
+ }
186
+ }
187
+
188
+ export default VirtualManager;
package/src/core/index.ts CHANGED
@@ -5,11 +5,13 @@
5
5
  import Viewport from "./Viewport";
6
6
  import FlickingError from "./FlickingError";
7
7
  import AnchorPoint from "./AnchorPoint";
8
+ import VirtualManager from "./VirtualManager";
8
9
 
9
10
  export {
10
11
  Viewport,
11
12
  FlickingError,
12
- AnchorPoint
13
+ AnchorPoint,
14
+ VirtualManager
13
15
  };
14
16
 
15
17
  export * from "./panel";
@@ -3,25 +3,34 @@
3
3
  * egjs projects are licensed under the MIT license
4
4
  */
5
5
  import Flicking from "../../Flicking";
6
- import { getProgress, getStyle, isString, parseAlign } from "../../utils";
6
+ import { getProgress, getStyle, parseAlign, setSize } from "../../utils";
7
7
  import { ALIGN, DIRECTION } from "../../const/external";
8
8
  import { LiteralUnion, ValueOf } from "../../type/internal";
9
9
 
10
+ import ElementProvider from "./provider/ElementProvider";
11
+
10
12
  export interface PanelOptions {
11
13
  index: number;
12
14
  align: LiteralUnion<ValueOf<typeof ALIGN>> | number;
13
15
  flicking: Flicking;
16
+ elementProvider: ElementProvider;
14
17
  }
15
18
 
16
- abstract class Panel {
19
+ /**
20
+ * A slide data component that holds information of a single HTMLElement
21
+ * @ko 슬라이드 데이터 컴포넌트로, 단일 HTMLElement의 정보를 갖고 있습니다
22
+ */
23
+ class Panel {
17
24
  // Internal States
18
25
  protected _flicking: Flicking;
26
+ protected _elProvider: ElementProvider;
19
27
  protected _index: number;
20
28
  protected _pos: number;
21
29
  protected _size: number;
22
30
  protected _height: number;
23
31
  protected _margin: { prev: number; next: number };
24
32
  protected _alignPos: number; // Actual align pos
33
+ protected _rendered: boolean;
25
34
  protected _removed: boolean;
26
35
  protected _loading: boolean;
27
36
  protected _toggleDirection: ValueOf<typeof DIRECTION>;
@@ -38,7 +47,12 @@ abstract class Panel {
38
47
  * @type {HTMLElement}
39
48
  * @readonly
40
49
  */
41
- abstract get element(): HTMLElement;
50
+ public get element() { return this._elProvider.element; }
51
+ /**
52
+ * @internal
53
+ * @readonly
54
+ */
55
+ public get elementProvider() { return this._elProvider; }
42
56
  /**
43
57
  * Index of the panel
44
58
  * @ko 패널의 인덱스
@@ -104,19 +118,19 @@ abstract class Panel {
104
118
  */
105
119
  public get removed() { return this._removed; }
106
120
  /**
107
- * A value indicating whether the panel's image/video is not loaded and waiting for resize
108
- * @ko 패널 내부의 이미지/비디오가 아직 로드되지 않아 {@link Panel#resize resize}될 것인지를 나타내는 값
121
+ * A value indicating whether the panel's element is being rendered on the screen
122
+ * @ko 패널의 엘리먼트가 화면상에 렌더링되고있는지 여부를 나타내는 값
109
123
  * @type {boolean}
110
124
  * @readonly
111
125
  */
112
- public get loading() { return this._loading; }
126
+ public get rendered() { return this._rendered; }
113
127
  /**
114
- * A value indicating whether the panel's element is being rendered on the screen
115
- * @ko 패널의 엘리먼트가 화면상에 렌더링되고있는지 여부를 나타내는 값
128
+ * A value indicating whether the panel's image/video is not loaded and waiting for resize
129
+ * @ko 패널 내부의 이미지/비디오가 아직 로드되지 않아 {@link Panel#resize resize}될 것인지를 나타내는 값
116
130
  * @type {boolean}
117
131
  * @readonly
118
132
  */
119
- public abstract get rendered();
133
+ public get loading() { return this._loading; }
120
134
  /**
121
135
  * Panel element's range of the bounding box
122
136
  * @ko 패널 엘리먼트의 Bounding box 범위
@@ -247,18 +261,22 @@ abstract class Panel {
247
261
  * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>
248
262
  * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>
249
263
  * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>
264
+ * @param {Flicking} [options.elementProvider] A provider instance that redirects elements<ko>실제 엘리먼트를 반환하는 엘리먼트 공급자의 인스턴스</ko>
250
265
  */
251
266
  public constructor({
252
267
  index,
253
268
  align,
254
- flicking
269
+ flicking,
270
+ elementProvider
255
271
  }: PanelOptions) {
256
272
  this._index = index;
257
273
  this._flicking = flicking;
274
+ this._elProvider = elementProvider;
258
275
 
259
276
  this._align = align;
260
277
 
261
278
  this._removed = false;
279
+ this._rendered = true;
262
280
  this._loading = false;
263
281
  this._resetInternalStates();
264
282
  }
@@ -267,13 +285,19 @@ abstract class Panel {
267
285
  * Mark panel element to be appended on the camera element
268
286
  * @internal
269
287
  */
270
- public abstract markForShow();
288
+ public markForShow() {
289
+ this._rendered = true;
290
+ this._elProvider.show(this._flicking);
291
+ }
271
292
 
272
293
  /**
273
294
  * Mark panel element to be removed from the camera element
274
295
  * @internal
275
296
  */
276
- public abstract markForHide();
297
+ public markForHide() {
298
+ this._rendered = false;
299
+ this._elProvider.hide(this._flicking);
300
+ }
277
301
 
278
302
  /**
279
303
  * Update size of the panel
@@ -288,7 +312,6 @@ abstract class Panel {
288
312
  margin: { prev: number; next: number };
289
313
  }): this {
290
314
  const el = this.element;
291
- const elStyle = getStyle(el);
292
315
  const flicking = this._flicking;
293
316
  const horizontal = flicking.horizontal;
294
317
 
@@ -297,6 +320,8 @@ abstract class Panel {
297
320
  this._margin = { ...cached.margin };
298
321
  this._height = cached.height;
299
322
  } else {
323
+ const elStyle = getStyle(el);
324
+
300
325
  this._size = horizontal ? el.offsetWidth : el.offsetHeight;
301
326
  this._margin = horizontal
302
327
  ? {
@@ -324,29 +349,11 @@ abstract class Panel {
324
349
  * @chainable
325
350
  * @return {this}
326
351
  */
327
- public setSize({
328
- width,
329
- height
330
- }: Partial<{
352
+ public setSize(size: Partial<{
331
353
  width: number | string;
332
354
  height: number | string;
333
355
  }>): this {
334
- const el = this.element;
335
-
336
- if (width != null) {
337
- if (isString(width)) {
338
- el.style.width = width;
339
- } else {
340
- el.style.width = `${width}px`;
341
- }
342
- }
343
- if (height != null) {
344
- if (isString(height)) {
345
- el.style.height = height;
346
- } else {
347
- el.style.height = `${height}px`;
348
- }
349
- }
356
+ setSize(this.element, size);
350
357
 
351
358
  return this;
352
359
  }
@@ -383,7 +390,7 @@ abstract class Panel {
383
390
  }
384
391
 
385
392
  /**
386
- * Check whether the given range is fully included in this panel's area
393
+ * Check whether the given range is fully included in this panel's area (inclusive)
387
394
  * @ko 주어진 범위가 이 패널 내부에 완전히 포함되는지를 반환합니다
388
395
  * @param {number} min Minimum value of the range to check<ko>확인하고자 하는 최소 범위</ko>
389
396
  * @param {number} max Maximum value of the range to check<ko>확인하고자 하는 최대 범위</ko>
@@ -402,6 +409,19 @@ abstract class Panel {
402
409
  return max >= panelRange.min && min <= panelRange.max;
403
410
  }
404
411
 
412
+ /**
413
+ * Check whether the panel is visble in the given range (exclusive)
414
+ * @ko 주어진 범위 내에서 이 패널의 일부가 보여지는지를 반환합니다
415
+ * @param {number} min Minimum value of the range to check<ko>확인하고자 하는 최소 범위</ko>
416
+ * @param {number} max Maximum value of the range to check<ko>확인하고자 하는 최대 범위</ko>
417
+ * @returns {boolean} A Boolean value indicating whether the panel is visible<ko>해당 범위 내에서 패널을 볼 수 있는지 여부</ko>
418
+ */
419
+ public isVisibleOnRange(min: number, max: number): boolean {
420
+ const panelRange = this.range;
421
+
422
+ return max > panelRange.min && min < panelRange.max;
423
+ }
424
+
405
425
  /**
406
426
  * Move {@link Camera} to this panel
407
427
  * @ko {@link Camera}를 이 패널로 이동합니다
@@ -0,0 +1,110 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import { DIRECTION } from "../../const/external";
6
+ import { circulateIndex } from "../../utils";
7
+
8
+ import Panel, { PanelOptions } from "./Panel";
9
+ import VirtualElementProvider from "./provider/VirtualElementProvider";
10
+
11
+ interface VirtualPanelOptions extends PanelOptions {
12
+ elementProvider: VirtualElementProvider;
13
+ }
14
+
15
+ /**
16
+ * An slide data component that holds information of a single HTMLElement
17
+ * @ko 슬라이드 데이터 컴포넌트로, 단일 HTMLElement의 정보를 갖고 있습니다
18
+ */
19
+ class VirtualPanel extends Panel {
20
+ protected _elProvider: VirtualElementProvider;
21
+ protected _cachedInnerHTML: string | null;
22
+
23
+ /**
24
+ * `HTMLElement` that panel's referencing
25
+ * @ko 패널이 참조하고 있는 `HTMLElement`
26
+ * @type {HTMLElement}
27
+ * @readonly
28
+ */
29
+ public get element() { return this._elProvider.element; }
30
+
31
+ /**
32
+ * Cached innerHTML by the previous render function
33
+ * @ko 이전 렌더링에서 캐시된 innerHTML 정보
34
+ * @type {string|null}
35
+ * @readonly
36
+ */
37
+ public get cachedInnerHTML() { return this._cachedInnerHTML; }
38
+
39
+ /**
40
+ * An number for indexing which element it will be rendered on
41
+ * @ko 몇 번째 엘리먼트에 렌더링될 것인지를 나타내는 숫자
42
+ * @type {number}
43
+ * @readonly
44
+ */
45
+ public get elementIndex() {
46
+ const flicking = this._flicking;
47
+ const virtualElCount = flicking.panelsPerView + 1;
48
+ const panelCount = flicking.panelCount;
49
+ let index = this._index;
50
+
51
+ if (this._toggled) {
52
+ // To prevent element duplication
53
+ index = this._toggleDirection === DIRECTION.NEXT
54
+ ? index + panelCount
55
+ : index - panelCount;
56
+ }
57
+
58
+ return circulateIndex(index, virtualElCount);
59
+ }
60
+
61
+ /**
62
+ * @param {object} options An options object<ko>옵션 오브젝트</ko>
63
+ * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>
64
+ * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>
65
+ * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>
66
+ */
67
+ public constructor(options: VirtualPanelOptions) {
68
+ super(options);
69
+
70
+ options.elementProvider.init(this);
71
+ this._elProvider = options.elementProvider;
72
+ this._cachedInnerHTML = null;
73
+ }
74
+
75
+ public cacheRenderResult(result: string) {
76
+ this._cachedInnerHTML = result;
77
+ }
78
+
79
+ public uncacheRenderResult() {
80
+ this._cachedInnerHTML = null;
81
+ }
82
+
83
+ public render() {
84
+ const flicking = this._flicking;
85
+ const { renderPanel, cache } = flicking.virtual;
86
+
87
+ const element = this._elProvider.element;
88
+ const newInnerHTML = this._cachedInnerHTML || renderPanel(this, this._index);
89
+
90
+ if (newInnerHTML === element.innerHTML) return;
91
+
92
+ element.innerHTML = newInnerHTML;
93
+
94
+ if (cache) {
95
+ this.cacheRenderResult(newInnerHTML);
96
+ }
97
+ }
98
+
99
+ public increaseIndex(val: number) {
100
+ this.uncacheRenderResult();
101
+ return super.increaseIndex(val);
102
+ }
103
+
104
+ public decreaseIndex(val: number) {
105
+ this.uncacheRenderResult();
106
+ return super.decreaseIndex(val);
107
+ }
108
+ }
109
+
110
+ export default VirtualPanel;
@@ -3,17 +3,15 @@
3
3
  * egjs projects are licensed under the MIT license
4
4
  */
5
5
  import Panel, { PanelOptions } from "./Panel";
6
- import ElementPanel, { ElementPanelOptions } from "./ElementPanel";
7
- import ExternalPanel, { ExternalPanelOptions } from "./ExternalPanel";
6
+ import VirtualPanel from "./VirtualPanel";
7
+
8
+ export * from "./provider";
8
9
 
9
10
  export {
10
11
  Panel,
11
- ElementPanel,
12
- ExternalPanel
12
+ VirtualPanel
13
13
  };
14
14
 
15
15
  export type {
16
- PanelOptions,
17
- ElementPanelOptions,
18
- ExternalPanelOptions
16
+ PanelOptions
19
17
  };
@@ -0,0 +1,14 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import Flicking from "../../../Flicking";
6
+
7
+ interface ElementProvider {
8
+ element: HTMLElement;
9
+ rendered: boolean;
10
+ show(flicking: Flicking): void;
11
+ hide(flicking: Flicking): void;
12
+ }
13
+
14
+ export default ElementProvider;
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import Flicking from "../../../Flicking";
6
+
7
+ import ElementProvider from "./ElementProvider";
8
+
9
+ /**
10
+ * @internal
11
+ */
12
+ class VanillaElementProvider implements ElementProvider {
13
+ private _element: HTMLElement;
14
+ private _rendered: boolean;
15
+
16
+ public get element() { return this._element; }
17
+ public get rendered() { return this._rendered; }
18
+
19
+ public constructor(element: HTMLElement) {
20
+ this._element = element;
21
+ this._rendered = true;
22
+ }
23
+
24
+ public show(flicking: Flicking): void {
25
+ const el = this.element;
26
+ const cameraEl = flicking.camera.element;
27
+
28
+ if (el.parentElement !== cameraEl) {
29
+ cameraEl.appendChild(el);
30
+ this._rendered = true;
31
+ }
32
+ }
33
+
34
+ public hide(flicking: Flicking): void {
35
+ const el = this.element;
36
+ const cameraEl = flicking.camera.element;
37
+
38
+ if (el.parentElement === cameraEl) {
39
+ cameraEl.removeChild(el);
40
+ this._rendered = false;
41
+ }
42
+ }
43
+ }
44
+
45
+ export default VanillaElementProvider;
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+
6
+ import Flicking from "../../../Flicking";
7
+ import VirtualPanel from "../VirtualPanel";
8
+
9
+ import ElementProvider from "./ElementProvider";
10
+
11
+ /**
12
+ * @internal
13
+ */
14
+ class VirtualElementProvider implements ElementProvider {
15
+ private _flicking: Flicking;
16
+ private _panel: VirtualPanel;
17
+
18
+ public get element() { return this._virtualElement.nativeElement; }
19
+ public get rendered() { return this._virtualElement.visible; }
20
+
21
+ private get _virtualElement() {
22
+ const flicking = this._flicking;
23
+ const elIndex = this._panel.elementIndex;
24
+ const virtualElements = flicking.virtual.elements;
25
+
26
+ return virtualElements[elIndex];
27
+ }
28
+
29
+ public constructor(flicking: Flicking) {
30
+ this._flicking = flicking;
31
+ }
32
+
33
+ public init(panel: VirtualPanel) {
34
+ this._panel = panel;
35
+ }
36
+
37
+ public show(): void {
38
+ // DO_NOTHING
39
+ // Actual element visibility is controlled by VirtualManager
40
+ }
41
+
42
+ public hide(): void {
43
+ // DO_NOTHING
44
+ // Actual element visibility is controlled by VirtualManager
45
+ }
46
+ }
47
+
48
+ export default VirtualElementProvider;
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import ElementProvider from "./ElementProvider";
6
+ import VanillaElementProvider from "./VanillaElementProvider";
7
+ import VirtualElementProvider from "./VirtualElementProvider";
8
+
9
+ export {
10
+ VanillaElementProvider,
11
+ VirtualElementProvider
12
+ };
13
+
14
+ export type {
15
+ ElementProvider
16
+ };
package/src/index.ts CHANGED
@@ -3,7 +3,18 @@
3
3
  * egjs projects are licensed under the MIT license
4
4
  */
5
5
  import Flicking from "./Flicking";
6
+ import type { FlickingOptions, FlickingEvents } from "./Flicking";
6
7
 
7
- export * from "./exports";
8
+ export * from "./core";
9
+ export * from "./camera";
10
+ export * from "./control";
11
+ export * from "./renderer";
12
+ export * from "./const/external";
13
+ export * from "./cfc";
14
+ export * from "./utils";
15
+
16
+ export * from "./type/event";
17
+ export * from "./type/external";
18
+ export type { FlickingOptions, FlickingEvents };
8
19
 
9
20
  export default Flicking;