@egjs/flicking 4.13.2-beta.0 → 4.14.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/dist/flicking.js CHANGED
@@ -4,13 +4,13 @@ name: @egjs/flicking
4
4
  license: MIT
5
5
  author: NAVER Corp.
6
6
  repository: https://github.com/naver/egjs-flicking
7
- version: 4.13.2-beta.0
7
+ version: 4.14.0
8
8
  */
9
9
  (function (global, factory) {
10
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@egjs/component'), require('@egjs/axes'), require('@egjs/imready')) :
11
- typeof define === 'function' && define.amd ? define(['@egjs/component', '@egjs/axes', '@egjs/imready'], factory) :
12
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Flicking = factory(global.eg.Component, global.eg.Axes, global.eg.ImReady));
13
- })(this, (function (Component, Axes, ImReady) { 'use strict';
10
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@egjs/component'), require('@egjs/axes'), require('@egjs/imready'), require('@cfcs/core')) :
11
+ typeof define === 'function' && define.amd ? define(['@egjs/component', '@egjs/axes', '@egjs/imready', '@cfcs/core'], factory) :
12
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Flicking = factory(global.eg.Component, global.eg.Axes, global.eg.ImReady, global.core));
13
+ })(this, (function (Component, Axes, ImReady, core) { 'use strict';
14
14
 
15
15
  /******************************************************************************
16
16
  Copyright (c) Microsoft Corporation.
@@ -682,11 +682,14 @@ version: 4.13.2-beta.0
682
682
  }
683
683
  return -1;
684
684
  };
685
- var getProgress = function (pos, prev, next) {
685
+ var getProgress$1 = function (pos, prev, next) {
686
686
  return (pos - prev) / (next - prev);
687
687
  };
688
688
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
689
689
  var getStyle = function (el) {
690
+ if (!el) {
691
+ return {};
692
+ }
690
693
  return window.getComputedStyle(el) || el.currentStyle;
691
694
  };
692
695
  var setSize = function (el, _a) {
@@ -800,7 +803,7 @@ version: 4.13.2-beta.0
800
803
  find: find,
801
804
  findRight: findRight,
802
805
  findIndex: findIndex,
803
- getProgress: getProgress,
806
+ getProgress: getProgress$1,
804
807
  getStyle: getStyle,
805
808
  setSize: setSize,
806
809
  isBetween: isBetween,
@@ -994,13 +997,59 @@ version: 4.13.2-beta.0
994
997
  return Viewport;
995
998
  }();
996
999
 
1000
+ /*
1001
+ * Copyright (c) 2015 NAVER Corp.
1002
+ * egjs projects are licensed under the MIT license
1003
+ */
1004
+ /**
1005
+ * A component that detects size change and trigger resize method when the autoResize option is used
1006
+ * @ko autoResize 옵션을 사용할 때 크기 변화를 감지하고 Flicking의 resize를 호출하는 컴포넌트
1007
+ */
997
1008
  var AutoResizer = /*#__PURE__*/function () {
998
1009
  function AutoResizer(flicking) {
999
1010
  var _this = this;
1000
- this._onResize = function () {
1011
+ this._onResizeWrapper = function () {
1012
+ _this._onResize([]);
1013
+ };
1014
+ this._onResize = function (entries) {
1001
1015
  var flicking = _this._flicking;
1002
1016
  var resizeDebounce = flicking.resizeDebounce;
1003
1017
  var maxResizeDebounce = flicking.maxResizeDebounce;
1018
+ var resizedViewportElement = flicking.element;
1019
+ // 현재 구현에서 리사이즈 옵저빙 대상은 패널과 뷰포트 2개만 존재.
1020
+ // 아래는 뷰포트만 변경되었을 때 동작해야하는 로직이 있으므로 아래와 같이 조건문을 건다.
1021
+ // 패널 쪽에서는 리사이즈 감지에 resizeObserver를 사용하지 않는 경우가 없으므로 이 조건은 곧 뷰포트만 리사이즈가 된 경우를 의미한다.
1022
+ var isResizedViewportOnly = entries.find(function (e) {
1023
+ return e.target === flicking.element;
1024
+ }) && entries.length === 1;
1025
+ // 참고: resizeObserver를 사용하지 않은 경우에는 entries.length가 0으로 오는데 이 경우에는 그냥 항상 리사이즈가 진행되도록 한다.
1026
+ // (vw, vh 등을 사용하는 경우 이상 동작이 발생할 여지가 있기 때문이다)
1027
+ if (isResizedViewportOnly) {
1028
+ // resize 이벤트가 발생했으나 이전과 width, height의 변화가 없다면 이후 로직을 진행하지 않는다.
1029
+ var beforeSize = {
1030
+ width: flicking.viewport.width,
1031
+ height: flicking.viewport.height
1032
+ };
1033
+ var afterSize = {
1034
+ width: getElementSize({
1035
+ el: resizedViewportElement,
1036
+ horizontal: true,
1037
+ useFractionalSize: _this._flicking.useFractionalSize,
1038
+ useOffset: false,
1039
+ style: getStyle(resizedViewportElement)
1040
+ }),
1041
+ height: getElementSize({
1042
+ el: resizedViewportElement,
1043
+ horizontal: false,
1044
+ useFractionalSize: _this._flicking.useFractionalSize,
1045
+ useOffset: false,
1046
+ style: getStyle(resizedViewportElement)
1047
+ })
1048
+ };
1049
+ if (beforeSize.height === afterSize.height && beforeSize.width === afterSize.width) {
1050
+ return;
1051
+ }
1052
+ }
1004
1053
  if (resizeDebounce <= 0) {
1005
1054
  void flicking.resize();
1006
1055
  } else {
@@ -1026,12 +1075,12 @@ version: 4.13.2-beta.0
1026
1075
  // eslint-disable-next-line @typescript-eslint/member-ordering
1027
1076
  this._skipFirstResize = function () {
1028
1077
  var isFirstResize = true;
1029
- return function () {
1078
+ return function (entries) {
1030
1079
  if (isFirstResize) {
1031
1080
  isFirstResize = false;
1032
1081
  return;
1033
1082
  }
1034
- _this._onResize();
1083
+ _this._onResize(entries);
1035
1084
  };
1036
1085
  }();
1037
1086
  this._flicking = flicking;
@@ -1057,14 +1106,46 @@ version: 4.13.2-beta.0
1057
1106
  if (flicking.useResizeObserver && !!window.ResizeObserver) {
1058
1107
  var viewportSizeNot0 = viewport.width !== 0 || viewport.height !== 0;
1059
1108
  var resizeObserver = viewportSizeNot0 ? new ResizeObserver(this._skipFirstResize) : new ResizeObserver(this._onResize);
1060
- resizeObserver.observe(flicking.viewport.element);
1061
1109
  this._resizeObserver = resizeObserver;
1110
+ this.observe(flicking.viewport.element);
1111
+ if (flicking.observePanelResize) {
1112
+ this.observePanels();
1113
+ }
1062
1114
  } else {
1063
- window.addEventListener("resize", this._onResize);
1115
+ window.addEventListener("resize", this._onResizeWrapper);
1064
1116
  }
1065
1117
  this._enabled = true;
1066
1118
  return this;
1067
1119
  };
1120
+ __proto.observePanels = function () {
1121
+ var _this = this;
1122
+ this._flicking.panels.forEach(function (panel) {
1123
+ _this.observe(panel.element);
1124
+ });
1125
+ return this;
1126
+ };
1127
+ __proto.unobservePanels = function () {
1128
+ var _this = this;
1129
+ this._flicking.panels.forEach(function (panel) {
1130
+ _this.unobserve(panel.element);
1131
+ });
1132
+ return this;
1133
+ };
1134
+ __proto.observe = function (element) {
1135
+ var resizeObserver = this._resizeObserver;
1136
+ if (!resizeObserver) return this;
1137
+ resizeObserver.observe(element);
1138
+ return this;
1139
+ };
1140
+ __proto.unobserve = function (element) {
1141
+ var resizeObserver = this._resizeObserver;
1142
+ if (!resizeObserver) return this;
1143
+ resizeObserver.unobserve(element);
1144
+ if (this._flicking.observePanelResize) {
1145
+ this.unobservePanels();
1146
+ }
1147
+ return this;
1148
+ };
1068
1149
  __proto.disable = function () {
1069
1150
  if (!this._enabled) return this;
1070
1151
  var resizeObserver = this._resizeObserver;
@@ -1072,7 +1153,7 @@ version: 4.13.2-beta.0
1072
1153
  resizeObserver.disconnect();
1073
1154
  this._resizeObserver = null;
1074
1155
  } else {
1075
- window.removeEventListener("resize", this._onResize);
1156
+ window.removeEventListener("resize", this._onResizeWrapper);
1076
1157
  }
1077
1158
  this._enabled = false;
1078
1159
  return this;
@@ -2963,11 +3044,7 @@ version: 4.13.2-beta.0
2963
3044
  if (snapDelta >= snapThreshold && snapDelta > 0) {
2964
3045
  // Move to anchor at position
2965
3046
  targetAnchor = this._findSnappedAnchor(position, anchorAtCamera);
2966
- // const targetPanel = targetAnchor.panel;
2967
- // const nextPosition = this._getPosition(targetPanel, DIRECTION.NEXT);
2968
- // const prevPosition = this._getPosition(targetPanel, DIRECTION.PREV);
2969
- // targetPosition = Math.abs(camera.position - nextPosition) < Math.abs(camera.position - prevPosition) ? nextPosition : prevPosition;
2970
- } else if (absPosDelta >= flicking.threshold && absPosDelta > 0 && anchorAtCamera === activeAnchor) {
3047
+ } else if (absPosDelta >= flicking.threshold && absPosDelta > 0) {
2971
3048
  // Move to the adjacent panel
2972
3049
  targetAnchor = this._findAdjacentAnchor(position, posDelta, anchorAtCamera);
2973
3050
  } else {
@@ -2995,7 +3072,6 @@ version: 4.13.2-beta.0
2995
3072
  if (!anchorAtCamera || !anchorAtPosition) {
2996
3073
  throw new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE);
2997
3074
  }
2998
- // console.log("_findSnappedAnchor", anchorAtPosition);
2999
3075
  if (!isFinite(count)) {
3000
3076
  return anchorAtPosition;
3001
3077
  }
@@ -3437,7 +3513,10 @@ version: 4.13.2-beta.0
3437
3513
  };
3438
3514
  __proto.findAnchorIncludePosition = function (position) {
3439
3515
  var anchors = this._flicking.camera.anchorPoints;
3440
- return anchors.reduce(function (nearest, anchor) {
3516
+ var anchorsIncludingPosition = anchors.filter(function (anchor) {
3517
+ return anchor.panel.includePosition(position, true);
3518
+ });
3519
+ return anchorsIncludingPosition.reduce(function (nearest, anchor) {
3441
3520
  if (!nearest) return anchor;
3442
3521
  return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
3443
3522
  }, null);
@@ -4102,7 +4181,7 @@ version: 4.13.2-beta.0
4102
4181
  if (prevPosition > panelPos) {
4103
4182
  prevPosition -= rangeDiff;
4104
4183
  }
4105
- return nearestPanel.index - 1 + getProgress(position, prevPosition, panelPos);
4184
+ return nearestPanel.index - 1 + getProgress$1(position, prevPosition, panelPos);
4106
4185
  } else {
4107
4186
  var nextPanel = nearestPanel.next();
4108
4187
  var nextPosition = nextPanel ? nextPanel.position + nextPanel.offset : nextRange + bounceSize[1];
@@ -4110,7 +4189,7 @@ version: 4.13.2-beta.0
4110
4189
  if (nextPosition < panelPos) {
4111
4190
  nextPosition += rangeDiff;
4112
4191
  }
4113
- return nearestPanel.index + getProgress(position, panelPos, nextPosition);
4192
+ return nearestPanel.index + getProgress$1(position, panelPos, nextPosition);
4114
4193
  }
4115
4194
  },
4116
4195
  enumerable: false,
@@ -4906,6 +4985,18 @@ version: 4.13.2-beta.0
4906
4985
  var activePanel = control.activePanel;
4907
4986
  // Update camera & control
4908
4987
  this._updateCameraAndControl();
4988
+ if (flicking.autoResize && flicking.useResizeObserver) {
4989
+ panelsAdded.forEach(function (panel) {
4990
+ if (panel.element) {
4991
+ flicking.autoResizer.observe(panel.element);
4992
+ }
4993
+ });
4994
+ panelsRemoved.forEach(function (panel) {
4995
+ if (panel.element) {
4996
+ flicking.autoResizer.unobserve(panel.element);
4997
+ }
4998
+ });
4999
+ }
4909
5000
  void this.render();
4910
5001
  if (!flicking.animating) {
4911
5002
  if (!activePanel || activePanel.removed) {
@@ -5454,10 +5545,10 @@ version: 4.13.2-beta.0
5454
5545
  }
5455
5546
  if (camPos < position) {
5456
5547
  var disappearPosNext = position + (camera.size - camera.alignPosition) + alignPosition;
5457
- return -getProgress(camPos, position, disappearPosNext);
5548
+ return -getProgress$1(camPos, position, disappearPosNext);
5458
5549
  } else {
5459
5550
  var disappearPosPrev = position - (camera.alignPosition + this._size - alignPosition);
5460
- return 1 - getProgress(camPos, disappearPosPrev, position);
5551
+ return 1 - getProgress$1(camPos, disappearPosPrev, position);
5461
5552
  }
5462
5553
  },
5463
5554
  enumerable: false,
@@ -6197,18 +6288,23 @@ version: 4.13.2-beta.0
6197
6288
  useResizeObserver = _9 === void 0 ? true : _9,
6198
6289
  _10 = _b.resizeDebounce,
6199
6290
  resizeDebounce = _10 === void 0 ? 0 : _10,
6200
- _11 = _b.maxResizeDebounce,
6201
- maxResizeDebounce = _11 === void 0 ? 100 : _11,
6202
- _12 = _b.useFractionalSize,
6203
- useFractionalSize = _12 === void 0 ? false : _12,
6204
- _13 = _b.externalRenderer,
6205
- externalRenderer = _13 === void 0 ? null : _13,
6206
- _14 = _b.renderExternal,
6207
- renderExternal = _14 === void 0 ? null : _14;
6291
+ _11 = _b.observePanelResize,
6292
+ observePanelResize = _11 === void 0 ? false : _11,
6293
+ _12 = _b.maxResizeDebounce,
6294
+ maxResizeDebounce = _12 === void 0 ? 100 : _12,
6295
+ _13 = _b.useFractionalSize,
6296
+ useFractionalSize = _13 === void 0 ? false : _13,
6297
+ _14 = _b.externalRenderer,
6298
+ externalRenderer = _14 === void 0 ? null : _14,
6299
+ _15 = _b.renderExternal,
6300
+ renderExternal = _15 === void 0 ? null : _15,
6301
+ _16 = _b.optimizeSizeUpdate,
6302
+ optimizeSizeUpdate = _16 === void 0 ? false : _16;
6208
6303
  var _this = _super.call(this) || this;
6209
6304
  // Internal states
6210
6305
  _this._initialized = false;
6211
6306
  _this._plugins = [];
6307
+ _this._isResizing = false;
6212
6308
  // Bind options
6213
6309
  _this._align = align;
6214
6310
  _this._defaultIndex = defaultIndex;
@@ -6244,9 +6340,11 @@ version: 4.13.2-beta.0
6244
6340
  _this._useResizeObserver = useResizeObserver;
6245
6341
  _this._resizeDebounce = resizeDebounce;
6246
6342
  _this._maxResizeDebounce = maxResizeDebounce;
6343
+ _this._observePanelResize = observePanelResize;
6247
6344
  _this._useFractionalSize = useFractionalSize;
6248
6345
  _this._externalRenderer = externalRenderer;
6249
6346
  _this._renderExternal = renderExternal;
6347
+ _this._optimizeSizeUpdate = optimizeSizeUpdate;
6250
6348
  // Create core components
6251
6349
  _this._viewport = new Viewport(_this, getElement(root));
6252
6350
  _this._autoResizer = new AutoResizer(_this);
@@ -6327,6 +6425,19 @@ version: 4.13.2-beta.0
6327
6425
  enumerable: false,
6328
6426
  configurable: true
6329
6427
  });
6428
+ Object.defineProperty(__proto, "autoResizer", {
6429
+ /**
6430
+ * {@link AutoResizer} instance of the Flicking
6431
+ * @ko 현재 Flicking에 활성화된 {@link AutoResizer} 인스턴스
6432
+ * @internal
6433
+ * @readonly
6434
+ */
6435
+ get: function () {
6436
+ return this._autoResizer;
6437
+ },
6438
+ enumerable: false,
6439
+ configurable: true
6440
+ });
6330
6441
  Object.defineProperty(__proto, "initialized", {
6331
6442
  // Internal States
6332
6443
  /**
@@ -7200,6 +7311,9 @@ version: 4.13.2-beta.0
7200
7311
  // OTHERS
7201
7312
  set: function (val) {
7202
7313
  this._autoResize = val;
7314
+ if (!this._initialized) {
7315
+ return;
7316
+ }
7203
7317
  if (val) {
7204
7318
  this._autoResizer.enable();
7205
7319
  } else {
@@ -7222,13 +7336,38 @@ version: 4.13.2-beta.0
7222
7336
  },
7223
7337
  set: function (val) {
7224
7338
  this._useResizeObserver = val;
7225
- if (this._autoResize) {
7339
+ if (this._initialized && this._autoResize) {
7226
7340
  this._autoResizer.enable();
7227
7341
  }
7228
7342
  },
7229
7343
  enumerable: false,
7230
7344
  configurable: true
7231
7345
  });
7346
+ Object.defineProperty(__proto, "observePanelResize", {
7347
+ /**
7348
+ * Whether to use {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver} to observe the size of the panel element
7349
+ * This is only available when `useResizeObserver` is enabled.
7350
+ * This option garantees that the resize event is triggered when the size of the panel element is changed.
7351
+ * @ko 이 옵션을 활성화할 경우, {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}를 사용하여 패널 엘리먼트의 크기를 추적합니다.
7352
+ * 이 옵션은 `useResizeObserver` 옵션이 활성화된 경우에만 사용할 수 있습니다.
7353
+ * 이 옵션은 패널 엘리먼트의 크기가 변경될 경우 resize 이벤트가 발생하도록 보장합니다.
7354
+ */
7355
+ get: function () {
7356
+ return this._observePanelResize;
7357
+ },
7358
+ set: function (val) {
7359
+ this._observePanelResize = val;
7360
+ if (this._initialized && this._autoResize) {
7361
+ if (val) {
7362
+ this._autoResizer.observePanels();
7363
+ } else {
7364
+ this._autoResizer.unobservePanels();
7365
+ }
7366
+ }
7367
+ },
7368
+ enumerable: false,
7369
+ configurable: true
7370
+ });
7232
7371
  Object.defineProperty(__proto, "resizeDebounce", {
7233
7372
  /**
7234
7373
  * Delays size recalculation from `autoResize` by the given time in milisecond.
@@ -7310,6 +7449,30 @@ version: 4.13.2-beta.0
7310
7449
  enumerable: false,
7311
7450
  configurable: true
7312
7451
  });
7452
+ Object.defineProperty(__proto, "optimizeSizeUpdate", {
7453
+ /**
7454
+ * This option works only when autoResize is set to true.
7455
+ * By default, autoResize listens to changes in both the viewport's width and height, updating all panel sizes accordingly.
7456
+ * When optimizeSizeUpdate is enabled, the update behavior is optimized based on the flicking direction:
7457
+ * If direction is "horizontal", only changes in width will trigger panel size updates.
7458
+ * If direction is "vertical", only changes in height will do so.
7459
+ * This option is useful when panel heights vary and unwanted flickering occurs due to frequent size recalculations during flicking. Enabling optimizeSizeUpdate prevents unnecessary updates and helps maintain visual stability.
7460
+ * @ko optimizeSizeUpdate는 autoResize가 true일 때만 동작합니다.
7461
+ * 기본적으로 autoResize는 뷰포트의 width와 height 변화를 모두 감지하여 패널들의 사이즈를 업데이트합니다.
7462
+ * 이 옵션을 활성화하면 플리킹 방향에 따라 필요한 차원(horizontal → width, vertical → height)에 대해서만 사이즈를 업데이트합니다.
7463
+ * 내부 패널의 높이가 서로 다를 때, 플리킹 중 과도한 리사이징으로 인한 깜빡임 현상을 줄이는 데 유용합니다.
7464
+ * @type {boolean}
7465
+ * @default false
7466
+ */
7467
+ get: function () {
7468
+ return this._optimizeSizeUpdate;
7469
+ },
7470
+ set: function (val) {
7471
+ this._optimizeSizeUpdate = val;
7472
+ },
7473
+ enumerable: false,
7474
+ configurable: true
7475
+ });
7313
7476
  /**
7314
7477
  * Initialize Flicking and move to the default index
7315
7478
  * This is automatically called on Flicking's constructor when `autoInit` is true(default)
@@ -7748,6 +7911,8 @@ version: 4.13.2-beta.0
7748
7911
  return __generator(this, function (_a) {
7749
7912
  switch (_a.label) {
7750
7913
  case 0:
7914
+ if (this._isResizing) return [2 /*return*/];
7915
+ this._isResizing = true;
7751
7916
  viewport = this._viewport;
7752
7917
  renderer = this._renderer;
7753
7918
  camera = this._camera;
@@ -7762,9 +7927,20 @@ version: 4.13.2-beta.0
7762
7927
  element: viewport.element
7763
7928
  }));
7764
7929
  viewport.resize();
7930
+ if (!this._optimizeSizeUpdate) return [3 /*break*/, 3];
7931
+ if (!(this.horizontal && viewport.width !== prevWidth || !this.horizontal && viewport.height !== prevHeight)) return [3 /*break*/, 2];
7765
7932
  return [4 /*yield*/, renderer.forceRenderAllPanels()];
7766
7933
  case 1:
7934
+ _a.sent();
7935
+ _a.label = 2;
7936
+ case 2:
7937
+ return [3 /*break*/, 5];
7938
+ case 3:
7939
+ return [4 /*yield*/, renderer.forceRenderAllPanels()];
7940
+ case 4:
7767
7941
  _a.sent(); // Render all panel elements, to update sizes
7942
+ _a.label = 5;
7943
+ case 5:
7768
7944
  if (!this._initialized) {
7769
7945
  return [2 /*return*/];
7770
7946
  }
@@ -7777,7 +7953,7 @@ version: 4.13.2-beta.0
7777
7953
  camera.updatePanelOrder();
7778
7954
  camera.updateOffset();
7779
7955
  return [4 /*yield*/, renderer.render()];
7780
- case 2:
7956
+ case 6:
7781
7957
  _a.sent();
7782
7958
  if (!this._initialized) {
7783
7959
  return [2 /*return*/];
@@ -7800,6 +7976,7 @@ version: 4.13.2-beta.0
7800
7976
  sizeChanged: sizeChanged,
7801
7977
  element: viewport.element
7802
7978
  }));
