@egjs/flicking 4.6.1 → 4.7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@egjs/flicking",
3
- "version": "4.6.1",
3
+ "version": "4.7.0",
4
4
  "description": "Everyday 30 million people experience. It's reliable, flexible and extendable carousel.",
5
5
  "main": "dist/flicking.js",
6
6
  "module": "dist/flicking.esm.js",
@@ -33,6 +33,7 @@
33
33
  "demo:prebuild-version": "cpx 'dist/**/*' docs/build/release/$npm_package_version/dist --clean",
34
34
  "demo:prebuild-latest": "cpx 'dist/**/*' docs/build/release/latest/dist --clean",
35
35
  "demo:deploy": "npm run docs:release && npm run build && npm run demo:prebuild-version && npm run demo:prebuild-latest && gh-pages -d docs/build/ --add --remote upstream",
36
+ "demo:deploy-origin": "npm run docs:release && npm run build && npm run demo:prebuild-version && npm run demo:prebuild-latest && gh-pages -d docs/build/ --add --remote origin",
36
37
  "release": "release-helper upstream",
37
38
  "changelog": "node ./config/changelog.js",
38
39
  "coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
@@ -135,7 +136,7 @@
135
136
  "typescript-transform-paths": "^2.2.3"
136
137
  },
137
138
  "dependencies": {
138
- "@egjs/axes": "^2.8.0",
139
+ "@egjs/axes": "^3.1.2",
139
140
  "@egjs/component": "^3.0.1",
140
141
  "@egjs/imready": "^1.1.3",
141
142
  "@egjs/list-differ": "^1.0.0"
package/src/Flicking.ts CHANGED
@@ -58,6 +58,7 @@ export interface FlickingOptions {
58
58
  panelsPerView: number;
59
59
  noPanelStyleOverride: boolean;
60
60
  resizeOnContentsReady: boolean;
61
+ nested: boolean;
61
62
 
62
63
  // EVENT
63
64
  needPanelThreshold: number;
@@ -136,6 +137,7 @@ class Flicking extends Component<FlickingEvents> {
136
137
  private _noPanelStyleOverride: FlickingOptions["noPanelStyleOverride"];
137
138
  private _resizeOnContentsReady: FlickingOptions["resizeOnContentsReady"];
138
139
  private _virtual: FlickingOptions["virtual"];
140
+ private _nested: FlickingOptions["nested"];
139
141
 
140
142
  private _needPanelThreshold: FlickingOptions["needPanelThreshold"];
141
143
  private _preventEventsBeforeInit: FlickingOptions["preventEventsBeforeInit"];
@@ -413,6 +415,15 @@ class Flicking extends Component<FlickingEvents> {
413
415
  * @default false
414
416
  */
415
417
  public get resizeOnContentsReady() { return this._resizeOnContentsReady; }
418
+ /**
419
+ * 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.
420
+ * If the parent Flicking and child Flicking have different horizontal option, you do not need to set this option.
421
+ * @ko Flicking 내부에 Flicking이 배치될 때 하위 Flicking에서 이 옵션을 활성화하면 하위 Flicking이 첫/마지막 패널에 도달한 뒤부터 같은 방향으로 상위 Flicking이 움직입니다.
422
+ * 만약 상위 Flicking과 하위 Flicking이 서로 다른 horizontal 옵션을 가지고 있다면 이 옵션을 설정할 필요가 없습니다.
423
+ * @type {boolean}
424
+ * @default false
425
+ */
426
+ public get nested() { return this._nested; }
416
427
  // EVENTS
417
428
  /**
418
429
  * A Threshold from viewport edge before triggering `needPanel` event
@@ -677,6 +688,7 @@ class Flicking extends Component<FlickingEvents> {
677
688
  public set panelsPerView(val: FlickingOptions["panelsPerView"]) { this._panelsPerView = val; }
678
689
  public set noPanelStyleOverride(val: FlickingOptions["noPanelStyleOverride"]) { this._noPanelStyleOverride = val; }
679
690
  public set resizeOnContentsReady(val: FlickingOptions["resizeOnContentsReady"]) { this._resizeOnContentsReady = val; }
691
+ public set nested(val: FlickingOptions["nested"]) { this._nested = val; }
680
692
  // EVENTS
681
693
  public set needPanelThreshold(val: FlickingOptions["needPanelThreshold"]) { this._needPanelThreshold = val; }
682
694
  public set preventEventsBeforeInit(val: FlickingOptions["preventEventsBeforeInit"]) { this._preventEventsBeforeInit = val; }
@@ -768,6 +780,7 @@ class Flicking extends Component<FlickingEvents> {
768
780
  panelsPerView = -1,
769
781
  noPanelStyleOverride = false,
770
782
  resizeOnContentsReady = false,
783
+ nested = false,
771
784
  needPanelThreshold = 0,
772
785
  preventEventsBeforeInit = true,
773
786
  deceleration = 0.0075,
@@ -808,6 +821,7 @@ class Flicking extends Component<FlickingEvents> {
808
821
  this._panelsPerView = panelsPerView;
809
822
  this._noPanelStyleOverride = noPanelStyleOverride;
810
823
  this._resizeOnContentsReady = resizeOnContentsReady;
824
+ this._nested = nested;
811
825
  this._virtual = virtual;
812
826
  this._needPanelThreshold = needPanelThreshold;
813
827
  this._preventEventsBeforeInit = preventEventsBeforeInit;
@@ -383,25 +383,7 @@ class Camera {
383
383
  * @return {AnchorPoint | null} The {@link AnchorPoint} nearest to the given position<ko>해당 좌표에 가장 인접한 {@link AnchorPoint}</ko>
384
384
  */
385
385
  public findNearestAnchor(position: number): AnchorPoint | null {
386
- const anchors = this._anchors;
387
-
388
- if (anchors.length <= 0) return null;
389
-
390
- let prevDist = Infinity;
391
- for (let anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
392
- const anchor = anchors[anchorIdx];
393
- const dist = Math.abs(anchor.position - position);
394
-
395
- if (dist > prevDist) {
396
- // Return previous anchor
397
- return anchors[anchorIdx - 1];
398
- }
399
-
400
- prevDist = dist;
401
- }
402
-
403
- // Return last anchor
404
- return anchors[anchors.length - 1];
386
+ return this._mode.findNearestAnchor(position);
405
387
  }
406
388
 
407
389
  /**
@@ -44,6 +44,28 @@ abstract class CameraMode {
44
44
  }, null);
45
45
  }
46
46
 
47
+ public findNearestAnchor(position: number): AnchorPoint | null {
48
+ const anchors = this._flicking.camera.anchorPoints;
49
+
50
+ if (anchors.length <= 0) return null;
51
+
52
+ let prevDist = Infinity;
53
+ for (let anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
54
+ const anchor = anchors[anchorIdx];
55
+ const dist = Math.abs(anchor.position - position);
56
+
57
+ if (dist > prevDist) {
58
+ // Return previous anchor
59
+ return anchors[anchorIdx - 1];
60
+ }
61
+
62
+ prevDist = dist;
63
+ }
64
+
65
+ // Return last anchor
66
+ return anchors[anchors.length - 1];
67
+ }
68
+
47
69
  public clampToReachablePosition(position: number): number {
48
70
  const camera = this._flicking.camera;
49
71
  const range = camera.range;
@@ -64,6 +64,33 @@ class CircularCameraMode extends CameraMode {
64
64
  }));
65
65
  }
66
66
 
67
+ public findNearestAnchor(position: number): AnchorPoint | null {
68
+ const camera = this._flicking.camera;
69
+ const anchors = camera.anchorPoints;
70
+
71
+ if (anchors.length <= 0) return null;
72
+
73
+ const camRange = camera.range;
74
+ let minDist = Infinity;
75
+ let minDistIndex = -1;
76
+ for (let anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
77
+ const anchor = anchors[anchorIdx];
78
+ const dist = Math.min(
79
+ Math.abs(anchor.position - position),
80
+ Math.abs(anchor.position - camRange.min + camRange.max - position),
81
+ Math.abs(position - camRange.min + camRange.max - anchor.position)
82
+ );
83
+
84
+ if (dist < minDist) {
85
+ minDist = dist;
86
+ minDistIndex = anchorIdx;
87
+ }
88
+ }
89
+
90
+ // Return last anchor
91
+ return anchors[minDistIndex];
92
+ }
93
+
67
94
  public findAnchorIncludePosition(position: number): AnchorPoint | null {
68
95
  const camera = this._flicking.camera;
69
96
  const range = camera.range;
package/src/cfc/sync.ts CHANGED
@@ -85,7 +85,9 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
85
85
  }
86
86
  }
87
87
 
88
- renderer.updateAfterPanelChange(added, removed);
88
+ if (diffResult.added.length > 0 || diffResult.removed.length > 0) {
89
+ renderer.updateAfterPanelChange(added, removed);
90
+ }
89
91
  };
90
92
 
91
93
  const batchInsert = (renderer: Renderer, diffResult: DiffResult<any>, addedElements: any[], startIdx: number, endIdx?: number) => {
@@ -86,7 +86,7 @@ class AxesController {
86
86
  * @type {boolean}
87
87
  * @readonly
88
88
  */
89
- public get enabled() { return this._panInput?.isEnable() ?? false; }
89
+ public get enabled() { return this._panInput?.isEnabled() ?? false; }
90
90
  /**
91
91
  * Current position value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
92
92
  * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 좌표 값
@@ -134,6 +134,7 @@ class AxesController {
134
134
  }, {
135
135
  deceleration: flicking.deceleration,
136
136
  interruptable: flicking.interruptable,
137
+ nested: flicking.nested,
137
138
  easing: flicking.easing
138
139
  });
139
140
  this._panInput = new PanInput(flicking.viewport.element, {
@@ -220,7 +221,7 @@ class AxesController {
220
221
  axis.range = [controlParams.range.min, controlParams.range.max];
221
222
  axis.bounce = parseBounce(flicking.bounce, camera.size);
222
223
 
223
- axes.axm.set({ [AXES.POSITION_KEY]: controlParams.position });
224
+ axes.axisManager.set({ [AXES.POSITION_KEY]: controlParams.position });
224
225
 
225
226
  return this;
226
227
  }
@@ -331,7 +332,7 @@ class AxesController {
331
332
  ? circulatePosition(position, camera.range.min, camera.range.max)
332
333
  : position;
333
334
 
334
- axes.axm.set({ [AXES.POSITION_KEY]: newPos });
335
+ axes.axisManager.set({ [AXES.POSITION_KEY]: newPos });
335
336
 
336
337
  return Promise.resolve();
337
338
  } else {
@@ -171,7 +171,7 @@ abstract class Control {
171
171
  * @chainable
172
172
  * @return {Promise<void>}
173
173
  */
174
- public updatePosition(_progressInPanel: number): void { // eslint-disable-line @typescript-eslint/no-unused-vars
174
+ public updatePosition(progressInPanel: number): void { // eslint-disable-line @typescript-eslint/no-unused-vars
175
175
  const flicking = getFlickingAttached(this._flicking);
176
176
  const camera = flicking.camera;
177
177
  const activePanel = this._activePanel;
@@ -321,7 +321,7 @@ abstract class Control {
321
321
  }
322
322
  }
323
323
 
324
- protected _triggerIndexChangeEvent(panel: Panel, position: number, axesEvent?: OnRelease): void {
324
+ protected _triggerIndexChangeEvent(panel: Panel, position: number, axesEvent?: OnRelease) {
325
325
  const flicking = getFlickingAttached(this._flicking);
326
326
  const triggeringEvent = panel !== this._activePanel ? EVENTS.WILL_CHANGE : EVENTS.WILL_RESTORE;
327
327
  const camera = flicking.camera;
@@ -106,7 +106,7 @@ class FreeControl extends Control {
106
106
  * </ko>
107
107
  * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
108
108
  */
109
- public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
109
+ public moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
110
110
  const flicking = getFlickingAttached(this._flicking);
111
111
 
112
112
  const camera = flicking.camera;
@@ -84,7 +84,7 @@ class SnapControl extends Control {
84
84
  * </ko>
85
85
  * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
86
86
  */
87
- public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
87
+ public moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
88
88
  const flicking = getFlickingAttached(this._flicking);
89
89
  const camera = flicking.camera;
90
90
  const activeAnchor = camera.findActiveAnchor();
@@ -187,7 +187,7 @@ class StrictControl extends Control {
187
187
  * </ko>
188
188
  * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
189
189
  */
190
- public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
190
+ public moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
191
191
  const flicking = getFlickingAttached(this._flicking);
192
192
  const camera = flicking.camera;
193
193
  const activePanel = this._activePanel;
@@ -219,6 +219,10 @@ class StrictControl extends Control {
219
219
  const shouldBounceToFirst = position <= cameraRange.min && isBetween(firstAnchor.panel.index, indexRange.min, indexRange.max);
220
220
  const shouldBounceToLast = position >= cameraRange.max && isBetween(lastAnchor.panel.index, indexRange.min, indexRange.max);
221
221
 
222
+ const isAdjacent = adjacentAnchor && (indexRange.min <= indexRange.max
223
+ ? isBetween(adjacentAnchor.index, indexRange.min, indexRange.max)
224
+ : adjacentAnchor.index >= indexRange.min || adjacentAnchor.index <= indexRange.max);
225
+
222
226
  if (shouldBounceToFirst || shouldBounceToLast) {
223
227
  // In bounce area
224
228
  const targetAnchor = position < cameraRange.min ? firstAnchor : lastAnchor;
@@ -229,10 +233,10 @@ class StrictControl extends Control {
229
233
  // Move to anchor at position
230
234
  targetPanel = anchorAtPosition.panel;
231
235
  targetPos = anchorAtPosition.position;
232
- } else if (isOverThreshold && adjacentAnchor && isBetween(adjacentAnchor.index, indexRange.min, indexRange.max)) {
236
+ } else if (isOverThreshold && isAdjacent) {
233
237
  // Move to adjacent anchor
234
- targetPanel = adjacentAnchor.panel;
235
- targetPos = adjacentAnchor.position;
238
+ targetPanel = adjacentAnchor!.panel;
239
+ targetPos = adjacentAnchor!.position;
236
240
  } else {
237
241
  // Restore to active panel
238
242
  targetPos = camera.clampToReachablePosition(activePanel.position);
@@ -65,7 +65,10 @@ class AnimatingState extends State {
65
65
  axesEvent
66
66
  }));
67
67
 
68
- control.setActive(this._targetPanel!, control.activePanel, axesEvent.isTrusted);
68
+ const targetPanel = this._targetPanel;
69
+ if (targetPanel) {
70
+ control.setActive(targetPanel, control.activePanel, axesEvent.isTrusted);
71
+ }
69
72
  }
70
73
  }
71
74
 
@@ -34,7 +34,7 @@ class DraggingState extends State {
34
34
  this._moveToChangedPosition(ctx);
35
35
  }
36
36
 
37
- public onRelease(ctx: Parameters<State["onRelease"]>[0]): void {
37
+ public onRelease(ctx: Parameters<State["onRelease"]>[0]) {
38
38
  const { flicking, axesEvent, transitTo } = ctx;
39
39
 
40
40
  // Update last position to cope with Axes's animating behavior
@@ -55,7 +55,12 @@ class DraggingState extends State {
55
55
  const position = axesEvent.destPos[AXES.POSITION_KEY];
56
56
  const duration = Math.max(axesEvent.duration, flicking.duration);
57
57
 
58
- void control.moveToPosition(position, duration, axesEvent);
58
+ try {
59
+ void control.moveToPosition(position, duration, axesEvent);
60
+ } catch (err) {
61
+ transitTo(STATE_TYPE.IDLE);
62
+ axesEvent.setTo({ [AXES.POSITION_KEY]: flicking.camera.position }, 0);
63
+ }
59
64
  }
60
65
  }
61
66
 
@@ -337,24 +337,26 @@ abstract class Renderer {
337
337
 
338
338
  void this.render();
339
339
 
340
- if (!activePanel || activePanel.removed) {
341
- if (panels.length <= 0) {
342
- // All panels removed
343
- camera.lookAt(0);
344
- } else {
345
- let targetIndex = activePanel?.index ?? 0;
346
- if (targetIndex > panels.length - 1) {
347
- targetIndex = panels.length - 1;
340
+ if (!flicking.animating) {
341
+ if (!activePanel || activePanel.removed) {
342
+ if (panels.length <= 0) {
343
+ // All panels removed
344
+ camera.lookAt(0);
345
+ } else {
346
+ let targetIndex = activePanel?.index ?? 0;
347
+ if (targetIndex > panels.length - 1) {
348
+ targetIndex = panels.length - 1;
349
+ }
350
+
351
+ void control.moveToPanel(panels[targetIndex], {
352
+ duration: 0
353
+ }).catch(() => void 0);
348
354
  }
349
-
350
- void control.moveToPanel(panels[targetIndex], {
355
+ } else {
356
+ void control.moveToPanel(activePanel, {
351
357
  duration: 0
352
358
  }).catch(() => void 0);
353
359
  }
354
- } else {
355
- void control.moveToPanel(control.activePanel!, {
356
- duration: 0
357
- }).catch(() => void 0);
358
360
  }
359
361
 
360
362
  flicking.camera.updateOffset();
package/TODO.md DELETED
@@ -1,3 +0,0 @@
1
- ## React 18 대응
2
- - [] updateoffset을 미루기
3
- - render가 완료되기 전에 updateOffset이 3번 호출되었음