@egjs/flicking 4.2.4 → 4.4.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 (86) hide show
  1. package/README.md +1 -1
  2. package/declaration/Flicking.d.ts +24 -11
  3. package/declaration/camera/Camera.d.ts +5 -4
  4. package/declaration/camera/CircularCamera.d.ts +3 -2
  5. package/declaration/const/error.d.ts +3 -1
  6. package/declaration/const/external.d.ts +5 -0
  7. package/declaration/control/Control.d.ts +2 -2
  8. package/declaration/control/FreeControl.d.ts +1 -1
  9. package/declaration/control/StrictControl.d.ts +1 -1
  10. package/declaration/control/states/State.d.ts +2 -1
  11. package/declaration/core/AutoResizer.d.ts +13 -0
  12. package/declaration/core/VirtualManager.d.ts +37 -0
  13. package/declaration/core/index.d.ts +2 -1
  14. package/declaration/core/panel/ExternalPanel.d.ts +9 -5
  15. package/declaration/core/panel/Panel.d.ts +17 -10
  16. package/declaration/core/panel/VirtualPanel.d.ts +19 -0
  17. package/declaration/core/panel/index.d.ts +4 -3
  18. package/declaration/core/panel/provider/ElementProvider.d.ts +7 -0
  19. package/declaration/core/panel/provider/ExternalElementProvider.d.ts +8 -0
  20. package/declaration/core/panel/provider/VanillaElementProvider.d.ts +10 -0
  21. package/declaration/core/panel/provider/VirtualElementProvider.d.ts +13 -0
  22. package/declaration/core/panel/provider/index.d.ts +6 -0
  23. package/declaration/index.d.ts +11 -1
  24. package/declaration/renderer/ExternalRenderer.d.ts +1 -0
  25. package/declaration/renderer/Renderer.d.ts +18 -13
  26. package/declaration/renderer/VanillaRenderer.d.ts +2 -7
  27. package/declaration/renderer/index.d.ts +1 -0
  28. package/declaration/renderer/strategy/NormalRenderingStrategy.d.ts +25 -0
  29. package/declaration/renderer/strategy/RenderingStrategy.d.ts +15 -0
  30. package/declaration/renderer/strategy/VirtualRenderingStrategy.d.ts +17 -0
  31. package/declaration/renderer/strategy/index.d.ts +5 -0
  32. package/declaration/utils.d.ts +7 -1
  33. package/dist/flicking.esm.js +4649 -3767
  34. package/dist/flicking.esm.js.map +1 -1
  35. package/dist/flicking.js +4689 -3783
  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 +4359 -2062
  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 +2 -1
  44. package/src/Flicking.ts +148 -30
  45. package/src/camera/BoundCamera.ts +2 -2
  46. package/src/camera/Camera.ts +59 -36
  47. package/src/camera/CircularCamera.ts +54 -29
  48. package/src/camera/LinearCamera.ts +1 -1
  49. package/src/cfc/getRenderingPanels.ts +6 -1
  50. package/src/cfc/sync.ts +2 -2
  51. package/src/const/error.ts +6 -3
  52. package/src/const/external.ts +6 -0
  53. package/src/control/AxesController.ts +17 -9
  54. package/src/control/Control.ts +37 -39
  55. package/src/control/FreeControl.ts +4 -4
  56. package/src/control/SnapControl.ts +3 -3
  57. package/src/control/StrictControl.ts +4 -4
  58. package/src/control/states/AnimatingState.ts +6 -3
  59. package/src/control/states/State.ts +4 -2
  60. package/src/core/AutoResizer.ts +81 -0
  61. package/src/core/VirtualManager.ts +188 -0
  62. package/src/core/index.ts +3 -1
  63. package/src/core/panel/ExternalPanel.ts +23 -15
  64. package/src/core/panel/Panel.ts +68 -60
  65. package/src/core/panel/VirtualPanel.ts +110 -0
  66. package/src/core/panel/index.ts +5 -4
  67. package/src/core/panel/provider/ElementProvider.ts +13 -0
  68. package/src/core/panel/provider/ExternalElementProvider.ts +15 -0
  69. package/src/core/panel/provider/VanillaElementProvider.ts +40 -0
  70. package/src/core/panel/provider/VirtualElementProvider.ts +45 -0
  71. package/src/core/panel/provider/index.ts +18 -0
  72. package/src/index.ts +12 -1
  73. package/src/index.umd.ts +2 -0
  74. package/src/renderer/ExternalRenderer.ts +36 -4
  75. package/src/renderer/Renderer.ts +174 -69
  76. package/src/renderer/VanillaRenderer.ts +28 -86
  77. package/src/renderer/index.ts +2 -0
  78. package/src/renderer/strategy/NormalRenderingStrategy.ts +109 -0
  79. package/src/renderer/strategy/RenderingStrategy.ts +21 -0
  80. package/src/renderer/strategy/VirtualRenderingStrategy.ts +110 -0
  81. package/src/renderer/strategy/index.ts +17 -0
  82. package/src/utils.ts +36 -2
  83. package/declaration/core/panel/ElementPanel.d.ts +0 -14
  84. package/declaration/exports.d.ts +0 -10
  85. package/src/core/panel/ElementPanel.ts +0 -52
  86. package/src/exports.ts +0 -16
