@egjs/flicking 4.13.2-beta.0 → 4.13.2-beta.1

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.
@@ -4,7 +4,7 @@ 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.13.2-beta.1
8
8
  */
9
9
  import Component, { ComponentEvent } from '@egjs/component';
10
10
  import Axes, { PanInput } from '@egjs/axes';
@@ -672,6 +672,9 @@ var getProgress = function (pos, prev, next) {
672
672
  };
673
673
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
674
674
  var getStyle = function (el) {
675
+ if (!el) {
676
+ return {};
677
+ }
675
678
  return window.getComputedStyle(el) || el.currentStyle;
676
679
  };
677
680
  var setSize = function (el, _a) {
@@ -944,13 +947,59 @@ var Viewport = /*#__PURE__*/function () {
944
947
  return Viewport;
945
948
  }();
946
949
 
950
+ /*
951
+ * Copyright (c) 2015 NAVER Corp.
952
+ * egjs projects are licensed under the MIT license
953
+ */
954
+ /**
955
+ * A component that detects size change and trigger resize method when the autoResize option is used
956
+ * @ko autoResize 옵션을 사용할 때 크기 변화를 감지하고 Flicking의 resize를 호출하는 컴포넌트
957
+ */
947
958
  var AutoResizer = /*#__PURE__*/function () {
948
959
  function AutoResizer(flicking) {
949
960
  var _this = this;
950
- this._onResize = function () {
961
+ this._onResizeWrapper = function () {
962
+ _this._onResize([]);
963
+ };
964
+ this._onResize = function (entries) {
951
965
  var flicking = _this._flicking;
952
966
  var resizeDebounce = flicking.resizeDebounce;
953
967
  var maxResizeDebounce = flicking.maxResizeDebounce;
968
+ var resizedViewportElement = flicking.element;
969
+ // 현재 구현에서 리사이즈 옵저빙 대상은 패널과 뷰포트 2개만 존재.
970
+ // 아래는 뷰포트만 변경되었을 때 동작해야하는 로직이 있으므로 아래와 같이 조건문을 건다.
971
+ // 패널 쪽에서는 리사이즈 감지에 resizeObserver를 사용하지 않는 경우가 없으므로 이 조건은 곧 뷰포트만 리사이즈가 된 경우를 의미한다.
972
+ var isResizedViewportOnly = entries.find(function (e) {
973
+ return e.target === flicking.element;
974
+ }) && entries.length === 1;
975
+ // 참고: resizeObserver를 사용하지 않은 경우에는 entries.length가 0으로 오는데 이 경우에는 그냥 항상 리사이즈가 진행되도록 한다.
976
+ // (vw, vh 등을 사용하는 경우 이상 동작이 발생할 여지가 있기 때문이다)
977
+ if (isResizedViewportOnly) {
978
+ // resize 이벤트가 발생했으나 이전과 width, height의 변화가 없다면 이후 로직을 진행하지 않는다.
979
+ var beforeSize = {
980
+ width: flicking.viewport.width,
981
+ height: flicking.viewport.height
982
+ };
983
+ var afterSize = {
984
+ width: getElementSize({
985
+ el: resizedViewportElement,
986
+ horizontal: true,
987
+ useFractionalSize: _this._flicking.useFractionalSize,
988
+ useOffset: false,
989
+ style: getStyle(resizedViewportElement)
990
+ }),
991
+ height: getElementSize({
992
+ el: resizedViewportElement,
993
+ horizontal: false,
994
+ useFractionalSize: _this._flicking.useFractionalSize,
995
+ useOffset: false,
996
+ style: getStyle(resizedViewportElement)
997
+ })
998
+ };
999
+ if (beforeSize.height === afterSize.height && beforeSize.width === afterSize.width) {
1000
+ return;
1001
+ }
1002
+ }
954
1003
  if (resizeDebounce <= 0) {
955
1004
  void flicking.resize();
956
1005
  } else {
@@ -976,12 +1025,12 @@ var AutoResizer = /*#__PURE__*/function () {
976
1025
  // eslint-disable-next-line @typescript-eslint/member-ordering
977
1026
  this._skipFirstResize = function () {
978
1027
  var isFirstResize = true;
979
- return function () {
1028
+ return function (entries) {
980
1029
  if (isFirstResize) {
981
1030
  isFirstResize = false;
982
1031
  return;
983
1032
  }
984
- _this._onResize();
1033
+ _this._onResize(entries);
985
1034
  };
986
1035
  }();
987
1036
  this._flicking = flicking;
@@ -1007,14 +1056,46 @@ var AutoResizer = /*#__PURE__*/function () {
1007
1056
  if (flicking.useResizeObserver && !!window.ResizeObserver) {
1008
1057
  var viewportSizeNot0 = viewport.width !== 0 || viewport.height !== 0;
1009
1058
  var resizeObserver = viewportSizeNot0 ? new ResizeObserver(this._skipFirstResize) : new ResizeObserver(this._onResize);
1010
- resizeObserver.observe(flicking.viewport.element);
1011
1059
  this._resizeObserver = resizeObserver;
1060
+ this.observe(flicking.viewport.element);
1061
+ if (flicking.observePanelResize) {
1062
+ this.observePanels();
1063
+ }
1012
1064
  } else {
1013
- window.addEventListener("resize", this._onResize);
1065
+ window.addEventListener("resize", this._onResizeWrapper);
1014
1066
  }
1015
1067
  this._enabled = true;
1016
1068
  return this;
1017
1069
  };
1070
+ __proto.observePanels = function () {
1071
+ var _this = this;
1072
+ this._flicking.panels.forEach(function (panel) {
1073
+ _this.observe(panel.element);
1074
+ });
1075
+ return this;
1076
+ };
1077
+ __proto.unobservePanels = function () {
1078
+ var _this = this;
1079
+ this._flicking.panels.forEach(function (panel) {
1080
+ _this.unobserve(panel.element);
1081
+ });
1082
+ return this;
1083
+ };
1084
+ __proto.observe = function (element) {
1085
+ var resizeObserver = this._resizeObserver;
1086
+ if (!resizeObserver) return this;
1087
+ resizeObserver.observe(element);
1088
+ return this;
1089
+ };
1090
+ __proto.unobserve = function (element) {
1091
+ var resizeObserver = this._resizeObserver;
1092
+ if (!resizeObserver) return this;
1093
+ resizeObserver.unobserve(element);
1094
+ if (this._flicking.observePanelResize) {
1095
+ this.unobservePanels();
1096
+ }
1097
+ return this;
1098
+ };
1018
1099
  __proto.disable = function () {
1019
1100
  if (!this._enabled) return this;
1020
1101
  var resizeObserver = this._resizeObserver;
@@ -1022,7 +1103,7 @@ var AutoResizer = /*#__PURE__*/function () {
1022
1103
  resizeObserver.disconnect();
1023
1104
  this._resizeObserver = null;
1024
1105
  } else {
1025
- window.removeEventListener("resize", this._onResize);
1106
+ window.removeEventListener("resize", this._onResizeWrapper);
1026
1107
  }
1027
1108
  this._enabled = false;
1028
1109
  return this;
@@ -2913,11 +2994,7 @@ var SnapControl = /*#__PURE__*/function (_super) {
2913
2994
  if (snapDelta >= snapThreshold && snapDelta > 0) {
2914
2995
  // Move to anchor at position
2915
2996
  targetAnchor = this._findSnappedAnchor(position, anchorAtCamera);
2916
- // const targetPanel = targetAnchor.panel;
2917
- // const nextPosition = this._getPosition(targetPanel, DIRECTION.NEXT);
2918
- // const prevPosition = this._getPosition(targetPanel, DIRECTION.PREV);
2919
- // targetPosition = Math.abs(camera.position - nextPosition) < Math.abs(camera.position - prevPosition) ? nextPosition : prevPosition;
2920
- } else if (absPosDelta >= flicking.threshold && absPosDelta > 0 && anchorAtCamera === activeAnchor) {
2997
+ } else if (absPosDelta >= flicking.threshold && absPosDelta > 0) {
2921
2998
  // Move to the adjacent panel
2922
2999
  targetAnchor = this._findAdjacentAnchor(position, posDelta, anchorAtCamera);
2923
3000
  } else {
@@ -2945,7 +3022,6 @@ var SnapControl = /*#__PURE__*/function (_super) {
2945
3022
  if (!anchorAtCamera || !anchorAtPosition) {
2946
3023
  throw new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE);
2947
3024
  }
2948
- // console.log("_findSnappedAnchor", anchorAtPosition);
2949
3025
  if (!isFinite(count)) {
2950
3026
  return anchorAtPosition;
2951
3027
  }
@@ -3366,7 +3442,10 @@ var CameraMode = /*#__PURE__*/function () {
3366
3442
  };
3367
3443
  __proto.findAnchorIncludePosition = function (position) {
3368
3444
  var anchors = this._flicking.camera.anchorPoints;
3369
- return anchors.reduce(function (nearest, anchor) {
3445
+ var anchorsIncludingPosition = anchors.filter(function (anchor) {
3446
+ return anchor.panel.includePosition(position, true);
3447
+ });
3448
+ return anchorsIncludingPosition.reduce(function (nearest, anchor) {
3370
3449
  if (!nearest) return anchor;
3371
3450
  return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
3372
3451
  }, null);
@@ -4822,6 +4901,18 @@ var Renderer = /*#__PURE__*/function () {
4822
4901
  var activePanel = control.activePanel;
4823
4902
  // Update camera & control
4824
4903
  this._updateCameraAndControl();
4904
+ if (flicking.autoResize && flicking.useResizeObserver) {
4905
+ panelsAdded.forEach(function (panel) {
4906
+ if (panel.element) {
4907
+ flicking.autoResizer.observe(panel.element);
4908
+ }
4909
+ });
4910
+ panelsRemoved.forEach(function (panel) {
4911
+ if (panel.element) {
4912
+ flicking.autoResizer.unobserve(panel.element);
4913
+ }
4914
+ });
4915
+ }
4825
4916
  void this.render();
4826
4917
  if (!flicking.animating) {
4827
4918
  if (!activePanel || activePanel.removed) {
@@ -6099,18 +6190,23 @@ var Flicking = /*#__PURE__*/function (_super) {
6099
6190
  useResizeObserver = _9 === void 0 ? true : _9,
6100
6191
  _10 = _b.resizeDebounce,
6101
6192
  resizeDebounce = _10 === void 0 ? 0 : _10,
6102
- _11 = _b.maxResizeDebounce,
6103
- maxResizeDebounce = _11 === void 0 ? 100 : _11,
6104
- _12 = _b.useFractionalSize,
6105
- useFractionalSize = _12 === void 0 ? false : _12,
6106
- _13 = _b.externalRenderer,
6107
- externalRenderer = _13 === void 0 ? null : _13,
6108
- _14 = _b.renderExternal,
6109
- renderExternal = _14 === void 0 ? null : _14;
6193
+ _11 = _b.observePanelResize,
6194
+ observePanelResize = _11 === void 0 ? false : _11,
6195
+ _12 = _b.maxResizeDebounce,
6196
+ maxResizeDebounce = _12 === void 0 ? 100 : _12,
6197
+ _13 = _b.useFractionalSize,
6198
+ useFractionalSize = _13 === void 0 ? false : _13,
6199
+ _14 = _b.externalRenderer,
6200
+ externalRenderer = _14 === void 0 ? null : _14,
6201
+ _15 = _b.renderExternal,
6202
+ renderExternal = _15 === void 0 ? null : _15,
6203
+ _16 = _b.optimizeSizeUpdate,
6204
+ optimizeSizeUpdate = _16 === void 0 ? false : _16;
6110
6205
  var _this = _super.call(this) || this;
6111
6206
  // Internal states
6112
6207
  _this._initialized = false;
6113
6208
  _this._plugins = [];
6209
+ _this._isResizing = false;
6114
6210
  // Bind options
6115
6211
  _this._align = align;
6116
6212
  _this._defaultIndex = defaultIndex;
@@ -6146,9 +6242,11 @@ var Flicking = /*#__PURE__*/function (_super) {
6146
6242
  _this._useResizeObserver = useResizeObserver;
6147
6243
  _this._resizeDebounce = resizeDebounce;
6148
6244
  _this._maxResizeDebounce = maxResizeDebounce;
6245
+ _this._observePanelResize = observePanelResize;
6149
6246
  _this._useFractionalSize = useFractionalSize;
6150
6247
  _this._externalRenderer = externalRenderer;
6151
6248
  _this._renderExternal = renderExternal;
6249
+ _this._optimizeSizeUpdate = optimizeSizeUpdate;
6152
6250
  // Create core components
6153
6251
  _this._viewport = new Viewport(_this, getElement(root));
6154
6252
  _this._autoResizer = new AutoResizer(_this);
@@ -6229,6 +6327,19 @@ var Flicking = /*#__PURE__*/function (_super) {
6229
6327
  enumerable: false,
6230
6328
  configurable: true
6231
6329
  });
6330
+ Object.defineProperty(__proto, "autoResizer", {
6331
+ /**
6332
+ * {@link AutoResizer} instance of the Flicking
6333
+ * @ko 현재 Flicking에 활성화된 {@link AutoResizer} 인스턴스
6334
+ * @internal
6335
+ * @readonly
6336
+ */
6337
+ get: function () {
6338
+ return this._autoResizer;
6339
+ },
6340
+ enumerable: false,
6341
+ configurable: true
6342
+ });
6232
6343
  Object.defineProperty(__proto, "initialized", {
6233
6344
  // Internal States
6234
6345
  /**
@@ -7102,6 +7213,9 @@ var Flicking = /*#__PURE__*/function (_super) {
7102
7213
  // OTHERS
7103
7214
  set: function (val) {
7104
7215
  this._autoResize = val;
7216
+ if (!this._initialized) {
7217
+ return;
7218
+ }
7105
7219
  if (val) {
7106
7220
  this._autoResizer.enable();
7107
7221
  } else {
@@ -7124,13 +7238,38 @@ var Flicking = /*#__PURE__*/function (_super) {
7124
7238
  },
7125
7239
  set: function (val) {
7126
7240
  this._useResizeObserver = val;
7127
- if (this._autoResize) {
7241
+ if (this._initialized && this._autoResize) {
7128
7242
  this._autoResizer.enable();
7129
7243
  }
7130
7244
  },
7131
7245
  enumerable: false,
7132
7246
  configurable: true
7133
7247
  });
7248
+ Object.defineProperty(__proto, "observePanelResize", {
7249
+ /**
7250
+ * Whether to use {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver} to observe the size of the panel element
7251
+ * This is only available when `useResizeObserver` is enabled.
7252
+ * This option garantees that the resize event is triggered when the size of the panel element is changed.
7253
+ * @ko 이 옵션을 활성화할 경우, {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}를 사용하여 패널 엘리먼트의 크기를 추적합니다.
7254
+ * 이 옵션은 `useResizeObserver` 옵션이 활성화된 경우에만 사용할 수 있습니다.
7255
+ * 이 옵션은 패널 엘리먼트의 크기가 변경될 경우 resize 이벤트가 발생하도록 보장합니다.
7256
+ */
7257
+ get: function () {
7258
+ return this._observePanelResize;
7259
+ },
7260
+ set: function (val) {
7261
+ this._observePanelResize = val;
7262
+ if (this._initialized && this._autoResize) {
7263
+ if (val) {
7264
+ this._autoResizer.observePanels();
7265
+ } else {
7266
+ this._autoResizer.unobservePanels();
7267
+ }
7268
+ }
7269
+ },
7270
+ enumerable: false,
7271
+ configurable: true
7272
+ });
7134
7273
  Object.defineProperty(__proto, "resizeDebounce", {
7135
7274
  /**
7136
7275
  * Delays size recalculation from `autoResize` by the given time in milisecond.
@@ -7212,6 +7351,30 @@ var Flicking = /*#__PURE__*/function (_super) {
7212
7351
  enumerable: false,
7213
7352
  configurable: true
7214
7353
  });
7354
+ Object.defineProperty(__proto, "optimizeSizeUpdate", {
7355
+ /**
7356
+ * This option works only when autoResize is set to true.
7357
+ * By default, autoResize listens to changes in both the viewport's width and height, updating all panel sizes accordingly.
7358
+ * When optimizeSizeUpdate is enabled, the update behavior is optimized based on the flicking direction:
7359
+ * If direction is "horizontal", only changes in width will trigger panel size updates.
7360
+ * If direction is "vertical", only changes in height will do so.
7361
+ * 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.
7362
+ * @ko optimizeSizeUpdate는 autoResize가 true일 때만 동작합니다.
7363
+ * 기본적으로 autoResize는 뷰포트의 width와 height 변화를 모두 감지하여 패널들의 사이즈를 업데이트합니다.
7364
+ * 이 옵션을 활성화하면 플리킹 방향에 따라 필요한 차원(horizontal → width, vertical → height)에 대해서만 사이즈를 업데이트합니다.
7365
+ * 내부 패널의 높이가 서로 다를 때, 플리킹 중 과도한 리사이징으로 인한 깜빡임 현상을 줄이는 데 유용합니다.
7366
+ * @type {boolean}
7367
+ * @default false
7368
+ */
7369
+ get: function () {
7370
+ return this._optimizeSizeUpdate;
7371
+ },
7372
+ set: function (val) {
7373
+ this._optimizeSizeUpdate = val;
7374
+ },
7375
+ enumerable: false,
7376
+ configurable: true
7377
+ });
7215
7378
  /**
7216
7379
  * Initialize Flicking and move to the default index
7217
7380
  * This is automatically called on Flicking's constructor when `autoInit` is true(default)
@@ -7650,6 +7813,8 @@ var Flicking = /*#__PURE__*/function (_super) {
7650
7813
  return __generator(this, function (_a) {
7651
7814
  switch (_a.label) {
7652
7815
  case 0:
7816
+ if (this._isResizing) return [2 /*return*/];
7817
+ this._isResizing = true;
7653
7818
  viewport = this._viewport;
7654
7819
  renderer = this._renderer;
7655
7820
  camera = this._camera;
@@ -7664,9 +7829,20 @@ var Flicking = /*#__PURE__*/function (_super) {
7664
7829
  element: viewport.element
7665
7830
  }));
7666
7831
  viewport.resize();
7832
+ if (!this._optimizeSizeUpdate) return [3 /*break*/, 3];
7833
+ if (!(this.horizontal && viewport.width !== prevWidth || !this.horizontal && viewport.height !== prevHeight)) return [3 /*break*/, 2];
7667
7834
  return [4 /*yield*/, renderer.forceRenderAllPanels()];
7668
7835
  case 1:
7836
+ _a.sent();
7837
+ _a.label = 2;
7838
+ case 2:
7839
+ return [3 /*break*/, 5];
7840
+ case 3:
7841
+ return [4 /*yield*/, renderer.forceRenderAllPanels()];
7842
+ case 4:
7669
7843
  _a.sent(); // Render all panel elements, to update sizes
7844
+ _a.label = 5;
7845
+ case 5:
7670
7846
  if (!this._initialized) {
7671
7847
  return [2 /*return*/];
7672
7848
  }
@@ -7679,7 +7855,7 @@ var Flicking = /*#__PURE__*/function (_super) {
7679
7855
  camera.updatePanelOrder();
7680
7856
  camera.updateOffset();
7681
7857
  return [4 /*yield*/, renderer.render()];
7682
- case 2:
7858
+ case 6:
7683
7859
  _a.sent();
7684
7860
  if (!this._initialized) {
7685
7861
  return [2 /*return*/];
@@ -7702,6 +7878,7 @@ var Flicking = /*#__PURE__*/function (_super) {
7702
7878
  sizeChanged: sizeChanged,
7703
7879
  element: viewport.element
7704
7880
  }));
7881
+ this._isResizing = false;
7705
7882
  return [2 /*return*/];
7706
7883
  }
7707
7884
  });
@@ -7921,7 +8098,7 @@ var Flicking = /*#__PURE__*/function (_super) {
7921
8098
  * Flicking.VERSION; // ex) 4.0.0
7922
8099
  * ```
7923
8100
  */
7924
- Flicking.VERSION = "4.13.2-beta.0";
8101
+ Flicking.VERSION = "4.13.2-beta.1";
7925
8102
  return Flicking;
7926
8103
  }(Component);
7927
8104