7979
+ this._isResizing = false;
7803
7980
  return [2 /*return*/];
7804
7981
  }
7805
7982
  });
@@ -8019,7 +8196,7 @@ version: 4.13.2-beta.0
8019
8196
  * Flicking.VERSION; // ex) 4.0.0
8020
8197
  * ```
8021
8198
  */
8022
- Flicking.VERSION = "4.13.2-beta.0";
8199
+ Flicking.VERSION = "4.14.0";
8023
8200
  return Flicking;
8024
8201
  }(Component);
8025
8202
 
@@ -8606,6 +8783,196 @@ version: 4.13.2-beta.0
8606
8783
  getDefaultCameraTransform: getDefaultCameraTransform
8607
8784
  };
8608
8785
 
8786
+ // Check if Flicking has reached the first panel
8787
+ var getIsReachStart = function (flicking) {
8788
+ return !flicking.circular && flicking.index === 0;
8789
+ };
8790
+ // Check if Flicking has reached the last panel
8791
+ var getIsReachEnd = function (flicking) {
8792
+ return !flicking.circular && flicking.index === flicking.panelCount - 1;
8793
+ };
8794
+ // Get the total number of panels
8795
+ var getTotalPanelCount = function (flicking) {
8796
+ return flicking.panelCount;
8797
+ };
8798
+ // Get the current active panel index
8799
+ var getCurrentPanelIndex = function (flicking) {
8800
+ return flicking.index;
8801
+ };
8802
+ // Calculate the overall scroll progress percentage based on the current camera position
8803
+ var getProgress = function (flicking) {
8804
+ var cam = flicking.camera;
8805
+ var progressRatio = (cam.position - cam.range.min) / (cam.range.max - cam.range.min);
8806
+ var percent = Math.min(Math.max(progressRatio, 0), 1) * 100;
8807
+ return percent;
8808
+ };
8809
+ // Calculate the progress between panels including decimal values
8810
+ var getIndexProgress = function (flicking) {
8811
+ var cam = flicking.camera;
8812
+ var anchorPoints = cam.anchorPoints;
8813
+ var length = anchorPoints.length;
8814
+ var cameraPosition = cam.position;
8815
+ var isCircular = flicking.circularEnabled;
8816
+ var indexProgress = 0;
8817
+ var _a = cam.range,
8818
+ min = _a.min,
8819
+ max = _a.max;
8820
+ var firstAnchorPoint = anchorPoints[0];
8821
+ var lastAnchorPoint = anchorPoints[length - 1];
8822
+ var distanceLastToFirst = max - lastAnchorPoint.position + (firstAnchorPoint.position - min);
8823
+ anchorPoints.some(function (anchorPoint, index) {
8824
+ var anchorPosition = anchorPoint.position;
8825
+ var nextAnchorPoint = anchorPoints[index + 1];
8826
+ if (index === 0 && cameraPosition <= anchorPosition) {
8827
+ if (isCircular) {
8828
+ indexProgress = (cameraPosition - anchorPosition) / distanceLastToFirst;
8829
+ } else {
8830
+ indexProgress = (cameraPosition - anchorPosition) / anchorPoint.panel.size;
8831
+ }
8832
+ } else if (index === length - 1 && cameraPosition >= anchorPosition) {
8833
+ if (isCircular) {
8834
+ indexProgress = index + (cameraPosition - anchorPosition) / distanceLastToFirst;
8835
+ } else {
8836
+ indexProgress = index + (cameraPosition - anchorPosition) / anchorPoint.panel.size;
8837
+ }
8838
+ } else if (nextAnchorPoint && anchorPosition <= cameraPosition && cameraPosition <= nextAnchorPoint.position) {
8839
+ indexProgress = index + (cameraPosition - anchorPosition) / (nextAnchorPoint.position - anchorPosition);
8840
+ } else {
8841
+ return false;
8842
+ }
8843
+ return true;
8844
+ });
8845
+ return indexProgress;
8846
+ };
8847
+ /**
8848
+ * Internal reactive API adapter for Flicking that manages state and event listeners
8849
+ * This adapter is used internally by framework-specific packages (react-flicking, vue-flicking, etc.)
8850
+ * to provide reactive API support. Users rarely need to use this directly.
8851
+ * @ko Flicking의 상태와 이벤트 리스너를 관리하는 내부 반응형 API 어댑터
8852
+ * 이 어댑터는 react-flicking, vue-flicking 등의 프레임워크별 패키지에서 내부적으로 사용되어
8853
+ * 반응형 API 지원을 제공합니다. 사용자가 직접 사용할 일은 거의 없습니다.
8854
+ * @param onInit - Callback when reactive object is initialized<ko>반응형 객체가 초기화될 때 호출되는 콜백</ko>
8855
+ * @param onDestroy - Callback when reactive object is destroyed<ko>반응형 객체가 파괴될 때 호출되는 콜백</ko>
8856
+ * @param setMethods - Function to set available methods<ko>사용 가능한 메서드를 설정하는 함수</ko>
8857
+ * @returns Reactive object with Flicking state and methods<ko>Flicking 상태와 메서드를 포함한 반응형 객체</ko>
8858
+ */
8859
+ var flickingReactiveAPIAdapter = function (_a) {
8860
+ var _b, _c, _d;
8861
+ var onInit = _a.onInit,
8862
+ onDestroy = _a.onDestroy,
8863
+ setMethods = _a.setMethods,
8864
+ getProps = _a.getProps;
8865
+ var flicking;
8866
+ // Move to a specific panel index
8867
+ var moveTo = function (i) {
8868
+ if (flicking == null) {
8869
+ return Promise.reject(new Error("Flicking instance is not available"));
8870
+ }
8871
+ if (flicking === null || flicking === void 0 ? void 0 : flicking.animating) {
8872
+ return Promise.resolve();
8873
+ }
8874
+ return flicking.moveTo(i);
8875
+ };
8876
+ setMethods(["moveTo"]);
8877
+ var options = getProps().options;
8878
+ // options를 고려하지 않고 초기값을 설정해도 동작에는 아무런 문제가 없으나, 이 시점의 초기값과 컴포넌트 init 단계에서의 초기값이 다르면 화면 리렌더링이 발생할 수 있으므로
8879
+ // 이렇게 미리 옵션을 통해서 예측할 수 있는 부분들은 맞춰둔다.
8880
+ var reactiveObj = core.reactive({
8881
+ isReachStart: (options === null || options === void 0 ? void 0 : options.defaultIndex) ? (options === null || options === void 0 ? void 0 : options.defaultIndex) === 0 : true,
8882
+ isReachEnd: (options === null || options === void 0 ? void 0 : options.totalPanelCount) && (options === null || options === void 0 ? void 0 : options.defaultIndex) ? options.defaultIndex === options.totalPanelCount - 1 : false,
8883
+ totalPanelCount: (_b = options === null || options === void 0 ? void 0 : options.totalPanelCount) !== null && _b !== void 0 ? _b : 0,
8884
+ currentPanelIndex: (_c = options === null || options === void 0 ? void 0 : options.defaultIndex) !== null && _c !== void 0 ? _c : 0,
8885
+ progress: 0,
8886
+ indexProgress: (_d = options === null || options === void 0 ? void 0 : options.defaultIndex) !== null && _d !== void 0 ? _d : 0,
8887
+ moveTo: moveTo
8888
+ });
8889
+ // Update state when panel changes
8890
+ var onChanged = function () {
8891
+ if (flicking === undefined) return;
8892
+ reactiveObj.isReachStart = getIsReachStart(flicking);
8893
+ reactiveObj.isReachEnd = getIsReachEnd(flicking);
8894
+ reactiveObj.currentPanelIndex = getCurrentPanelIndex(flicking);
8895
+ };
8896
+ // Update state when panel count changes
8897
+ var onPanelChange = function () {
8898
+ if (flicking === undefined) return;
8899
+ onChanged();
8900
+ reactiveObj.totalPanelCount = getTotalPanelCount(flicking);
8901
+ };
8902
+ // Update progress when camera moves
8903
+ var onMove = function () {
8904
+ if (flicking === undefined) return;
8905
+ reactiveObj.progress = getProgress(flicking);
8906
+ reactiveObj.indexProgress = getIndexProgress(flicking);
8907
+ };
8908
+ onInit(function (inst, data) {
8909
+ flicking = data.flicking;
8910
+ if (flicking === undefined) return;
8911
+ reactiveObj.isReachStart = getIsReachStart(flicking);
8912
+ reactiveObj.isReachEnd = getIsReachEnd(flicking);
8913
+ reactiveObj.currentPanelIndex = getCurrentPanelIndex(flicking);
8914
+ reactiveObj.progress = getProgress(flicking);
8915
+ reactiveObj.totalPanelCount = getTotalPanelCount(flicking);
8916
+ flicking === null || flicking === void 0 ? void 0 : flicking.on("changed", onChanged);
8917
+ flicking === null || flicking === void 0 ? void 0 : flicking.on("panelChange", onPanelChange);
8918
+ flicking === null || flicking === void 0 ? void 0 : flicking.on("move", onMove);
8919
+ });
8920
+ onDestroy(function () {
8921
+ flicking === null || flicking === void 0 ? void 0 : flicking.off("changed", onChanged);
8922
+ flicking === null || flicking === void 0 ? void 0 : flicking.off("panelChange", onPanelChange);
8923
+ flicking === null || flicking === void 0 ? void 0 : flicking.off("move", onMove);
8924
+ });
8925
+ return reactiveObj;
8926
+ };
8927
+ /**
8928
+ * Connect Flicking instance to reactive API
8929
+ * @ko Flicking 인스턴스를 반응형 API에 연결합니다
8930
+ * @param {Flicking} flicking - Flicking instance to connect<ko>연결할 Flicking 인스턴스</ko>
8931
+ * @param {FlickingReactiveAPIOptions} [options] - Flicking options<ko>Flicking 옵션</ko>
8932
+ * @returns {FlickingReactiveObject} Reactive object with Flicking state and methods<ko>Flicking 상태와 메서드를 포함한 반응형 객체</ko>
8933
+ * @example
8934
+ * ```js
8935
+ * import Flicking, { connectFlickingReactiveAPI } from "@egjs/flicking";
8936
+ *
8937
+ * const flicking = new Flicking("#el");
8938
+ * const reactiveObj = connectFlickingReactiveAPI(flicking);
8939
+ *
8940
+ * // Access reactive state
8941
+ * console.log("Current panel:", reactiveObj.currentPanelIndex);
8942
+ * console.log("Progress:", reactiveObj.progress + "%");
8943
+ * console.log("Is at start:", reactiveObj.isReachStart);
8944
+ * console.log("Is at end:", reactiveObj.isReachEnd);
8945
+ * console.log("Total panels:", reactiveObj.totalPanelCount);
8946
+ * console.log("Index progress:", reactiveObj.indexProgress);
8947
+ *
8948
+ * // Subscribe to state changes
8949
+ * reactiveObj.subscribe("currentPanelIndex", (nextValue) => {
8950
+ * console.log("Panel changed to:", nextValue);
8951
+ * });
8952
+ *
8953
+ * // Use reactive methods
8954
+ * reactiveObj.moveTo(2); // Move to third panel
8955
+ * ```
8956
+ */
8957
+ var connectFlickingReactiveAPI = function (flicking, options) {
8958
+ var obj = core.adaptReactive(flickingReactiveAPIAdapter, function () {
8959
+ return {
8960
+ flicking: flicking,
8961
+ options: options
8962
+ };
8963
+ });
8964
+ obj.mounted();
8965
+ var instance = obj.instance();
8966
+ obj.init();
8967
+ return instance;
8968
+ };
8969
+
8970
+ var FlickingReactiveAPI = {
8971
+ __proto__: null,
8972
+ flickingReactiveAPIAdapter: flickingReactiveAPIAdapter,
8973
+ connectFlickingReactiveAPI: connectFlickingReactiveAPI
8974
+ };
8975
+
8609
8976
  /*
8610
8977
  * Copyright (c) 2015 NAVER Corp.
8611
8978
  * egjs projects are licensed under the MIT license
@@ -8618,6 +8985,7 @@ version: 4.13.2-beta.0
8618
8985
  merge(Flicking, CFC);
8619
8986
  merge(Flicking, Utils);
8620
8987
  merge(Flicking, CrossFlicking$1);
8988
+ merge(Flicking, FlickingReactiveAPI);
8621
8989
 
8622
8990
  return Flicking;
8623
8991