@@ -68,12 +68,38 @@ class CircularCamera extends Camera {
68
68
  if (!this._circularEnabled) return super.findAnchorIncludePosition(position);
69
69
 
70
70
  const range = this._range;
71
+ const anchors = this._anchors;
72
+ const rangeDiff = this.rangeDiff;
73
+ const anchorCount = anchors.length;
71
74
  const positionInRange = circulatePosition(position, range.min, range.max);
72
- const anchorInRange = super.findAnchorIncludePosition(positionInRange);
73
75
 
74
- if (!anchorInRange) return null;
76
+ let anchorInRange: AnchorPoint | null = super.findAnchorIncludePosition(positionInRange);
77
+
78
+ if (anchorCount > 0 && (position === range.min || position === range.max)) {
79
+ const possibleAnchors = [
80
+ anchorInRange,
81
+ new AnchorPoint({
82
+ index: 0,
83
+ position: anchors[0].position + rangeDiff,
84
+ panel: anchors[0].panel
85
+ }),
86
+ new AnchorPoint({
87
+ index: anchorCount - 1,
88
+ position: anchors[anchorCount - 1].position - rangeDiff,
89
+ panel: anchors[anchorCount - 1].panel
90
+ })
91
+ ].filter(anchor => !!anchor) as AnchorPoint[];
92
+
93
+ anchorInRange = possibleAnchors.reduce((nearest: AnchorPoint | null, anchor) => {
94
+ if (!nearest) return anchor;
95
+
96
+ return Math.abs(nearest.position - position) < Math.abs(anchor.position - position)
97
+ ? nearest
98
+ : anchor;
99
+ }, null);
100
+ }
75
101
 
76
- const rangeDiff = this.rangeDiff;
102
+ if (!anchorInRange) return null;
77
103
 
78
104
  if (position < range.min) {
79
105
  const loopCount = -Math.floor((range.min - position) / rangeDiff) - 1;
@@ -124,9 +150,9 @@ class CircularCamera extends Camera {
124
150
 
125
151
  // Check looped visible area for circular case
126
152
  if (visibleRange.min < range.min) {
127
- return visibleInCurrentRange || panel.includeRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff, false);
153
+ return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff);
128
154
  } else if (visibleRange.max > range.max) {
129
- return visibleInCurrentRange || panel.includeRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff, false);
155
+ return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff);
130
156
  }
131
157
 
132
158
  return visibleInCurrentRange;
@@ -142,7 +168,7 @@ class CircularCamera extends Camera {
142
168
  * @return {this}
143
169
  */
144
170
  public updateRange() {
145
- const flicking = getFlickingAttached(this._flicking, "Camera");
171
+ const flicking = getFlickingAttached(this._flicking);
146
172
  const renderer = flicking.renderer;
147
173
 
148
174
  const panels = renderer.panels;
@@ -171,39 +197,47 @@ class CircularCamera extends Camera {
171
197
  this._range = { min: firstPanel.position, max: lastPanel.position };
172
198
  }
173
199
 
174
- this._updateCircularOffset();
200
+ this.updateOffset();
175
201
 
176
202
  return this;
177
203
  }
178
204
 
179
- public async lookAt(pos: number) {
180
- const flicking = getFlickingAttached(this._flicking, "Camera");
205
+ public updateOffset() {
206
+ this._updateCircularOffset();
207
+
208
+ return super.updateOffset();
209
+ }
210
+
211
+ public lookAt(pos: number) {
212
+ const flicking = getFlickingAttached(this._flicking);
181
213
  const prevPos = this._position;
182
214
 
183
- if (pos === prevPos) return await super.lookAt(pos);
215
+ if (pos === prevPos) return super.lookAt(pos);
184
216
 
185
217
  const panels = flicking.renderer.panels;
186
218
  const toggled = panels.map(panel => panel.toggle(prevPos, pos));
187
219
 
188
220
  this._position = pos;
221
+ super.lookAt(pos);
189
222
 
190
223
  if (toggled.some(isToggled => isToggled)) {
191
- this._updateCircularOffset();
192
- await flicking.renderer.render();
224
+ void flicking.renderer.render().then(() => {
225
+ this.updateOffset();
226
+ });
193
227
  }
194
-
195
- return await super.lookAt(pos);
196
228
  }
197
229
 
198
- protected _applyTransform(): void {
230
+ public applyTransform(): this {
199
231
  const el = this._el;
200
- const flicking = getFlickingAttached(this._flicking, "Camera");
232
+ const flicking = getFlickingAttached(this._flicking);
201
233
 
202
234
  const actualPosition = this._position - this._alignPos - this._offset + this._circularOffset;
203
235
 
204
236
  el.style[this._transform] = flicking.horizontal
205
237
  ? `translate(${-actualPosition}px)`
206
238
  : `translate(0, ${-actualPosition}px)`;
239
+
240
+ return this;
207
241
  }
208
242
 
209
243
  protected _resetInternalValues() {
@@ -222,19 +256,10 @@ class CircularCamera extends Camera {
222
256
  return;
223
257
  }
224
258
 
225
- const flicking = getFlickingAttached(this._flicking, "Camera");
226
- const toggledPrev: Panel[] = [];
227
- const toggledNext: Panel[] = [];
228
-
229
- flicking.panels
230
- .filter(panel => panel.toggled)
231
- .forEach(panel => {
232
- if (panel.toggleDirection === DIRECTION.PREV) {
233
- toggledPrev.push(panel);
234
- } else {
235
- toggledNext.push(panel);
236
- }
237
- });
259
+ const flicking = getFlickingAttached(this._flicking);
260
+ const toggled = flicking.panels.filter(panel => panel.toggled);
261
+ const toggledPrev = toggled.filter(panel => panel.toggleDirection === DIRECTION.PREV);
262
+ const toggledNext = toggled.filter(panel => panel.toggleDirection === DIRECTION.NEXT);
238
263
 
239
264
  this._circularOffset = this._calcPanelAreaSum(toggledPrev) - this._calcPanelAreaSum(toggledNext);
240
265
  }
@@ -21,7 +21,7 @@ class LinearCamera extends Camera {
21
21
  * @return {this}
22
22
  */
23
23
  public updateRange() {
24
- const flicking = getFlickingAttached(this._flicking, "Camera");
24
+ const flicking = getFlickingAttached(this._flicking);
25
25
  const renderer = flicking.renderer;
26
26
 
27
27
  const firstPanel = renderer.getPanel(0);
@@ -8,12 +8,17 @@ export default <T>(flicking: Flicking, diffResult: DiffResult<T>) => {
8
8
  return map;
9
9
  }, {});
10
10
 
11
+ const maintainedMap = diffResult.maintained.reduce((map, [prev, current]) => {
12
+ map[prev] = current;
13
+ return map;
14
+ }, {});
15
+
11
16
  return [
12
17
  ...flicking.panels
13
18
  .filter(panel => !removedPanels[panel.index])
14
19
  // Sort panels by position
15
20
  .sort((panel1, panel2) => (panel1.position + panel1.offset) - (panel2.position + panel2.offset))
16
- .map(panel => diffResult.prevList[panel.index]),
21
+ .map(panel => diffResult.list[maintainedMap[panel.index]]),
17
22
  ...diffResult.added.map(idx => diffResult.list[idx])
18
23
  ];
19
24
  };
package/src/cfc/sync.ts CHANGED
@@ -79,13 +79,13 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
79
79
 
80
80
  const batchInsert = (renderer: Renderer, diffResult: DiffResult<any>, rendered: any[], startIdx: number, endIdx?: number) => {
81
81
  renderer.batchInsert(
82
- ...diffResult.added.slice(startIdx, endIdx).map((index, elIdx) => ({ index, elements: [rendered[elIdx + diffResult.prevList.length]] }))
82
+ ...diffResult.added.slice(startIdx, endIdx).map((index, elIdx) => ({ index, elements: [rendered[elIdx + diffResult.prevList.length]], hasDOMInElements: false }))
83
83
  );
84
84
  };
85
85
 
86
86
  const batchRemove = (renderer: Renderer, startIdx: number, endIdx?: number) => {
87
87
  const removed = renderer.panels.slice(startIdx, endIdx);
88
88
 
89
- renderer.batchRemove({ index: startIdx, deleteCount: removed.length });
89
+ renderer.batchRemove({ index: startIdx, deleteCount: removed.length, hasDOMInElements: false });
90
90
  };
91
91
 
@@ -25,6 +25,7 @@
25
25
  * <ko>프레임워크(React, Angular, Vue ...)에서 사용 불가능한 메소드를 호출했을 경우</ko>
26
26
  * @property {number} NOT_INITIALIZED When the {@link Flicking#init} is not called before but is needed<ko>{@link Flicking#init}의 호출이 필요하나, 아직 호출되지 않았을 경우</ko>
27
27
  * @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>
28
+ * @property {number} NOT_ALLOWED_IN_VIRTUAL When the non-allowed method is called while the virtual option is enabled<ko>virtual 옵션이 활성화된 상태에서 사용 불가능한 메소드가 호출되었을 경우</ko>
28
29
  */
29
30
  export const CODE = {
30
31
  WRONG_TYPE: 0,
@@ -40,14 +41,15 @@ export const CODE = {
40
41
  ANIMATION_ALREADY_PLAYING: 10,
41
42
  NOT_ALLOWED_IN_FRAMEWORK: 11,
42
43
  NOT_INITIALIZED: 12,
43
- NO_ACTIVE: 13
44
+ NO_ACTIVE: 13,
45
+ NOT_ALLOWED_IN_VIRTUAL: 14
44
46
  } as const;
45
47
 
46
48
  export const MESSAGE = {
47
49
  WRONG_TYPE: (wrongVal: any, correctTypes: string[]) => `${wrongVal}(${typeof wrongVal}) is not a ${correctTypes.map(type => `"${type}"`).join(" or ")}.`,
48
50
  ELEMENT_NOT_FOUND: (selector: string) => `Element with selector "${selector}" not found.`,
49
51
  VAL_MUST_NOT_NULL: (val: any, name: string) => `${name} should be provided. Given: ${val}`,
50
- NOT_ATTACHED_TO_FLICKING: (name: string) => `${name} is not attached to the Flicking instance. "init()" should be called first.`,
52
+ NOT_ATTACHED_TO_FLICKING: "This module is not attached to the Flicking instance. \"init()\" should be called first.",
51
53
  WRONG_OPTION: (optionName: string, val: any) => `Option "${optionName}" is not in correct format, given: ${val}`,
52
54
  INDEX_OUT_OF_RANGE: (val: number, min: number, max: number) => `Index "${val}" is out of range: should be between ${min} and ${max}.`,
53
55
  POSITION_NOT_REACHABLE: (position: number) => `Position "${position}" is not reachable.`,
@@ -57,5 +59,6 @@ export const MESSAGE = {
57
59
  ANIMATION_ALREADY_PLAYING: "Animation is already playing.",
58
60
  NOT_ALLOWED_IN_FRAMEWORK: "This behavior is not allowed in the frameworks like React, Vue, or Angular.",
59
61
  NOT_INITIALIZED: "Flicking is not initialized yet, call init() first.",
60
- NO_ACTIVE: "There's no active panel that Flicking has selected. This may be due to the absence of any panels."
62
+ NO_ACTIVE: "There's no active panel that Flicking has selected. This may be due to the absence of any panels.",
63
+ NOT_ALLOWED_IN_VIRTUAL: "This behavior is not allowed when the virtual option is enabled"
61
64
  } as const;
@@ -92,3 +92,9 @@ export const MOVE_TYPE = {
92
92
  FREE_SCROLL: "freeScroll",
93
93
  STRICT: "strict"
94
94
  } as const;
95
+
96
+ export const CLASS = {
97
+ VERTICAL: "vertical",
98
+ HIDDEN: "flicking-hidden",
99
+ DEFAULT_VIRTUAL: "flicking-panel"
100
+ };
@@ -167,9 +167,11 @@ class AxesController {
167
167
  * @return {void}
168
168
  */
169
169
  public destroy(): void {
170
- this.removePreventClickHandler();
170
+ if (this._axes) {
171
+ this.removePreventClickHandler();
172
+ this._axes.destroy();
173
+ }
171
174
 
172
- this._axes?.destroy();
173
175
  this._panInput?.destroy();
174
176
 
175
177
  this._resetInternalValues();
@@ -209,7 +211,7 @@ class AxesController {
209
211
  * @return {this}
210
212
  */
211
213
  public update(controlParams: ControlParams): this {
212
- const flicking = getFlickingAttached(this._flicking, "Control");
214
+ const flicking = getFlickingAttached(this._flicking);
213
215
  const camera = flicking.camera;
214
216
  const axes = this._axes!;
215
217
  const axis = axes.axis[AXES.POSITION_KEY];
@@ -229,7 +231,7 @@ class AxesController {
229
231
  * @return {this}
230
232
  */
231
233
  public addPreventClickHandler(): this {
232
- const flicking = getFlickingAttached(this._flicking, "Control");
234
+ const flicking = getFlickingAttached(this._flicking);
233
235
  const axes = this._axes!;
234
236
  const cameraEl = flicking.camera.element;
235
237
 
@@ -246,7 +248,7 @@ class AxesController {
246
248
  * @return {this}
247
249
  */
248
250
  public removePreventClickHandler(): this {
249
- const flicking = getFlickingAttached(this._flicking, "Control");
251
+ const flicking = getFlickingAttached(this._flicking);
250
252
  const axes = this._axes!;
251
253
  const cameraEl = flicking.camera.element;
252
254
 
@@ -280,17 +282,23 @@ class AxesController {
280
282
  */
281
283
  public animateTo(position: number, duration: number, axesEvent?: OnRelease): Promise<void> {
282
284
  const axes = this._axes;
285
+ const state = this._stateMachine.state;
283
286
 
284
287
  if (!axes) {
285
- return Promise.reject(new FlickingError(ERROR.MESSAGE.NOT_ATTACHED_TO_FLICKING("Control"), ERROR.CODE.NOT_ATTACHED_TO_FLICKING));
288
+ return Promise.reject(new FlickingError(ERROR.MESSAGE.NOT_ATTACHED_TO_FLICKING, ERROR.CODE.NOT_ATTACHED_TO_FLICKING));
286
289
  }
287
290
 
288
291
  const startPos = axes.get([AXES.POSITION_KEY])[AXES.POSITION_KEY];
289
292
 
290
293
  if (startPos === position) {
291
- const flicking = getFlickingAttached(this._flicking, "Control");
294
+ const flicking = getFlickingAttached(this._flicking);
295
+
296
+ flicking.camera.lookAt(position);
292
297
 
293
- return flicking.camera.lookAt(position);
298
+ if (state.targetPanel) {
299
+ flicking.control.setActive(state.targetPanel, flicking.control.activePanel, axesEvent?.isTrusted ?? false);
300
+ }
301
+ return Promise.resolve();
294
302
  }
295
303
 
296
304
  this._animatingContext = {
@@ -314,7 +322,7 @@ class AxesController {
314
322
  };
315
323
 
316
324
  if (duration === 0) {
317
- const flicking = getFlickingAttached(this._flicking, "Control");
325
+ const flicking = getFlickingAttached(this._flicking);
318
326
  const camera = flicking.camera;
319
327
 
320
328
  animate();
@@ -14,8 +14,6 @@ import * as ERROR from "../const/error";
14
14
  import { getDirection, getFlickingAttached } from "../utils";
15
15
  import { ValueOf } from "../type/internal";
16
16
 
17
- import { STATE_TYPE } from "./states/State";
18
-
19
17
  /**
20
18
  * A component that manages inputs and animation of Flicking
21
19
  * @ko Flicking의 입력 장치 & 애니메이션을 담당하는 컴포넌트
@@ -173,13 +171,13 @@ abstract class Control {
173
171
  * @chainable
174
172
  * @return {Promise<void>}
175
173
  */
176
- public async updatePosition(_progressInPanel: number): Promise<void> { // eslint-disable-line @typescript-eslint/no-unused-vars
177
- const flicking = getFlickingAttached(this._flicking, "Control");
174
+ public updatePosition(_progressInPanel: number): void { // eslint-disable-line @typescript-eslint/no-unused-vars
175
+ const flicking = getFlickingAttached(this._flicking);
178
176
  const camera = flicking.camera;
179
177
  const activePanel = this._activePanel;
180
178
 
181
179
  if (activePanel) {
182
- await camera.lookAt(camera.clampToReachablePosition(activePanel.position));
180
+ camera.lookAt(camera.clampToReachablePosition(activePanel.position));
183
181
  }
184
182
  }
185
183
 
@@ -190,7 +188,7 @@ abstract class Control {
190
188
  * @return {this}
191
189
  */
192
190
  public updateInput(): this {
193
- const flicking = getFlickingAttached(this._flicking, "Control");
191
+ const flicking = getFlickingAttached(this._flicking);
194
192
  const camera = flicking.camera;
195
193
 
196
194
  this._controller.update(camera.controlParams);
@@ -257,7 +255,7 @@ abstract class Control {
257
255
  direction?: ValueOf<typeof DIRECTION>;
258
256
  axesEvent?: OnRelease;
259
257
  }) {
260
- const flicking = getFlickingAttached(this._flicking, "Control");
258
+ const flicking = getFlickingAttached(this._flicking);
261
259
  const camera = flicking.camera;
262
260
 
263
261
  let position = panel.position;
@@ -297,8 +295,34 @@ abstract class Control {
297
295
  return this._animateToPosition({ position, duration, newActivePanel: panel, axesEvent });
298
296
  }
299
297
 
298
+ /**
299
+ * @internal
300
+ */
301
+ public setActive(newActivePanel: Panel, prevActivePanel: Panel | null, isTrusted: boolean) {
302
+ const flicking = getFlickingAttached(this._flicking);
303
+
304
+ this._activePanel = newActivePanel;
305
+
306
+ flicking.camera.updateAdaptiveHeight();
307
+
308
+ if (newActivePanel !== prevActivePanel) {
309
+ flicking.trigger(new ComponentEvent(EVENTS.CHANGED, {
310
+ index: newActivePanel.index,
311
+ panel: newActivePanel,
312
+ prevIndex: prevActivePanel?.index ?? -1,
313
+ prevPanel: prevActivePanel,
314
+ isTrusted,
315
+ direction: prevActivePanel ? getDirection(prevActivePanel.position, newActivePanel.position) : DIRECTION.NONE
316
+ }));
317
+ } else {
318
+ flicking.trigger(new ComponentEvent(EVENTS.RESTORED, {
319
+ isTrusted
320
+ }));
321
+ }
322
+ }
323
+
300
324
  protected _triggerIndexChangeEvent(panel: Panel, position: number, axesEvent?: OnRelease): void {
301
- const flicking = getFlickingAttached(this._flicking, "Control");
325
+ const flicking = getFlickingAttached(this._flicking);
302
326
  const triggeringEvent = panel !== this._activePanel ? EVENTS.WILL_CHANGE : EVENTS.WILL_RESTORE;
303
327
  const camera = flicking.camera;
304
328
  const activePanel = this._activePanel;
@@ -327,18 +351,16 @@ abstract class Control {
327
351
  newActivePanel: Panel;
328
352
  axesEvent?: OnRelease;
329
353
  }) {
330
- const flicking = getFlickingAttached(this._flicking, "Control");
331
- const currentPanel = this._activePanel;
354
+ const flicking = getFlickingAttached(this._flicking);
332
355
  const animate = () => this._controller.animateTo(position, duration, axesEvent);
333
- const isTrusted = axesEvent?.isTrusted || false;
356
+ const state = this._controller.state;
357
+
358
+ state.targetPanel = newActivePanel;
334
359
 
335
360
  if (duration <= 0) {
336
- const animation = animate();
337
- this._setActive(newActivePanel, currentPanel, isTrusted);
338
- return animation;
361
+ return animate();
339
362
  } else {
340
363
  return animate().then(async () => {
341
- this._setActive(newActivePanel, currentPanel, isTrusted);
342
364
  await flicking.renderer.render();
343
365
  }).catch(err => {
344
366
  if (axesEvent && err instanceof FlickingError && err.code === ERROR.CODE.ANIMATION_INTERRUPTED) return;
@@ -346,30 +368,6 @@ abstract class Control {
346
368
  });
347
369
  }
348
370
  }
349
-
350
- protected _setActive(newActivePanel: Panel, prevActivePanel: Panel | null, isTrusted: boolean) {
351
- const flicking = getFlickingAttached(this._flicking, "Control");
352
-
353
- this._activePanel = newActivePanel;
354
-
355
- flicking.camera.updateAdaptiveHeight();
356
- this._controller.stateMachine.transitTo(STATE_TYPE.IDLE);
357
-
358
- if (newActivePanel !== prevActivePanel) {
359
- flicking.trigger(new ComponentEvent(EVENTS.CHANGED, {
360
- index: newActivePanel.index,
361
- panel: newActivePanel,
362
- prevIndex: prevActivePanel?.index ?? -1,
363
- prevPanel: prevActivePanel,
364
- isTrusted,
365
- direction: prevActivePanel ? getDirection(prevActivePanel.position, newActivePanel.position) : DIRECTION.NONE
366
- }));
367
- } else {
368
- flicking.trigger(new ComponentEvent(EVENTS.RESTORED, {
369
- isTrusted
370
- }));
371
- }
372
- }
373
371
  }
374
372
 
375
373
  export default Control;
@@ -57,8 +57,8 @@ class FreeControl extends Control {
57
57
  * @chainable
58
58
  * @return {Promise<void>}
59
59
  */
60
- public async updatePosition(progressInPanel: number): Promise<void> {
61
- const flicking = getFlickingAttached(this._flicking, "Control");
60
+ public updatePosition(progressInPanel: number): void {
61
+ const flicking = getFlickingAttached(this._flicking);
62
62
  const camera = flicking.camera;
63
63
  const activePanel = this._activePanel;
64
64
 
@@ -66,7 +66,7 @@ class FreeControl extends Control {
66
66
  const panelRange = activePanel.range;
67
67
  const newPosition = panelRange.min + (panelRange.max - panelRange.min) * progressInPanel;
68
68
 
69
- await camera.lookAt(camera.clampToReachablePosition(newPosition));
69
+ camera.lookAt(camera.clampToReachablePosition(newPosition));
70
70
  }
71
71
  }
72
72
 
@@ -107,7 +107,7 @@ class FreeControl extends Control {
107
107
  * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
108
108
  */
109
109
  public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
110
- const flicking = getFlickingAttached(this._flicking, "Control");
110
+ const flicking = getFlickingAttached(this._flicking);
111
111
 
112
112
  const camera = flicking.camera;
113
113
  const targetPos = camera.clampToReachablePosition(position);
@@ -85,7 +85,7 @@ class SnapControl extends Control {
85
85
  * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
86
86
  */
87
87
  public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
88
- const flicking = getFlickingAttached(this._flicking, "Control");
88
+ const flicking = getFlickingAttached(this._flicking);
89
89
  const camera = flicking.camera;
90
90
  const activeAnchor = camera.findActiveAnchor();
91
91
  const anchorAtCamera = camera.findNearestAnchor(camera.position);
@@ -128,7 +128,7 @@ class SnapControl extends Control {
128
128
  }
129
129
 
130
130
  private _findSnappedAnchor(position: number, anchorAtCamera: AnchorPoint): AnchorPoint {
131
- const flicking = getFlickingAttached(this._flicking, "Control");
131
+ const flicking = getFlickingAttached(this._flicking);
132
132
  const camera = flicking.camera;
133
133
  const count = this._count;
134
134
 
@@ -191,7 +191,7 @@ class SnapControl extends Control {
191
191
  }
192
192
 
193
193
  private _findAdjacentAnchor(posDelta: number, anchorAtCamera: AnchorPoint): AnchorPoint {
194
- const flicking = getFlickingAttached(this._flicking, "Control");
194
+ const flicking = getFlickingAttached(this._flicking);
195
195
  const camera = flicking.camera;
196
196
  const adjacentAnchor = (posDelta > 0 ? camera.getNextAnchor(anchorAtCamera) : camera.getPrevAnchor(anchorAtCamera)) ?? anchorAtCamera;
197
197
 
@@ -66,7 +66,7 @@ class StrictControl extends Control {
66
66
  * @return {this}
67
67
  */
68
68
  public updateInput(): this {
69
- const flicking = getFlickingAttached(this._flicking, "Control");
69
+ const flicking = getFlickingAttached(this._flicking);
70
70
  const camera = flicking.camera;
71
71
  const renderer = flicking.renderer;
72
72
  const controller = this._controller;
@@ -178,7 +178,7 @@ class StrictControl extends Control {
178
178
  * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
179
179
  */
180
180
  public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
181
- const flicking = getFlickingAttached(this._flicking, "Control");
181
+ const flicking = getFlickingAttached(this._flicking);
182
182
  const camera = flicking.camera;
183
183
  const activePanel = this._activePanel;
184
184
  const axesRange = this._controller.range;
@@ -239,8 +239,8 @@ class StrictControl extends Control {
239
239
  });
240
240
  }
241
241
 
242
- protected _setActive = (newActivePanel: Panel, prevActivePanel: Panel | null, isTrusted: boolean) => {
243
- super._setActive(newActivePanel, prevActivePanel, isTrusted);
242
+ public setActive = (newActivePanel: Panel, prevActivePanel: Panel | null, isTrusted: boolean) => {
243
+ super.setActive(newActivePanel, prevActivePanel, isTrusted);
244
244
  this.updateInput();
245
245
  };
246
246
 
@@ -51,18 +51,21 @@ class AnimatingState extends State {
51
51
  }
52
52
 
53
53
  public onFinish(ctx: Parameters<State["onFinish"]>[0]) {
54
- const { flicking, axesEvent } = ctx;
54
+ const { flicking, axesEvent, transitTo } = ctx;
55
55
 
56
- const controller = flicking.control.controller;
56
+ const control = flicking.control;
57
+ const controller = control.controller;
57
58
  const animatingContext = controller.animatingContext;
58
59
 
60
+ transitTo(STATE_TYPE.IDLE);
61
+
59
62
  flicking.trigger(new ComponentEvent(EVENTS.MOVE_END, {
60
63
  isTrusted: axesEvent.isTrusted,
61
64
  direction: getDirection(animatingContext.start, animatingContext.end),
62
65
  axesEvent
63
66
  }));
64
67
 
65
- // transitTo is controlled by class Control because of order
68
+ control.setActive(this._targetPanel!, control.activePanel, axesEvent.isTrusted);
66
69
  }
67
70
  }
68
71
 
@@ -60,6 +60,8 @@ abstract class State {
60
60
  */
61
61
  public get targetPanel() { return this._targetPanel; }
62
62
 
63
+ public set targetPanel(val: Panel | null) { this._targetPanel = val; }
64
+
63
65
  /**
64
66
  * An callback which is called when state has changed to this state
65
67
  * @ko 현재 상태로 돌입했을때 호출되는 콜백 함수
@@ -177,7 +179,7 @@ abstract class State {
177
179
  ? circulatePosition(position, camera.range.min, camera.range.max)
178
180
  : position;
179
181
 
180
- void camera.lookAt(newPosition);
182
+ camera.lookAt(newPosition);
181
183
 
182
184
  const moveEvent = new ComponentEvent(EVENTS.MOVE, {
183
185
  isTrusted: axesEvent.isTrusted,
@@ -190,7 +192,7 @@ abstract class State {
190
192
 
191
193
  if (moveEvent.isCanceled()) {
192
194
  // Return to previous position
193
- void camera.lookAt(prevPosition);
195
+ camera.lookAt(prevPosition);
194
196
  transitTo(STATE_TYPE.DISABLED);
195
197
  }
196
198
  }
@@ -0,0 +1,81 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import Flicking from "../Flicking";
6
+
7
+ class AutoResizer {
8
+ private _flicking: Flicking;
9
+ private _enabled: boolean;
10
+ private _resizeObserver: ResizeObserver | null;
11
+
12
+ public get enabled() { return this._enabled; }
13
+
14
+ public constructor(flicking: Flicking) {
15
+ this._flicking = flicking;
16
+ this._enabled = false;
17
+ this._resizeObserver = null;
18
+ }
19
+
20
+ public enable(): this {
21
+ const flicking = this._flicking;
22
+ const viewport = flicking.viewport;
23
+
24
+ if (this._enabled) {
25
+ this.disable();
26
+ }
27
+
28
+ if (flicking.useResizeObserver && !!window.ResizeObserver) {
29
+ const viewportSizeNot0 = viewport.width !== 0 || viewport.height !== 0;
30
+
31
+ const resizeObserver = viewportSizeNot0
32
+ ? new ResizeObserver(this._skipFirstResize)
33
+ : new ResizeObserver(this._onResize);
34
+
35
+ resizeObserver.observe(flicking.viewport.element);
36
+
37
+ this._resizeObserver = resizeObserver;
38
+ } else {
39
+ window.addEventListener("resize", this._onResize);
40
+ }
41
+
42
+ this._enabled = true;
43
+
44
+ return this;
45
+ }
46
+
47
+ public disable(): this {
48
+ if (!this._enabled) return this;
49
+
50
+ const resizeObserver = this._resizeObserver;
51
+ if (resizeObserver) {
52
+ resizeObserver.disconnect();
53
+ this._resizeObserver = null;
54
+ } else {
55
+ window.removeEventListener("resize", this._onResize);
56
+ }
57
+
58
+ this._enabled = false;
59
+
60
+ return this;
61
+ }
62
+
63
+ private _onResize = () => {
64
+ void this._flicking.resize();
65
+ };
66
+
67
+ // eslint-disable-next-line @typescript-eslint/member-ordering
68
+ private _skipFirstResize = (() => {
69
+ let isFirstResize = true;
70
+
71
+ return (() => {
72
+ if (isFirstResize) {
73
+ isFirstResize = false;
74
+ return;
75
+ }
76
+ this._onResize();
77
+ });
78
+ })();
79
+ }
80
+
81
+ export default AutoResizer;