@egjs/flicking 4.4.2 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/declaration/Flicking.d.ts +8 -2
  2. package/declaration/camera/Camera.d.ts +26 -24
  3. package/declaration/camera/index.d.ts +2 -4
  4. package/declaration/camera/mode/BoundCameraMode.d.ts +13 -0
  5. package/declaration/camera/mode/CameraMode.d.ts +19 -0
  6. package/declaration/camera/mode/CircularCameraMode.d.ts +18 -0
  7. package/declaration/camera/mode/LinearCameraMode.d.ts +9 -0
  8. package/declaration/camera/mode/index.d.ts +6 -0
  9. package/declaration/const/external.d.ts +4 -0
  10. package/declaration/type/external.d.ts +1 -3
  11. package/dist/flicking.esm.js +1181 -1090
  12. package/dist/flicking.esm.js.map +1 -1
  13. package/dist/flicking.js +1184 -1092
  14. package/dist/flicking.js.map +1 -1
  15. package/dist/flicking.min.js +2 -2
  16. package/dist/flicking.min.js.map +1 -1
  17. package/dist/flicking.pkgd.js +1183 -1091
  18. package/dist/flicking.pkgd.js.map +1 -1
  19. package/dist/flicking.pkgd.min.js +2 -2
  20. package/dist/flicking.pkgd.min.js.map +1 -1
  21. package/package.json +4 -3
  22. package/src/Flicking.ts +26 -15
  23. package/src/camera/Camera.ts +155 -70
  24. package/src/camera/index.ts +3 -7
  25. package/src/camera/{BoundCamera.ts → mode/BoundCameraMode.ts} +46 -43
  26. package/src/camera/mode/CameraMode.ts +77 -0
  27. package/src/camera/mode/CircularCameraMode.ts +171 -0
  28. package/src/camera/mode/LinearCameraMode.ts +23 -0
  29. package/src/camera/mode/index.ts +14 -0
  30. package/src/const/external.ts +12 -0
  31. package/declaration/camera/BoundCamera.d.ts +0 -9
  32. package/declaration/camera/CircularCamera.d.ts +0 -37
  33. package/declaration/camera/LinearCamera.d.ts +0 -5
  34. package/src/camera/CircularCamera.ts +0 -268
  35. package/src/camera/LinearCamera.ts +0 -35
@@ -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.4.2
7
+ version: 4.5.0
8
8
  */
9
9
  import Component, { ComponentEvent } from '@egjs/component';
10
10
  import Axes, { PanInput } from '@egjs/axes';
@@ -240,10 +240,12 @@ function __read(o, n) {
240
240
 
241
241
  return ar;
242
242
  }
243
- function __spreadArray(to, from) {
244
- for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i];
243
+ /** @deprecated */
245
244
 
246
- return to;
245
+ function __spread() {
246
+ for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
247
+
248
+ return ar;
247
249
  }
248
250
 
249
251
  /*
@@ -423,6 +425,18 @@ var CLASS = {
423
425
  HIDDEN: "flicking-hidden",
424
426
  DEFAULT_VIRTUAL: "flicking-panel"
425
427
  };
428
+ /**
429
+ * An object with all possible {@link Flicking#circularFallback circularFallback}s
430
+ * @ko Flicking의 {@link Flicking#circularFallback circularFallback}에 설정 가능한 값들을 담고 있는 객체
431
+ * @type {object}
432
+ * @property {string} LINEAR "linear"
433
+ * @property {string} BOUND "bound"
434
+ */
435
+
436
+ var CIRCULAR_FALLBACK = {
437
+ LINEAR: "linear",
438
+ BOUND: "bound"
439
+ };
426
440
 
427
441
  var merge = function (target) {
428
442
  var sources = [];
@@ -606,7 +620,7 @@ var parseElement = function (element) {
606
620
  if (isString(el)) {
607
621
  var tempDiv = document.createElement("div");
608
622
  tempDiv.innerHTML = el;
609
- elements.push.apply(elements, __spreadArray([], __read(toArray(tempDiv.children))));
623
+ elements.push.apply(elements, __spread(toArray(tempDiv.children)));
610
624
 
611
625
  while (tempDiv.firstChild) {
612
626
  tempDiv.removeChild(tempDiv.firstChild);
@@ -2987,9 +3001,8 @@ function (_super) {
2987
3001
 
2988
3002
 
2989
3003
  function SnapControl(_a) {
2990
- var _b = _a === void 0 ? {} : _a,
2991
- _c = _b.count,
2992
- count = _c === void 0 ? Infinity : _c;
3004
+ var _b = (_a === void 0 ? {} : _a).count,
3005
+ count = _b === void 0 ? Infinity : _b;
2993
3006
 
2994
3007
  var _this = _super.call(this) || this;
2995
3008
 
@@ -3195,9 +3208,8 @@ function (_super) {
3195
3208
 
3196
3209
 
3197
3210
  function FreeControl(_a) {
3198
- var _b = _a === void 0 ? {} : _a,
3199
- _c = _b.stopAtEdge,
3200
- stopAtEdge = _c === void 0 ? true : _c;
3211
+ var _b = (_a === void 0 ? {} : _a).stopAtEdge,
3212
+ stopAtEdge = _b === void 0 ? true : _b;
3201
3213
 
3202
3214
  var _this = _super.call(this) || this;
3203
3215
 
@@ -3331,9 +3343,8 @@ function (_super) {
3331
3343
 
3332
3344
 
3333
3345
  function StrictControl(_a) {
3334
- var _b = _a === void 0 ? {} : _a,
3335
- _c = _b.count,
3336
- count = _c === void 0 ? 1 : _c;
3346
+ var _b = (_a === void 0 ? {} : _a).count,
3347
+ count = _b === void 0 ? 1 : _b;
3337
3348
 
3338
3349
  var _this = _super.call(this) || this;
3339
3350
 
@@ -3565,761 +3576,826 @@ function (_super) {
3565
3576
  }(Control);
3566
3577
 
3567
3578
  /**
3568
- * A component that manages actual movement inside the viewport
3569
- * @ko 뷰포트 내에서의 실제 움직임을 담당하는 컴포넌트
3579
+ * A mode of camera
3570
3580
  */
3571
3581
 
3572
- var Camera =
3582
+ var CameraMode =
3573
3583
  /*#__PURE__*/
3574
3584
  function () {
3575
3585
  /** */
3576
- function Camera(_a) {
3577
- var _this = this;
3586
+ function CameraMode(flicking) {
3587
+ this._flicking = flicking;
3588
+ }
3578
3589
 
3579
- var _b = _a === void 0 ? {} : _a,
3580
- _c = _b.align,
3581
- align = _c === void 0 ? ALIGN.CENTER : _c;
3590
+ var __proto = CameraMode.prototype;
3582
3591
 
3583
- this._checkTranslateSupport = function () {
3584
- var e_1, _a;
3592
+ __proto.getAnchors = function () {
3593
+ var panels = this._flicking.renderer.panels;
3594
+ return panels.map(function (panel, index) {
3595
+ return new AnchorPoint({
3596
+ index: index,
3597
+ position: panel.position,
3598
+ panel: panel
3599
+ });
3600
+ });
3601
+ };
3585
3602
 
3586
- var transforms = ["webkitTransform", "msTransform", "MozTransform", "OTransform", "transform"];
3587
- var supportedStyle = document.documentElement.style;
3588
- var transformName = "";
3603
+ __proto.findAnchorIncludePosition = function (position) {
3604
+ var anchors = this._flicking.camera.anchorPoints;
3605
+ var anchorsIncludingPosition = anchors.filter(function (anchor) {
3606
+ return anchor.panel.includePosition(position, true);
3607
+ });
3608
+ return anchorsIncludingPosition.reduce(function (nearest, anchor) {
3609
+ if (!nearest) return anchor;
3610
+ return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
3611
+ }, null);
3612
+ };
3589
3613
 
3590
- try {
3591
- for (var transforms_1 = __values(transforms), transforms_1_1 = transforms_1.next(); !transforms_1_1.done; transforms_1_1 = transforms_1.next()) {
3592
- var prefixedTransform = transforms_1_1.value;
3614
+ __proto.clampToReachablePosition = function (position) {
3615
+ var camera = this._flicking.camera;
3616
+ var range = camera.range;
3617
+ return clamp(position, range.min, range.max);
3618
+ };
3593
3619
 
3594
- if (prefixedTransform in supportedStyle) {
3595
- transformName = prefixedTransform;
3596
- }
3597
- }
3598
- } catch (e_1_1) {
3599
- e_1 = {
3600
- error: e_1_1
3601
- };
3602
- } finally {
3603
- try {
3604
- if (transforms_1_1 && !transforms_1_1.done && (_a = transforms_1.return)) _a.call(transforms_1);
3605
- } finally {
3606
- if (e_1) throw e_1.error;
3607
- }
3608
- }
3620
+ __proto.getCircularOffset = function () {
3621
+ return 0;
3622
+ };
3609
3623
 
3610
- if (!transformName) {
3611
- throw new FlickingError(MESSAGE.TRANSFORM_NOT_SUPPORTED, CODE.TRANSFORM_NOT_SUPPORTED);
3612
- }
3624
+ __proto.canReach = function (panel) {
3625
+ var camera = this._flicking.camera;
3626
+ var range = camera.range;
3627
+ if (panel.removed) return false;
3628
+ var panelPos = panel.position;
3629
+ return panelPos >= range.min && panelPos <= range.max;
3630
+ };
3613
3631
 
3614
- _this._transform = transformName;
3632
+ __proto.canSee = function (panel) {
3633
+ var camera = this._flicking.camera;
3634
+ var visibleRange = camera.visibleRange; // Should not include margin, as we don't declare what the margin is visible as what the panel is visible.
3635
+
3636
+ return panel.isVisibleOnRange(visibleRange.min, visibleRange.max);
3637
+ };
3638
+
3639
+ return CameraMode;
3640
+ }();
3641
+
3642
+ var LinearCameraMode =
3643
+ /*#__PURE__*/
3644
+ function (_super) {
3645
+ __extends(LinearCameraMode, _super);
3646
+
3647
+ function LinearCameraMode() {
3648
+ return _super !== null && _super.apply(this, arguments) || this;
3649
+ }
3650
+
3651
+ var __proto = LinearCameraMode.prototype;
3652
+
3653
+ __proto.checkAvailability = function () {
3654
+ // It's always available
3655
+ return true;
3656
+ };
3657
+
3658
+ __proto.getRange = function () {
3659
+ var _a, _b;
3660
+
3661
+ var renderer = this._flicking.renderer;
3662
+ var firstPanel = renderer.getPanel(0);
3663
+ var lastPanel = renderer.getPanel(renderer.panelCount - 1);
3664
+ return {
3665
+ min: (_a = firstPanel === null || firstPanel === void 0 ? void 0 : firstPanel.position) !== null && _a !== void 0 ? _a : 0,
3666
+ max: (_b = lastPanel === null || lastPanel === void 0 ? void 0 : lastPanel.position) !== null && _b !== void 0 ? _b : 0
3615
3667
  };
3668
+ };
3616
3669
 
3617
- this._flicking = null;
3670
+ return LinearCameraMode;
3671
+ }(CameraMode);
3618
3672
 
3619
- this._resetInternalValues(); // Options
3673
+ /**
3674
+ * A {@link Camera} mode that connects the last panel and the first panel, enabling continuous loop
3675
+ * @ko 첫번째 패널과 마지막 패널이 이어진 상태로, 무한히 회전할 수 있는 종류의 {@link Camera} 모드
3676
+ */
3620
3677
 
3678
+ var CircularCameraMode =
3679
+ /*#__PURE__*/
3680
+ function (_super) {
3681
+ __extends(CircularCameraMode, _super);
3621
3682
 
3622
- this._align = align;
3683
+ function CircularCameraMode() {
3684
+ return _super !== null && _super.apply(this, arguments) || this;
3623
3685
  }
3624
3686
 
3625
- var __proto = Camera.prototype;
3626
- Object.defineProperty(__proto, "element", {
3627
- // Internal states getter
3687
+ var __proto = CircularCameraMode.prototype;
3628
3688
 
3629
- /**
3630
- * The camera element(`.flicking-camera`)
3631
- * @ko 카메라 엘리먼트(`.flicking-camera`)
3632
- * @type {HTMLElement}
3633
- * @readonly
3634
- */
3635
- get: function () {
3636
- return this._el;
3637
- },
3638
- enumerable: false,
3639
- configurable: true
3640
- });
3641
- Object.defineProperty(__proto, "children", {
3642
- /**
3643
- * An array of the child elements of the camera element(`.flicking-camera`)
3644
- * @ko 카메라 엘리먼트(`.flicking-camera`) 자식 엘리먼트 배열
3645
- * @type {HTMLElement[]}
3646
- * @readonly
3647
- */
3648
- get: function () {
3649
- return toArray(this._el.children);
3650
- },
3651
- enumerable: false,
3652
- configurable: true
3653
- });
3654
- Object.defineProperty(__proto, "position", {
3655
- /**
3656
- * Current position of the camera
3657
- * @ko Camera의 현재 좌표
3658
- * @type {number}
3659
- * @readonly
3660
- */
3661
- get: function () {
3662
- return this._position;
3663
- },
3664
- enumerable: false,
3665
- configurable: true
3666
- });
3667
- Object.defineProperty(__proto, "alignPosition", {
3668
- /**
3669
- * Align position inside the viewport where {@link Panel}'s {@link Panel#alignPosition alignPosition} should be located at
3670
- * @ko 패널의 정렬 기준 위치. 뷰포트 내에서 {@link Panel}의 {@link Panel#alignPosition alignPosition}이 위치해야 하는 곳입니다
3671
- * @type {number}
3672
- * @readonly
3673
- */
3674
- get: function () {
3675
- return this._alignPos;
3676
- },
3677
- enumerable: false,
3678
- configurable: true
3679
- });
3680
- Object.defineProperty(__proto, "offset", {
3681
- /**
3682
- * Position offset, used for the {@link Flicking#renderOnlyVisible renderOnlyVisible} option
3683
- * @ko Camera의 좌표 오프셋. {@link Flicking#renderOnlyVisible renderOnlyVisible} 옵션을 위해 사용됩니다.
3684
- * @type {number}
3685
- * @default 0
3686
- * @readonly
3687
- */
3688
- get: function () {
3689
- return this._offset;
3690
- },
3691
- enumerable: false,
3692
- configurable: true
3693
- });
3694
- Object.defineProperty(__proto, "range", {
3695
- /**
3696
- * A range that Camera's {@link Camera#position position} can reach
3697
- * @ko Camera의 {@link Camera#position position}이 도달 가능한 범위
3698
- * @type {object}
3699
- * @property {number} min A minimum position<ko>최소 위치</ko>
3700
- * @property {number} max A maximum position<ko>최대 위치</ko>
3701
- * @readonly
3702
- */
3703
- get: function () {
3704
- return this._range;
3705
- },
3706
- enumerable: false,
3707
- configurable: true
3708
- });
3709
- Object.defineProperty(__proto, "rangeDiff", {
3710
- /**
3711
- * A difference between Camera's minimum and maximum position that can reach
3712
- * @ko Camera가 도달 가능한 최소/최대 좌표의 차이
3713
- * @type {number}
3714
- * @readonly
3715
- */
3716
- get: function () {
3717
- return this._range.max - this._range.min;
3718
- },
3719
- enumerable: false,
3720
- configurable: true
3721
- });
3722
- Object.defineProperty(__proto, "visiblePanels", {
3723
- /**
3724
- * An array of visible panels from the current position
3725
- * @ko 현재 보이는 패널들의 배열
3726
- * @type {Panel[]}
3727
- * @readonly
3728
- */
3729
- get: function () {
3730
- return this._visiblePanels;
3731
- },
3732
- enumerable: false,
3733
- configurable: true
3734
- });
3735
- Object.defineProperty(__proto, "visibleRange", {
3736
- /**
3737
- * A range of the visible area from the current position
3738
- * @ko 현재 위치에서 보이는 범위
3739
- * @type {object}
3740
- * @property {number} min A minimum position<ko>최소 위치</ko>
3741
- * @property {number} min A maximum position<ko>최대 위치</ko>
3742
- * @readonly
3743
- */
3744
- get: function () {
3689
+ __proto.checkAvailability = function () {
3690
+ var flicking = this._flicking;
3691
+ var renderer = flicking.renderer;
3692
+ var panels = renderer.panels;
3693
+
3694
+ if (panels.length <= 0) {
3695
+ return false;
3696
+ }
3697
+
3698
+ var firstPanel = panels[0];
3699
+ var lastPanel = panels[panels.length - 1];
3700
+ var firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
3701
+ var lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
3702
+ var visibleSize = flicking.camera.size;
3703
+ var panelSizeSum = lastPanelNext - firstPanelPrev;
3704
+ var canSetCircularMode = panels.every(function (panel) {
3705
+ return panelSizeSum - panel.size >= visibleSize;
3706
+ });
3707
+ return canSetCircularMode;
3708
+ };
3709
+
3710
+ __proto.getRange = function () {
3711
+ var flicking = this._flicking;
3712
+ var panels = flicking.renderer.panels;
3713
+
3714
+ if (panels.length <= 0) {
3745
3715
  return {
3746
- min: this._position - this._alignPos,
3747
- max: this._position - this._alignPos + this.size
3716
+ min: 0,
3717
+ max: 0
3748
3718
  };
3749
- },
3750
- enumerable: false,
3751
- configurable: true
3752
- });
3753
- Object.defineProperty(__proto, "anchorPoints", {
3754
- /**
3755
- * An array of {@link AnchorPoint}s that Camera can be stopped at
3756
- * @ko 카메라가 도달 가능한 {@link AnchorPoint}의 목록
3757
- * @type {AnchorPoint[]}
3758
- * @readonly
3759
- */
3760
- get: function () {
3761
- return this._anchors;
3762
- },
3763
- enumerable: false,
3764
- configurable: true
3765
- });
3766
- Object.defineProperty(__proto, "controlParams", {
3767
- /**
3768
- * A current parameters of the Camera for updating {@link AxesController}
3769
- * @ko {@link AxesController}를 업데이트하기 위한 현재 Camera 패러미터들
3770
- * @type {ControlParams}
3771
- * @readonly
3772
- */
3773
- get: function () {
3774
- return {
3775
- range: this._range,
3776
- position: this._position,
3777
- circular: false
3778
- };
3779
- },
3780
- enumerable: false,
3781
- configurable: true
3782
- });
3783
- Object.defineProperty(__proto, "atEdge", {
3784
- /**
3785
- * A Boolean value indicating whether Camera's over the minimum or maximum position reachable
3786
- * @ko 현재 카메라가 도달 가능한 범위의 최소 혹은 최대점을 넘어섰는지를 나타냅니다
3787
- * @type {boolean}
3788
- * @readonly
3789
- */
3790
- get: function () {
3791
- return this._position <= this._range.min || this._position >= this._range.max;
3792
- },
3793
- enumerable: false,
3794
- configurable: true
3795
- });
3796
- Object.defineProperty(__proto, "size", {
3797
- /**
3798
- * Return the size of the viewport
3799
- * @ko 뷰포트 크기를 반환합니다
3800
- * @type {number}
3801
- * @readonly
3802
- */
3803
- get: function () {
3804
- var flicking = this._flicking;
3805
- return flicking ? flicking.horizontal ? flicking.viewport.width : flicking.viewport.height : 0;
3806
- },
3807
- enumerable: false,
3808
- configurable: true
3809
- });
3810
- Object.defineProperty(__proto, "progress", {
3811
- /**
3812
- * Return the camera's position progress from the first panel to last panel
3813
- * Range is from 0 to last panel's index
3814
- * @ko 첫번째 패널로부터 마지막 패널까지의 카메라 위치의 진행도를 반환합니다
3815
- * 범위는 0부터 마지막 패널의 인덱스까지입니다
3816
- * @type {number}
3817
- * @readonly
3818
- */
3819
- get: function () {
3820
- var flicking = this._flicking;
3821
- var position = this._position + this._offset;
3822
- var nearestAnchor = this.findNearestAnchor(this._position);
3719
+ }
3823
3720
 
3824
- if (!flicking || !nearestAnchor) {
3825
- return NaN;
3826
- }
3721
+ var firstPanel = panels[0];
3722
+ var lastPanel = panels[panels.length - 1];
3723
+ var firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
3724
+ var lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
3725
+ return {
3726
+ min: firstPanelPrev,
3727
+ max: lastPanelNext
3728
+ };
3729
+ };
3827
3730
 
3828
- var nearestPanel = nearestAnchor.panel;
3829
- var panelPos = nearestPanel.position + nearestPanel.offset;
3830
- var bounceSize = flicking.control.controller.bounce;
3831
- var _a = this.range,
3832
- prevRange = _a.min,
3833
- nextRange = _a.max;
3834
- var rangeDiff = this.rangeDiff;
3731
+ __proto.getAnchors = function () {
3732
+ var flicking = this._flicking;
3733
+ var panels = flicking.renderer.panels;
3734
+ return panels.map(function (panel, index) {
3735
+ return new AnchorPoint({
3736
+ index: index,
3737
+ position: panel.position,
3738
+ panel: panel
3739
+ });
3740
+ });
3741
+ };
3835
3742
 
3836
- if (position === panelPos) {
3837
- return nearestPanel.index;
3838
- }
3743
+ __proto.findAnchorIncludePosition = function (position) {
3744
+ var camera = this._flicking.camera;
3745
+ var range = camera.range;
3746
+ var anchors = camera.anchorPoints;
3747
+ var rangeDiff = camera.rangeDiff;
3748
+ var anchorCount = anchors.length;
3749
+ var positionInRange = circulatePosition(position, range.min, range.max);
3839
3750
 
3840
- if (position < panelPos) {
3841
- var prevPanel = nearestPanel.prev();
3842
- var prevPosition = prevPanel ? prevPanel.position + prevPanel.offset : prevRange - bounceSize[0]; // Looped
3751
+ var anchorInRange = _super.prototype.findAnchorIncludePosition.call(this, positionInRange);
3843
3752
 
3844
- if (prevPosition > panelPos) {
3845
- prevPosition -= rangeDiff;
3846
- }
3753
+ if (anchorCount > 0 && (position === range.min || position === range.max)) {
3754
+ var possibleAnchors = [anchorInRange, new AnchorPoint({
3755
+ index: 0,
3756
+ position: anchors[0].position + rangeDiff,
3757
+ panel: anchors[0].panel
3758
+ }), new AnchorPoint({
3759
+ index: anchorCount - 1,
3760
+ position: anchors[anchorCount - 1].position - rangeDiff,
3761
+ panel: anchors[anchorCount - 1].panel
3762
+ })].filter(function (anchor) {
3763
+ return !!anchor;
3764
+ });
3765
+ anchorInRange = possibleAnchors.reduce(function (nearest, anchor) {
3766
+ if (!nearest) return anchor;
3767
+ return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
3768
+ }, null);
3769
+ }
3847
3770
 
3848
- return nearestPanel.index - 1 + getProgress(position, prevPosition, panelPos);
3849
- } else {
3850
- var nextPanel = nearestPanel.next();
3851
- var nextPosition = nextPanel ? nextPanel.position + nextPanel.offset : nextRange + bounceSize[1]; // Looped
3771
+ if (!anchorInRange) return null;
3852
3772
 
3853
- if (nextPosition < panelPos) {
3854
- nextPosition += rangeDiff;
3855
- }
3773
+ if (position < range.min) {
3774
+ var loopCount = -Math.floor((range.min - position) / rangeDiff) - 1;
3775
+ return new AnchorPoint({
3776
+ index: anchorInRange.index,
3777
+ position: anchorInRange.position + rangeDiff * loopCount,
3778
+ panel: anchorInRange.panel
3779
+ });
3780
+ } else if (position > range.max) {
3781
+ var loopCount = Math.floor((position - range.max) / rangeDiff) + 1;
3782
+ return new AnchorPoint({
3783
+ index: anchorInRange.index,
3784
+ position: anchorInRange.position + rangeDiff * loopCount,
3785
+ panel: anchorInRange.panel
3786
+ });
3787
+ }
3856
3788
 
3857
- return nearestPanel.index + getProgress(position, panelPos, nextPosition);
3858
- }
3859
- },
3860
- enumerable: false,
3861
- configurable: true
3862
- });
3863
- Object.defineProperty(__proto, "align", {
3864
- // Options Getter
3789
+ return anchorInRange;
3790
+ };
3865
3791
 
3866
- /**
3867
- * A value indicating where the {@link Camera#alignPosition alignPosition} should be located at inside the viewport element
3868
- * @ko {@link Camera#alignPosition alignPosition}이 뷰포트 엘리먼트 내의 어디에 위치해야 하는지를 나타내는 값
3869
- * @type {ALIGN | string | number}
3870
- */
3871
- get: function () {
3872
- return this._align;
3873
- },
3874
- // Options Setter
3875
- set: function (val) {
3876
- this._align = val;
3877
- },
3878
- enumerable: false,
3879
- configurable: true
3880
- });
3881
- /**
3882
- * Initialize Camera
3883
- * @ko Camera를 초기화합니다
3884
- * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>
3885
- * @chainable
3886
- * @throws {FlickingError}
3887
- * {@link ERROR_CODE VAL_MUST_NOT_NULL} If the camera element(`.flicking-camera`) does not exist inside viewport element
3888
- * <ko>{@link ERROR_CODE VAL_MUST_NOT_NULL} 뷰포트 엘리먼트 내부에 카메라 엘리먼트(`.flicking-camera`)가 존재하지 않을 경우</ko>
3889
- * @return {this}
3890
- */
3792
+ __proto.getCircularOffset = function () {
3793
+ var flicking = this._flicking;
3794
+ var camera = flicking.camera;
3795
+ if (!camera.circularEnabled) return 0;
3796
+ var toggled = flicking.panels.filter(function (panel) {
3797
+ return panel.toggled;
3798
+ });
3799
+ var toggledPrev = toggled.filter(function (panel) {
3800
+ return panel.toggleDirection === DIRECTION.PREV;
3801
+ });
3802
+ var toggledNext = toggled.filter(function (panel) {
3803
+ return panel.toggleDirection === DIRECTION.NEXT;
3804
+ });
3805
+ return this._calcPanelAreaSum(toggledPrev) - this._calcPanelAreaSum(toggledNext);
3806
+ };
3891
3807
 
3892
- __proto.init = function (flicking) {
3893
- this._flicking = flicking;
3894
- var viewportEl = flicking.viewport.element;
3895
- checkExistence(viewportEl.firstElementChild, "First element child of the viewport element");
3896
- this._el = viewportEl.firstElementChild;
3808
+ __proto.clampToReachablePosition = function (position) {
3809
+ // Basically all position is reachable for circular camera
3810
+ return position;
3811
+ };
3897
3812
 
3898
- this._checkTranslateSupport();
3813
+ __proto.canReach = function (panel) {
3814
+ if (panel.removed) return false; // Always reachable on circular mode
3899
3815
 
3900
- return this;
3816
+ return true;
3901
3817
  };
3902
- /**
3903
- * Destroy Camera and return to initial state
3904
- * @ko Camera를 초기 상태로 되돌립니다
3905
- * @return {void}
3906
- */
3907
-
3908
3818
 
3909
- __proto.destroy = function () {
3910
- this._flicking = null;
3819
+ __proto.canSee = function (panel) {
3820
+ var camera = this._flicking.camera;
3821
+ var range = camera.range;
3822
+ var rangeDiff = camera.rangeDiff;
3823
+ var visibleRange = camera.visibleRange;
3911
3824
 
3912
- this._resetInternalValues();
3825
+ var visibleInCurrentRange = _super.prototype.canSee.call(this, panel); // Check looped visible area for circular case
3913
3826
 
3914
- return this;
3915
- };
3916
- /**
3917
- * Move to the given position and apply CSS transform
3918
- * @ko 해당 좌표로 이동하고, CSS transform을 적용합니다
3919
- * @param {number} pos A new position<ko>움직일 위치</ko>
3920
- * @throws {FlickingError}
3921
- * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
3922
- * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
3923
- * @return {this}
3924
- */
3925
3827
 
3828
+ if (visibleRange.min < range.min) {
3829
+ return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff);
3830
+ } else if (visibleRange.max > range.max) {
3831
+ return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff);
3832
+ }
3926
3833
 
3927
- __proto.lookAt = function (pos) {
3928
- var prevPos = this._position;
3929
- this._position = pos;
3834
+ return visibleInCurrentRange;
3835
+ };
3930
3836
 
3931
- this._refreshVisiblePanels();
3837
+ __proto._calcPanelAreaSum = function (panels) {
3838
+ return panels.reduce(function (sum, panel) {
3839
+ return sum + panel.sizeIncludingMargin;
3840
+ }, 0);
3841
+ };
3932
3842
 
3933
- this._checkNeedPanel();
3843
+ return CircularCameraMode;
3844
+ }(CameraMode);
3934
3845
 
3935
- this._checkReachEnd(prevPos, pos);
3846
+ var BoundCameraMode =
3847
+ /*#__PURE__*/
3848
+ function (_super) {
3849
+ __extends(BoundCameraMode, _super);
3936
3850
 
3937
- this.applyTransform();
3938
- };
3939
- /**
3940
- * Return a previous {@link AnchorPoint} of given {@link AnchorPoint}
3941
- * If it does not exist, return `null` instead
3942
- * @ko 주어진 {@link AnchorPoint}의 이전 {@link AnchorPoint}를 반환합니다
3943
- * 존재하지 않을 경우 `null`을 반환합니다
3944
- * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>
3945
- * @return {AnchorPoint | null} The previous {@link AnchorPoint}<ko>이전 {@link AnchorPoint}</ko>
3946
- */
3851
+ function BoundCameraMode() {
3852
+ return _super !== null && _super.apply(this, arguments) || this;
3853
+ }
3947
3854
 
3855
+ var __proto = BoundCameraMode.prototype;
3948
3856
 
3949
- __proto.getPrevAnchor = function (anchor) {
3950
- return this._anchors[anchor.index - 1] || null;
3951
- };
3952
- /**
3953
- * Return a next {@link AnchorPoint} of given {@link AnchorPoint}
3954
- * If it does not exist, return `null` instead
3955
- * @ko 주어진 {@link AnchorPoint}의 다음 {@link AnchorPoint}를 반환합니다
3956
- * 존재하지 않을 경우 `null`을 반환합니다
3957
- * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>
3958
- * @return {AnchorPoint | null} The next {@link AnchorPoint}<ko>다음 {@link AnchorPoint}</ko>
3959
- */
3857
+ __proto.checkAvailability = function () {
3858
+ var flicking = this._flicking;
3859
+ var renderer = flicking.renderer;
3860
+ var firstPanel = renderer.getPanel(0);
3861
+ var lastPanel = renderer.getPanel(renderer.panelCount - 1);
3960
3862
 
3863
+ if (!firstPanel || !lastPanel) {
3864
+ return false;
3865
+ }
3961
3866
 
3962
- __proto.getNextAnchor = function (anchor) {
3963
- return this._anchors[anchor.index + 1] || null;
3867
+ var viewportSize = flicking.camera.size;
3868
+ var firstPanelPrev = firstPanel.range.min;
3869
+ var lastPanelNext = lastPanel.range.max;
3870
+ var panelAreaSize = lastPanelNext - firstPanelPrev;
3871
+ var isBiggerThanViewport = viewportSize < panelAreaSize;
3872
+ return isBiggerThanViewport;
3964
3873
  };
3965
- /**
3966
- * Return the camera's position progress in the panel below
3967
- * Value is from 0 to 1 when the camera's inside panel
3968
- * Value can be lower than 0 or bigger than 1 when it's in the margin area
3969
- * @ko 현재 카메라 아래 패널에서의 위치 진행도를 반환합니다
3970
- * 반환값은 카메라가 패널 내부에 있을 경우 0부터 1까지의 값을 갖습니다
3971
- * 패널의 margin 영역에 있을 경우 0보다 작거나 1보다 큰 값을 반환할 수 있습니다
3972
- */
3973
3874
 
3875
+ __proto.getRange = function () {
3876
+ var flicking = this._flicking;
3877
+ var renderer = flicking.renderer;
3878
+ var alignPos = flicking.camera.alignPosition;
3879
+ var firstPanel = renderer.getPanel(0);
3880
+ var lastPanel = renderer.getPanel(renderer.panelCount - 1);
3881
+
3882
+ if (!firstPanel || !lastPanel) {
3883
+ return {
3884
+ min: 0,
3885
+ max: 0
3886
+ };
3887
+ }
3974
3888
 
3975
- __proto.getProgressInPanel = function (panel) {
3976
- var panelRange = panel.range;
3977
- return (this._position - panelRange.min) / (panelRange.max - panelRange.min);
3889
+ var viewportSize = flicking.camera.size;
3890
+ var firstPanelPrev = firstPanel.range.min;
3891
+ var lastPanelNext = lastPanel.range.max;
3892
+ var panelAreaSize = lastPanelNext - firstPanelPrev;
3893
+ var isBiggerThanViewport = viewportSize < panelAreaSize;
3894
+ var firstPos = firstPanelPrev + alignPos;
3895
+ var lastPos = lastPanelNext - viewportSize + alignPos;
3896
+
3897
+ if (isBiggerThanViewport) {
3898
+ return {
3899
+ min: firstPos,
3900
+ max: lastPos
3901
+ };
3902
+ } else {
3903
+ var align = flicking.camera.align;
3904
+ var alignVal = typeof align === "object" ? align.camera : align;
3905
+ var pos = firstPos + parseAlign$1(alignVal, lastPos - firstPos);
3906
+ return {
3907
+ min: pos,
3908
+ max: pos
3909
+ };
3910
+ }
3978
3911
  };
3979
- /**
3980
- * Return {@link AnchorPoint} that includes given position
3981
- * If there's no {@link AnchorPoint} that includes the given position, return `null` instead
3982
- * @ko 주어진 좌표를 포함하는 {@link AnchorPoint}를 반환합니다
3983
- * 주어진 좌표를 포함하는 {@link AnchorPoint}가 없을 경우 `null`을 반환합니다
3984
- * @param {number} position A position to check<ko>확인할 좌표</ko>
3985
- * @return {AnchorPoint | null} The {@link AnchorPoint} that includes the given position<ko>해당 좌표를 포함하는 {@link AnchorPoint}</ko>
3986
- */
3987
3912
 
3913
+ __proto.getAnchors = function () {
3914
+ var flicking = this._flicking;
3915
+ var camera = flicking.camera;
3916
+ var panels = flicking.renderer.panels;
3988
3917
 
3989
- __proto.findAnchorIncludePosition = function (position) {
3990
- var anchors = this._anchors;
3991
- var anchorsIncludingPosition = anchors.filter(function (anchor) {
3992
- return anchor.panel.includePosition(position, true);
3918
+ if (panels.length <= 0) {
3919
+ return [];
3920
+ }
3921
+
3922
+ var range = flicking.camera.range;
3923
+ var reachablePanels = panels.filter(function (panel) {
3924
+ return camera.canReach(panel);
3993
3925
  });
3994
- return anchorsIncludingPosition.reduce(function (nearest, anchor) {
3995
- if (!nearest) return anchor;
3996
- return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
3997
- }, null);
3998
- };
3999
- /**
4000
- * Return {@link AnchorPoint} nearest to given position
4001
- * If there're no {@link AnchorPoint}s, return `null` instead
4002
- * @ko 해당 좌표에서 가장 가까운 {@link AnchorPoint}를 반환합니다
4003
- * {@link AnchorPoint}가 하나도 없을 경우 `null`을 반환합니다
4004
- * @param {number} position A position to check<ko>확인할 좌표</ko>
4005
- * @return {AnchorPoint | null} The {@link AnchorPoint} nearest to the given position<ko>해당 좌표에 가장 인접한 {@link AnchorPoint}</ko>
4006
- */
4007
3926
 
3927
+ if (reachablePanels.length > 0) {
3928
+ var shouldPrependBoundAnchor = reachablePanels[0].position !== range.min;
3929
+ var shouldAppendBoundAnchor = reachablePanels[reachablePanels.length - 1].position !== range.max;
3930
+ var indexOffset_1 = shouldPrependBoundAnchor ? 1 : 0;
3931
+ var newAnchors = reachablePanels.map(function (panel, idx) {
3932
+ return new AnchorPoint({
3933
+ index: idx + indexOffset_1,
3934
+ position: panel.position,
3935
+ panel: panel
3936
+ });
3937
+ });
4008
3938
 
4009
- __proto.findNearestAnchor = function (position) {
4010
- var anchors = this._anchors;
3939
+ if (shouldPrependBoundAnchor) {
3940
+ newAnchors.splice(0, 0, new AnchorPoint({
3941
+ index: 0,
3942
+ position: range.min,
3943
+ panel: panels[reachablePanels[0].index - 1]
3944
+ }));
3945
+ }
3946
+
3947
+ if (shouldAppendBoundAnchor) {
3948
+ newAnchors.push(new AnchorPoint({
3949
+ index: newAnchors.length,
3950
+ position: range.max,
3951
+ panel: panels[reachablePanels[reachablePanels.length - 1].index + 1]
3952
+ }));
3953
+ }
3954
+
3955
+ return newAnchors;
3956
+ } else if (range.min !== range.max) {
3957
+ // There're more than 2 panels
3958
+ var nearestPanelAtMin = this._findNearestPanel(range.min, panels);
3959
+
3960
+ var panelAtMin = nearestPanelAtMin.index === panels.length - 1 ? nearestPanelAtMin.prev() : nearestPanelAtMin;
3961
+ var panelAtMax = panelAtMin.next();
3962
+ return [new AnchorPoint({
3963
+ index: 0,
3964
+ position: range.min,
3965
+ panel: panelAtMin
3966
+ }), new AnchorPoint({
3967
+ index: 1,
3968
+ position: range.max,
3969
+ panel: panelAtMax
3970
+ })];
3971
+ } else {
3972
+ return [new AnchorPoint({
3973
+ index: 0,
3974
+ position: range.min,
3975
+ panel: this._findNearestPanel(range.min, panels)
3976
+ })];
3977
+ }
3978
+ };
3979
+
3980
+ __proto.findAnchorIncludePosition = function (position) {
3981
+ var camera = this._flicking.camera;
3982
+ var range = camera.range;
3983
+ var anchors = camera.anchorPoints;
4011
3984
  if (anchors.length <= 0) return null;
3985
+
3986
+ if (position <= range.min) {
3987
+ return anchors[0];
3988
+ } else if (position >= range.max) {
3989
+ return anchors[anchors.length - 1];
3990
+ } else {
3991
+ return _super.prototype.findAnchorIncludePosition.call(this, position);
3992
+ }
3993
+ };
3994
+
3995
+ __proto._findNearestPanel = function (pos, panels) {
4012
3996
  var prevDist = Infinity;
4013
3997
 
4014
- for (var anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
4015
- var anchor = anchors[anchorIdx];
4016
- var dist = Math.abs(anchor.position - position);
3998
+ for (var panelIdx = 0; panelIdx < panels.length; panelIdx++) {
3999
+ var panel = panels[panelIdx];
4000
+ var dist = Math.abs(panel.position - pos);
4017
4001
 
4018
4002
  if (dist > prevDist) {
4019
4003
  // Return previous anchor
4020
- return anchors[anchorIdx - 1];
4004
+ return panels[panelIdx - 1];
4021
4005
  }
4022
4006
 
4023
4007
  prevDist = dist;
4024
4008
  } // Return last anchor
4025
4009
 
4026
4010
 
4027
- return anchors[anchors.length - 1];
4011
+ return panels[panels.length - 1];
4028
4012
  };
4029
- /**
4030
- * Return {@link AnchorPoint} that matches {@link Flicking#currentPanel}
4031
- * @ko 현재 {@link Flicking#currentPanel}에 해당하는 {@link AnchorPoint}를 반환합니다
4032
- * @return {AnchorPoint | null}
4033
- */
4034
-
4035
4013
 
4036
- __proto.findActiveAnchor = function () {
4037
- var flicking = getFlickingAttached(this._flicking);
4038
- var activeIndex = flicking.control.activeIndex;
4039
- return find(this._anchors, function (anchor) {
4040
- return anchor.panel.index === activeIndex;
4041
- });
4042
- };
4043
- /**
4044
- * Clamp the given position between camera's range
4045
- * @ko 주어진 좌표를 Camera가 도달 가능한 범위 사이의 값으로 만듭니다
4046
- * @param {number} position A position to clamp<ko>범위를 제한할 좌표</ko>
4047
- * @return {number} A clamped position<ko>범위 제한된 좌표</ko>
4048
- */
4014
+ return BoundCameraMode;
4015
+ }(CameraMode);
4049
4016
 
4017
+ /**
4018
+ * A component that manages actual movement inside the viewport
4019
+ * @ko 뷰포트 내에서의 실제 움직임을 담당하는 컴포넌트
4020
+ */
4050
4021
 
4051
- __proto.clampToReachablePosition = function (position) {
4052
- var range = this._range;
4053
- return clamp(position, range.min, range.max);
4054
- };
4055
- /**
4056
- * Check whether the given panel is inside of the Camera's range
4057
- * @ko 해당 {@link Panel}이 Camera가 도달 가능한 범위 내에 있는지를 반환합니다
4058
- * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>
4059
- * @return {boolean} Whether the panel's inside Camera's range<ko>도달 가능한 범위 내에 해당 패널이 존재하는지 여부</ko>
4060
- */
4022
+ var Camera =
4023
+ /*#__PURE__*/
4024
+ function () {
4025
+ /** */
4026
+ function Camera(_a) {
4027
+ var _this = this;
4061
4028
 
4029
+ var _b = (_a === void 0 ? {} : _a).align,
4030
+ align = _b === void 0 ? ALIGN.CENTER : _b;
4062
4031
 
4063
- __proto.canReach = function (panel) {
4064
- var range = this._range;
4065
- if (panel.removed) return false;
4066
- var panelPos = panel.position;
4067
- return panelPos >= range.min && panelPos <= range.max;
4068
- };
4069
- /**
4070
- * Check whether the given panel element is visible at the current position
4071
- * @ko 현재 좌표에서 해당 패널 엘리먼트를 볼 수 있는지 여부를 반환합니다
4072
- * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>
4073
- * @return Whether the panel element is visible at the current position<ko>현재 위치에서 해당 패널 엘리먼트가 보이는지 여부</ko>
4074
- */
4032
+ this._checkTranslateSupport = function () {
4033
+ var e_1, _a;
4075
4034
 
4035
+ var transforms = ["webkitTransform", "msTransform", "MozTransform", "OTransform", "transform"];
4036
+ var supportedStyle = document.documentElement.style;
4037
+ var transformName = "";
4076
4038
 
4077
- __proto.canSee = function (panel) {
4078
- var visibleRange = this.visibleRange; // Should not include margin, as we don't declare what the margin is visible as what the panel is visible.
4039
+ try {
4040
+ for (var transforms_1 = __values(transforms), transforms_1_1 = transforms_1.next(); !transforms_1_1.done; transforms_1_1 = transforms_1.next()) {
4041
+ var prefixedTransform = transforms_1_1.value;
4079
4042
 
4080
- return panel.isVisibleOnRange(visibleRange.min, visibleRange.max);
4081
- };
4082
- /**
4083
- * Update Camera's {@link Camera#alignPosition alignPosition}
4084
- * @ko Camera의 {@link Camera#alignPosition alignPosition}을 업데이트합니다
4085
- * @chainable
4086
- * @return {this}
4087
- */
4043
+ if (prefixedTransform in supportedStyle) {
4044
+ transformName = prefixedTransform;
4045
+ }
4046
+ }
4047
+ } catch (e_1_1) {
4048
+ e_1 = {
4049
+ error: e_1_1
4050
+ };
4051
+ } finally {
4052
+ try {
4053
+ if (transforms_1_1 && !transforms_1_1.done && (_a = transforms_1.return)) _a.call(transforms_1);
4054
+ } finally {
4055
+ if (e_1) throw e_1.error;
4056
+ }
4057
+ }
4088
4058
 
4059
+ if (!transformName) {
4060
+ throw new FlickingError(MESSAGE.TRANSFORM_NOT_SUPPORTED, CODE.TRANSFORM_NOT_SUPPORTED);
4061
+ }
4089
4062
 
4090
- __proto.updateAlignPos = function () {
4091
- var align = this._align;
4092
- var alignVal = typeof align === "object" ? align.camera : align;
4093
- this._alignPos = parseAlign$1(alignVal, this.size);
4094
- return this;
4095
- };
4096
- /**
4097
- * Update Camera's {@link Camera#anchorPoints anchorPoints}
4098
- * @ko Camera의 {@link Camera#anchorPoints anchorPoints}를 업데이트합니다
4099
- * @throws {FlickingError}
4100
- * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
4101
- * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
4102
- * @chainable
4103
- * @return {this}
4104
- */
4105
-
4106
-
4107
- __proto.updateAnchors = function () {
4108
- var flicking = getFlickingAttached(this._flicking);
4109
- var panels = flicking.renderer.panels;
4110
- this._anchors = panels.map(function (panel, index) {
4111
- return new AnchorPoint({
4112
- index: index,
4113
- position: panel.position,
4114
- panel: panel
4115
- });
4116
- });
4117
- return this;
4118
- };
4119
- /**
4120
- * Update Viewport's height to active panel's height
4121
- * @ko 현재 선택된 패널의 높이와 동일하도록 뷰포트의 높이를 업데이트합니다
4122
- * @throws {FlickingError}
4123
- * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
4124
- * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
4125
- * @chainable
4126
- * @return {this}
4127
- */
4128
-
4129
-
4130
- __proto.updateAdaptiveHeight = function () {
4131
- var flicking = getFlickingAttached(this._flicking);
4132
- var activePanel = flicking.control.activePanel;
4133
- if (!flicking.horizontal || !flicking.adaptive || !activePanel) return;
4134
- flicking.viewport.setSize({
4135
- height: activePanel.height
4136
- });
4137
- };
4138
- /**
4139
- * Update current offset of the camera
4140
- * @ko 현재 카메라의 오프셋을 업데이트합니다
4141
- * @chainable
4142
- * @return {this}
4143
- */
4144
-
4145
-
4146
- __proto.updateOffset = function () {
4147
- var flicking = getFlickingAttached(this._flicking);
4148
- var position = this._position;
4149
- var unRenderedPanels = flicking.panels.filter(function (panel) {
4150
- return !panel.rendered;
4151
- });
4152
- this._offset = unRenderedPanels.filter(function (panel) {
4153
- return panel.position + panel.offset < position;
4154
- }).reduce(function (offset, panel) {
4155
- return offset + panel.sizeIncludingMargin;
4156
- }, 0);
4157
- this.applyTransform();
4158
- return this;
4159
- };
4160
- /**
4161
- * Reset the history of {@link Flicking#event:needPanel needPanel} events so it can be triggered again
4162
- * @ko 발생한 {@link Flicking#event:needPanel needPanel} 이벤트들을 초기화하여 다시 발생할 수 있도록 합니다
4163
- * @chainable
4164
- * @return {this}
4165
- */
4166
-
4167
-
4168
- __proto.resetNeedPanelHistory = function () {
4169
- this._needPanelTriggered = {
4170
- prev: false,
4171
- next: false
4063
+ _this._transform = transformName;
4172
4064
  };
4173
- return this;
4174
- };
4175
- /**
4176
- * Apply "transform" style with the current position to camera element
4177
- * @ko 현재 위치를 기준으로한 transform 스타일을 카메라 엘리먼트에 적용합니다.
4178
- * @chainable
4179
- * @return {this}
4180
- */
4181
4065
 
4066
+ this._flicking = null;
4182
4067
 
4183
- __proto.applyTransform = function () {
4184
- var el = this._el;
4185
- var flicking = getFlickingAttached(this._flicking);
4186
- var actualPosition = this._position - this._alignPos - this._offset;
4187
- el.style[this._transform] = flicking.horizontal ? "translate(" + -actualPosition + "px)" : "translate(0, " + -actualPosition + "px)";
4188
- return this;
4189
- };
4068
+ this._resetInternalValues(); // Options
4190
4069
 
4191
- __proto._resetInternalValues = function () {
4192
- this._position = 0;
4193
- this._alignPos = 0;
4194
- this._offset = 0;
4195
- this._range = {
4196
- min: 0,
4197
- max: 0
4198
- };
4199
- this._visiblePanels = [];
4200
- this._anchors = [];
4201
- this._needPanelTriggered = {
4202
- prev: false,
4203
- next: false
4204
- };
4205
- };
4206
4070
 
4207
- __proto._refreshVisiblePanels = function () {
4208
- var _this = this;
4071
+ this._align = align;
4072
+ }
4209
4073
 
4210
- var flicking = getFlickingAttached(this._flicking);
4211
- var panels = flicking.renderer.panels;
4212
- var newVisiblePanels = panels.filter(function (panel) {
4213
- return _this.canSee(panel);
4214
- });
4215
- var prevVisiblePanels = this._visiblePanels;
4216
- this._visiblePanels = newVisiblePanels;
4217
- var added = newVisiblePanels.filter(function (panel) {
4218
- return !includes(prevVisiblePanels, panel);
4219
- });
4220
- var removed = prevVisiblePanels.filter(function (panel) {
4221
- return !includes(newVisiblePanels, panel);
4222
- });
4074
+ var __proto = Camera.prototype;
4075
+ Object.defineProperty(__proto, "element", {
4076
+ // Internal states getter
4077
+
4078
+ /**
4079
+ * The camera element(`.flicking-camera`)
4080
+ * @ko 카메라 엘리먼트(`.flicking-camera`)
4081
+ * @type {HTMLElement}
4082
+ * @readonly
4083
+ */
4084
+ get: function () {
4085
+ return this._el;
4086
+ },
4087
+ enumerable: false,
4088
+ configurable: true
4089
+ });
4090
+ Object.defineProperty(__proto, "children", {
4091
+ /**
4092
+ * An array of the child elements of the camera element(`.flicking-camera`)
4093
+ * @ko 카메라 엘리먼트(`.flicking-camera`)의 자식 엘리먼트 배열
4094
+ * @type {HTMLElement[]}
4095
+ * @readonly
4096
+ */
4097
+ get: function () {
4098
+ return toArray(this._el.children);
4099
+ },
4100
+ enumerable: false,
4101
+ configurable: true
4102
+ });
4103
+ Object.defineProperty(__proto, "position", {
4104
+ /**
4105
+ * Current position of the camera
4106
+ * @ko Camera의 현재 좌표
4107
+ * @type {number}
4108
+ * @readonly
4109
+ */
4110
+ get: function () {
4111
+ return this._position;
4112
+ },
4113
+ enumerable: false,
4114
+ configurable: true
4115
+ });
4116
+ Object.defineProperty(__proto, "alignPosition", {
4117
+ /**
4118
+ * Align position inside the viewport where {@link Panel}'s {@link Panel#alignPosition alignPosition} should be located at
4119
+ * @ko 패널의 정렬 기준 위치. 뷰포트 내에서 {@link Panel}의 {@link Panel#alignPosition alignPosition}이 위치해야 하는 곳입니다
4120
+ * @type {number}
4121
+ * @readonly
4122
+ */
4123
+ get: function () {
4124
+ return this._alignPos;
4125
+ },
4126
+ enumerable: false,
4127
+ configurable: true
4128
+ });
4129
+ Object.defineProperty(__proto, "offset", {
4130
+ /**
4131
+ * Position offset, used for the {@link Flicking#renderOnlyVisible renderOnlyVisible} option
4132
+ * @ko Camera의 좌표 오프셋. {@link Flicking#renderOnlyVisible renderOnlyVisible} 옵션을 위해 사용됩니다.
4133
+ * @type {number}
4134
+ * @default 0
4135
+ * @readonly
4136
+ */
4137
+ get: function () {
4138
+ return this._offset - this._circularOffset;
4139
+ },
4140
+ enumerable: false,
4141
+ configurable: true
4142
+ });
4143
+ Object.defineProperty(__proto, "circularEnabled", {
4144
+ /**
4145
+ * Whether the `circular` option is enabled.
4146
+ * The {@link Flicking#circular circular} option can't be enabled when sum of the panel sizes are too small.
4147
+ * @ko {@link Flicking#circular circular} 옵션이 활성화되었는지 여부를 나타내는 멤버 변수.
4148
+ * {@link Flicking#circular circular} 옵션은 패널의 크기의 합이 충분하지 않을 경우 비활성화됩니다.
4149
+ * @type {boolean}
4150
+ * @default false
4151
+ * @readonly
4152
+ */
4153
+ get: function () {
4154
+ return this._circularEnabled;
4155
+ },
4156
+ enumerable: false,
4157
+ configurable: true
4158
+ });
4159
+ Object.defineProperty(__proto, "mode", {
4160
+ /**
4161
+ * A current camera mode
4162
+ * @type {CameraMode}
4163
+ * @readonly
4164
+ */
4165
+ get: function () {
4166
+ return this._mode;
4167
+ },
4168
+ enumerable: false,
4169
+ configurable: true
4170
+ });
4171
+ Object.defineProperty(__proto, "range", {
4172
+ /**
4173
+ * A range that Camera's {@link Camera#position position} can reach
4174
+ * @ko Camera의 {@link Camera#position position}이 도달 가능한 범위
4175
+ * @type {object}
4176
+ * @property {number} min A minimum position<ko>최소 위치</ko>
4177
+ * @property {number} max A maximum position<ko>최대 위치</ko>
4178
+ * @readonly
4179
+ */
4180
+ get: function () {
4181
+ return this._range;
4182
+ },
4183
+ enumerable: false,
4184
+ configurable: true
4185
+ });
4186
+ Object.defineProperty(__proto, "rangeDiff", {
4187
+ /**
4188
+ * A difference between Camera's minimum and maximum position that can reach
4189
+ * @ko Camera가 도달 가능한 최소/최대 좌표의 차이
4190
+ * @type {number}
4191
+ * @readonly
4192
+ */
4193
+ get: function () {
4194
+ return this._range.max - this._range.min;
4195
+ },
4196
+ enumerable: false,
4197
+ configurable: true
4198
+ });
4199
+ Object.defineProperty(__proto, "visiblePanels", {
4200
+ /**
4201
+ * An array of visible panels from the current position
4202
+ * @ko 현재 보이는 패널들의 배열
4203
+ * @type {Panel[]}
4204
+ * @readonly
4205
+ */
4206
+ get: function () {
4207
+ return this._visiblePanels;
4208
+ },
4209
+ enumerable: false,
4210
+ configurable: true
4211
+ });
4212
+ Object.defineProperty(__proto, "visibleRange", {
4213
+ /**
4214
+ * A range of the visible area from the current position
4215
+ * @ko 현재 위치에서 보이는 범위
4216
+ * @type {object}
4217
+ * @property {number} min A minimum position<ko>최소 위치</ko>
4218
+ * @property {number} min A maximum position<ko>최대 위치</ko>
4219
+ * @readonly
4220
+ */
4221
+ get: function () {
4222
+ return {
4223
+ min: this._position - this._alignPos,
4224
+ max: this._position - this._alignPos + this.size
4225
+ };
4226
+ },
4227
+ enumerable: false,
4228
+ configurable: true
4229
+ });
4230
+ Object.defineProperty(__proto, "anchorPoints", {
4231
+ /**
4232
+ * An array of {@link AnchorPoint}s that Camera can be stopped at
4233
+ * @ko 카메라가 도달 가능한 {@link AnchorPoint}의 목록
4234
+ * @type {AnchorPoint[]}
4235
+ * @readonly
4236
+ */
4237
+ get: function () {
4238
+ return this._anchors;
4239
+ },
4240
+ enumerable: false,
4241
+ configurable: true
4242
+ });
4243
+ Object.defineProperty(__proto, "controlParams", {
4244
+ /**
4245
+ * A current parameters of the Camera for updating {@link AxesController}
4246
+ * @ko {@link AxesController}를 업데이트하기 위한 현재 Camera 패러미터들
4247
+ * @type {ControlParams}
4248
+ * @readonly
4249
+ */
4250
+ get: function () {
4251
+ return {
4252
+ range: this._range,
4253
+ position: this._position,
4254
+ circular: this._circularEnabled
4255
+ };
4256
+ },
4257
+ enumerable: false,
4258
+ configurable: true
4259
+ });
4260
+ Object.defineProperty(__proto, "atEdge", {
4261
+ /**
4262
+ * A Boolean value indicating whether Camera's over the minimum or maximum position reachable
4263
+ * @ko 현재 카메라가 도달 가능한 범위의 최소 혹은 최대점을 넘어섰는지를 나타냅니다
4264
+ * @type {boolean}
4265
+ * @readonly
4266
+ */
4267
+ get: function () {
4268
+ return this._position <= this._range.min || this._position >= this._range.max;
4269
+ },
4270
+ enumerable: false,
4271
+ configurable: true
4272
+ });
4273
+ Object.defineProperty(__proto, "size", {
4274
+ /**
4275
+ * Return the size of the viewport
4276
+ * @ko 뷰포트 크기를 반환합니다
4277
+ * @type {number}
4278
+ * @readonly
4279
+ */
4280
+ get: function () {
4281
+ var flicking = this._flicking;
4282
+ return flicking ? flicking.horizontal ? flicking.viewport.width : flicking.viewport.height : 0;
4283
+ },
4284
+ enumerable: false,
4285
+ configurable: true
4286
+ });
4287
+ Object.defineProperty(__proto, "progress", {
4288
+ /**
4289
+ * Return the camera's position progress from the first panel to last panel
4290
+ * Range is from 0 to last panel's index
4291
+ * @ko 첫번째 패널로부터 마지막 패널까지의 카메라 위치의 진행도를 반환합니다
4292
+ * 범위는 0부터 마지막 패널의 인덱스까지입니다
4293
+ * @type {number}
4294
+ * @readonly
4295
+ */
4296
+ get: function () {
4297
+ var flicking = this._flicking;
4298
+ var position = this._position + this._offset;
4299
+ var nearestAnchor = this.findNearestAnchor(this._position);
4223
4300
 
4224
- if (added.length > 0 || removed.length > 0) {
4225
- void flicking.renderer.render().then(function () {
4226
- flicking.trigger(new ComponentEvent(EVENTS.VISIBLE_CHANGE, {
4227
- added: added,
4228
- removed: removed,
4229
- visiblePanels: newVisiblePanels
4230
- }));
4231
- });
4232
- }
4233
- };
4301
+ if (!flicking || !nearestAnchor) {
4302
+ return NaN;
4303
+ }
4234
4304
 
4235
- __proto._checkNeedPanel = function () {
4236
- var needPanelTriggered = this._needPanelTriggered;
4237
- if (needPanelTriggered.prev && needPanelTriggered.next) return;
4238
- var flicking = getFlickingAttached(this._flicking);
4239
- var panels = flicking.renderer.panels;
4305
+ var nearestPanel = nearestAnchor.panel;
4306
+ var panelPos = nearestPanel.position + nearestPanel.offset;
4307
+ var bounceSize = flicking.control.controller.bounce;
4308
+ var _a = this.range,
4309
+ prevRange = _a.min,
4310
+ nextRange = _a.max;
4311
+ var rangeDiff = this.rangeDiff;
4240
4312
 
4241
- if (panels.length <= 0) {
4242
- if (!needPanelTriggered.prev) {
4243
- flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
4244
- direction: DIRECTION.PREV
4245
- }));
4246
- needPanelTriggered.prev = true;
4313
+ if (position === panelPos) {
4314
+ return nearestPanel.index;
4247
4315
  }
4248
4316
 
4249
- if (!needPanelTriggered.next) {
4250
- flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
4251
- direction: DIRECTION.NEXT
4252
- }));
4253
- needPanelTriggered.next = true;
4254
- }
4317
+ if (position < panelPos) {
4318
+ var prevPanel = nearestPanel.prev();
4319
+ var prevPosition = prevPanel ? prevPanel.position + prevPanel.offset : prevRange - bounceSize[0]; // Looped
4255
4320
 
4256
- return;
4257
- }
4321
+ if (prevPosition > panelPos) {
4322
+ prevPosition -= rangeDiff;
4323
+ }
4258
4324
 
4259
- var cameraPosition = this._position;
4260
- var cameraSize = this.size;
4261
- var cameraRange = this._range;
4262
- var needPanelThreshold = flicking.needPanelThreshold;
4263
- var cameraPrev = cameraPosition - this._alignPos;
4264
- var cameraNext = cameraPrev + cameraSize;
4265
- var firstPanel = panels[0];
4266
- var lastPanel = panels[panels.length - 1];
4325
+ return nearestPanel.index - 1 + getProgress(position, prevPosition, panelPos);
4326
+ } else {
4327
+ var nextPanel = nearestPanel.next();
4328
+ var nextPosition = nextPanel ? nextPanel.position + nextPanel.offset : nextRange + bounceSize[1]; // Looped
4267
4329
 
4268
- if (!needPanelTriggered.prev) {
4269
- var firstPanelPrev = firstPanel.range.min;
4330
+ if (nextPosition < panelPos) {
4331
+ nextPosition += rangeDiff;
4332
+ }
4270
4333
 
4271
- if (cameraPrev <= firstPanelPrev + needPanelThreshold || cameraPosition <= cameraRange.min + needPanelThreshold) {
4272
- flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
4273
- direction: DIRECTION.PREV
4274
- }));
4275
- needPanelTriggered.prev = true;
4334
+ return nearestPanel.index + getProgress(position, panelPos, nextPosition);
4276
4335
  }
4277
- }
4336
+ },
4337
+ enumerable: false,
4338
+ configurable: true
4339
+ });
4340
+ Object.defineProperty(__proto, "align", {
4341
+ // Options Getter
4278
4342
 
4279
- if (!needPanelTriggered.next) {
4280
- var lastPanelNext = lastPanel.range.max;
4343
+ /**
4344
+ * A value indicating where the {@link Camera#alignPosition alignPosition} should be located at inside the viewport element
4345
+ * @ko {@link Camera#alignPosition alignPosition}이 뷰포트 엘리먼트 내의 어디에 위치해야 하는지를 나타내는 값
4346
+ * @type {ALIGN | string | number}
4347
+ */
4348
+ get: function () {
4349
+ return this._align;
4350
+ },
4351
+ // Options Setter
4352
+ set: function (val) {
4353
+ this._align = val;
4354
+ },
4355
+ enumerable: false,
4356
+ configurable: true
4357
+ });
4358
+ /**
4359
+ * Initialize Camera
4360
+ * @ko Camera를 초기화합니다
4361
+ * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>
4362
+ * @chainable
4363
+ * @throws {FlickingError}
4364
+ * {@link ERROR_CODE VAL_MUST_NOT_NULL} If the camera element(`.flicking-camera`) does not exist inside viewport element
4365
+ * <ko>{@link ERROR_CODE VAL_MUST_NOT_NULL} 뷰포트 엘리먼트 내부에 카메라 엘리먼트(`.flicking-camera`)가 존재하지 않을 경우</ko>
4366
+ * @return {this}
4367
+ */
4281
4368
 
4282
- if (cameraNext >= lastPanelNext - needPanelThreshold || cameraPosition >= cameraRange.max - needPanelThreshold) {
4283
- flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
4284
- direction: DIRECTION.NEXT
4285
- }));
4286
- needPanelTriggered.next = true;
4287
- }
4288
- }
4289
- };
4369
+ __proto.init = function (flicking) {
4370
+ this._flicking = flicking;
4371
+ var viewportEl = flicking.viewport.element;
4372
+ checkExistence(viewportEl.firstElementChild, "First element child of the viewport element");
4373
+ this._el = viewportEl.firstElementChild;
4290
4374
 
4291
- __proto._checkReachEnd = function (prevPos, newPos) {
4292
- var flicking = getFlickingAttached(this._flicking);
4293
- var range = this._range;
4294
- var wasBetweenRange = prevPos > range.min && prevPos < range.max;
4295
- var isBetweenRange = newPos > range.min && newPos < range.max;
4296
- if (!wasBetweenRange || isBetweenRange) return;
4297
- var direction = newPos <= range.min ? DIRECTION.PREV : DIRECTION.NEXT;
4298
- flicking.trigger(new ComponentEvent(EVENTS.REACH_EDGE, {
4299
- direction: direction
4300
- }));
4375
+ this._checkTranslateSupport();
4376
+
4377
+ this._updateMode();
4378
+
4379
+ return this;
4301
4380
  };
4381
+ /**
4382
+ * Destroy Camera and return to initial state
4383
+ * @ko Camera를 초기 상태로 되돌립니다
4384
+ * @return {void}
4385
+ */
4302
4386
 
4303
- return Camera;
4304
- }();
4305
4387
 
4306
- /**
4307
- * A {@link Camera} that can move from the position of the first panel to the position of the last panel
4308
- * @ko 첫번째 패널의 좌표로부터 마지막 패널의 좌표로까지 이동할 수 있는 종류의 {@link Camera}
4309
- */
4388
+ __proto.destroy = function () {
4389
+ this._flicking = null;
4310
4390
 
4311
- var LinearCamera =
4312
- /*#__PURE__*/
4313
- function (_super) {
4314
- __extends(LinearCamera, _super);
4391
+ this._resetInternalValues();
4315
4392
 
4316
- function LinearCamera() {
4317
- return _super !== null && _super.apply(this, arguments) || this;
4318
- }
4393
+ return this;
4394
+ };
4319
4395
  /**
4320
- * Update {@link Camera#range range} of Camera
4321
- * @ko Camera의 {@link Camera#range range}를 업데이트합니다
4322
- * @chainable
4396
+ * Move to the given position and apply CSS transform
4397
+ * @ko 해당 좌표로 이동하고, CSS transform을 적용합니다
4398
+ * @param {number} pos A new position<ko>움직일 위치</ko>
4323
4399
  * @throws {FlickingError}
4324
4400
  * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
4325
4401
  * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
@@ -4327,170 +4403,190 @@ function (_super) {
4327
4403
  */
4328
4404
 
4329
4405
 
4330
- var __proto = LinearCamera.prototype;
4331
-
4332
- __proto.updateRange = function () {
4333
- var _a, _b;
4406
+ __proto.lookAt = function (pos) {
4407
+ var _this = this;
4334
4408
 
4335
4409
  var flicking = getFlickingAttached(this._flicking);
4336
- var renderer = flicking.renderer;
4337
- var firstPanel = renderer.getPanel(0);
4338
- var lastPanel = renderer.getPanel(renderer.panelCount - 1);
4339
- this._range = {
4340
- min: (_a = firstPanel === null || firstPanel === void 0 ? void 0 : firstPanel.position) !== null && _a !== void 0 ? _a : 0,
4341
- max: (_b = lastPanel === null || lastPanel === void 0 ? void 0 : lastPanel.position) !== null && _b !== void 0 ? _b : 0
4342
- };
4343
- return this;
4344
- };
4410
+ var prevPos = this._position;
4411
+ this._position = pos;
4345
4412
 
4346
- return LinearCamera;
4347
- }(Camera);
4413
+ var toggled = this._togglePanels(prevPos, pos);
4348
4414
 
4349
- /**
4350
- * A {@link Camera} that connects the last panel and the first panel, enabling continuous loop
4351
- * @ko 첫번째 패널과 마지막 패널이 이어진 상태로, 무한히 회전할 수 있는 종류의 {@link Camera}
4352
- */
4415
+ this._refreshVisiblePanels();
4353
4416
 
4354
- var CircularCamera =
4355
- /*#__PURE__*/
4356
- function (_super) {
4357
- __extends(CircularCamera, _super);
4417
+ this._checkNeedPanel();
4358
4418
 
4359
- function CircularCamera() {
4360
- var _this = _super !== null && _super.apply(this, arguments) || this;
4419
+ this._checkReachEnd(prevPos, pos);
4361
4420
 
4362
- _this._circularOffset = 0;
4363
- _this._circularEnabled = false;
4364
- return _this;
4365
- }
4421
+ this.applyTransform();
4422
+
4423
+ if (toggled) {
4424
+ void flicking.renderer.render().then(function () {
4425
+ _this.updateOffset();
4426
+ });
4427
+ }
4428
+ };
4429
+ /**
4430
+ * Return a previous {@link AnchorPoint} of given {@link AnchorPoint}
4431
+ * If it does not exist, return `null` instead
4432
+ * @ko 주어진 {@link AnchorPoint}의 이전 {@link AnchorPoint}를 반환합니다
4433
+ * 존재하지 않을 경우 `null`을 반환합니다
4434
+ * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>
4435
+ * @return {AnchorPoint | null} The previous {@link AnchorPoint}<ko>이전 {@link AnchorPoint}</ko>
4436
+ */
4366
4437
 
4367
- var __proto = CircularCamera.prototype;
4368
- Object.defineProperty(__proto, "offset", {
4369
- get: function () {
4370
- return this._offset - this._circularOffset;
4371
- },
4372
- enumerable: false,
4373
- configurable: true
4374
- });
4375
- Object.defineProperty(__proto, "controlParams", {
4376
- get: function () {
4377
- return {
4378
- range: this._range,
4379
- position: this._position,
4380
- circular: this._circularEnabled
4381
- };
4382
- },
4383
- enumerable: false,
4384
- configurable: true
4385
- });
4386
4438
 
4387
4439
  __proto.getPrevAnchor = function (anchor) {
4388
- if (!this._circularEnabled || anchor.index !== 0) return _super.prototype.getPrevAnchor.call(this, anchor);
4389
- var anchors = this._anchors;
4390
- var rangeDiff = this.rangeDiff;
4391
- var lastAnchor = anchors[anchors.length - 1];
4392
- return new AnchorPoint({
4393
- index: lastAnchor.index,
4394
- position: lastAnchor.position - rangeDiff,
4395
- panel: lastAnchor.panel
4396
- });
4440
+ if (!this._circularEnabled || anchor.index !== 0) {
4441
+ return this._anchors[anchor.index - 1] || null;
4442
+ } else {
4443
+ var anchors = this._anchors;
4444
+ var rangeDiff = this.rangeDiff;
4445
+ var lastAnchor = anchors[anchors.length - 1];
4446
+ return new AnchorPoint({
4447
+ index: lastAnchor.index,
4448
+ position: lastAnchor.position - rangeDiff,
4449
+ panel: lastAnchor.panel
4450
+ });
4451
+ }
4397
4452
  };
4453
+ /**
4454
+ * Return a next {@link AnchorPoint} of given {@link AnchorPoint}
4455
+ * If it does not exist, return `null` instead
4456
+ * @ko 주어진 {@link AnchorPoint}의 다음 {@link AnchorPoint}를 반환합니다
4457
+ * 존재하지 않을 경우 `null`을 반환합니다
4458
+ * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>
4459
+ * @return {AnchorPoint | null} The next {@link AnchorPoint}<ko>다음 {@link AnchorPoint}</ko>
4460
+ */
4461
+
4398
4462
 
4399
4463
  __proto.getNextAnchor = function (anchor) {
4400
4464
  var anchors = this._anchors;
4401
- if (!this._circularEnabled || anchor.index !== anchors.length - 1) return _super.prototype.getNextAnchor.call(this, anchor);
4402
- var rangeDiff = this.rangeDiff;
4403
- var firstAnchor = anchors[0];
4404
- return new AnchorPoint({
4405
- index: firstAnchor.index,
4406
- position: firstAnchor.position + rangeDiff,
4407
- panel: firstAnchor.panel
4408
- });
4465
+
4466
+ if (!this._circularEnabled || anchor.index !== anchors.length - 1) {
4467
+ return anchors[anchor.index + 1] || null;
4468
+ } else {
4469
+ var rangeDiff = this.rangeDiff;
4470
+ var firstAnchor = anchors[0];
4471
+ return new AnchorPoint({
4472
+ index: firstAnchor.index,
4473
+ position: firstAnchor.position + rangeDiff,
4474
+ panel: firstAnchor.panel
4475
+ });
4476
+ }
4477
+ };
4478
+ /**
4479
+ * Return the camera's position progress in the panel below
4480
+ * Value is from 0 to 1 when the camera's inside panel
4481
+ * Value can be lower than 0 or bigger than 1 when it's in the margin area
4482
+ * @ko 현재 카메라 아래 패널에서의 위치 진행도를 반환합니다
4483
+ * 반환값은 카메라가 패널 내부에 있을 경우 0부터 1까지의 값을 갖습니다
4484
+ * 패널의 margin 영역에 있을 경우 0보다 작거나 1보다 큰 값을 반환할 수 있습니다
4485
+ */
4486
+
4487
+
4488
+ __proto.getProgressInPanel = function (panel) {
4489
+ var panelRange = panel.range;
4490
+ return (this._position - panelRange.min) / (panelRange.max - panelRange.min);
4409
4491
  };
4492
+ /**
4493
+ * Return {@link AnchorPoint} that includes given position
4494
+ * If there's no {@link AnchorPoint} that includes the given position, return `null` instead
4495
+ * @ko 주어진 좌표를 포함하는 {@link AnchorPoint}를 반환합니다
4496
+ * 주어진 좌표를 포함하는 {@link AnchorPoint}가 없을 경우 `null`을 반환합니다
4497
+ * @param {number} position A position to check<ko>확인할 좌표</ko>
4498
+ * @return {AnchorPoint | null} The {@link AnchorPoint} that includes the given position<ko>해당 좌표를 포함하는 {@link AnchorPoint}</ko>
4499
+ */
4500
+
4410
4501
 
4411
4502
  __proto.findAnchorIncludePosition = function (position) {
4412
- if (!this._circularEnabled) return _super.prototype.findAnchorIncludePosition.call(this, position);
4413
- var range = this._range;
4503
+ return this._mode.findAnchorIncludePosition(position);
4504
+ };
4505
+ /**
4506
+ * Return {@link AnchorPoint} nearest to given position
4507
+ * If there're no {@link AnchorPoint}s, return `null` instead
4508
+ * @ko 해당 좌표에서 가장 가까운 {@link AnchorPoint}를 반환합니다
4509
+ * {@link AnchorPoint}가 하나도 없을 경우 `null`을 반환합니다
4510
+ * @param {number} position A position to check<ko>확인할 좌표</ko>
4511
+ * @return {AnchorPoint | null} The {@link AnchorPoint} nearest to the given position<ko>해당 좌표에 가장 인접한 {@link AnchorPoint}</ko>
4512
+ */
4513
+
4514
+
4515
+ __proto.findNearestAnchor = function (position) {
4414
4516
  var anchors = this._anchors;
4415
- var rangeDiff = this.rangeDiff;
4416
- var anchorCount = anchors.length;
4417
- var positionInRange = circulatePosition(position, range.min, range.max);
4517
+ if (anchors.length <= 0) return null;
4518
+ var prevDist = Infinity;
4418
4519
 
4419
- var anchorInRange = _super.prototype.findAnchorIncludePosition.call(this, positionInRange);
4520
+ for (var anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
4521
+ var anchor = anchors[anchorIdx];
4522
+ var dist = Math.abs(anchor.position - position);
4420
4523
 
4421
- if (anchorCount > 0 && (position === range.min || position === range.max)) {
4422
- var possibleAnchors = [anchorInRange, new AnchorPoint({
4423
- index: 0,
4424
- position: anchors[0].position + rangeDiff,
4425
- panel: anchors[0].panel
4426
- }), new AnchorPoint({
4427
- index: anchorCount - 1,
4428
- position: anchors[anchorCount - 1].position - rangeDiff,
4429
- panel: anchors[anchorCount - 1].panel
4430
- })].filter(function (anchor) {
4431
- return !!anchor;
4432
- });
4433
- anchorInRange = possibleAnchors.reduce(function (nearest, anchor) {
4434
- if (!nearest) return anchor;
4435
- return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
4436
- }, null);
4437
- }
4524
+ if (dist > prevDist) {
4525
+ // Return previous anchor
4526
+ return anchors[anchorIdx - 1];
4527
+ }
4438
4528
 
4439
- if (!anchorInRange) return null;
4529
+ prevDist = dist;
4530
+ } // Return last anchor
4440
4531
 
4441
- if (position < range.min) {
4442
- var loopCount = -Math.floor((range.min - position) / rangeDiff) - 1;
4443
- return new AnchorPoint({
4444
- index: anchorInRange.index,
4445
- position: anchorInRange.position + rangeDiff * loopCount,
4446
- panel: anchorInRange.panel
4447
- });
4448
- } else if (position > range.max) {
4449
- var loopCount = Math.floor((position - range.max) / rangeDiff) + 1;
4450
- return new AnchorPoint({
4451
- index: anchorInRange.index,
4452
- position: anchorInRange.position + rangeDiff * loopCount,
4453
- panel: anchorInRange.panel
4454
- });
4455
- }
4456
4532
 
4457
- return anchorInRange;
4533
+ return anchors[anchors.length - 1];
4458
4534
  };
4535
+ /**
4536
+ * Return {@link AnchorPoint} that matches {@link Flicking#currentPanel}
4537
+ * @ko 현재 {@link Flicking#currentPanel}에 해당하는 {@link AnchorPoint}를 반환합니다
4538
+ * @return {AnchorPoint | null}
4539
+ */
4459
4540
 
4460
- __proto.clampToReachablePosition = function (position) {
4461
- // Basically all position is reachable for circular camera
4462
- return this._circularEnabled ? position : _super.prototype.clampToReachablePosition.call(this, position);
4463
- };
4464
4541
 
4465
- __proto.canReach = function (panel) {
4466
- if (panel.removed) return false;
4467
- return this._circularEnabled // Always reachable on circular mode
4468
- ? true : _super.prototype.canReach.call(this, panel);
4542
+ __proto.findActiveAnchor = function () {
4543
+ var flicking = getFlickingAttached(this._flicking);
4544
+ var activeIndex = flicking.control.activeIndex;
4545
+ return find(this._anchors, function (anchor) {
4546
+ return anchor.panel.index === activeIndex;
4547
+ });
4469
4548
  };
4549
+ /**
4550
+ * Clamp the given position between camera's range
4551
+ * @ko 주어진 좌표를 Camera가 도달 가능한 범위 사이의 값으로 만듭니다
4552
+ * @param {number} position A position to clamp<ko>범위를 제한할 좌표</ko>
4553
+ * @return {number} A clamped position<ko>범위 제한된 좌표</ko>
4554
+ */
4470
4555
 
4471
- __proto.canSee = function (panel) {
4472
- var range = this._range;
4473
- var rangeDiff = this.rangeDiff;
4474
- var visibleRange = this.visibleRange;
4475
4556
 
4476
- var visibleInCurrentRange = _super.prototype.canSee.call(this, panel);
4557
+ __proto.clampToReachablePosition = function (position) {
4558
+ return this._mode.clampToReachablePosition(position);
4559
+ };
4560
+ /**
4561
+ * Check whether the given panel is inside of the Camera's range
4562
+ * @ko 해당 {@link Panel}이 Camera가 도달 가능한 범위 내에 있는지를 반환합니다
4563
+ * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>
4564
+ * @return {boolean} Whether the panel's inside Camera's range<ko>도달 가능한 범위 내에 해당 패널이 존재하는지 여부</ko>
4565
+ */
4477
4566
 
4478
- if (!this._circularEnabled) {
4479
- return visibleInCurrentRange;
4480
- } // Check looped visible area for circular case
4481
4567
 
4568
+ __proto.canReach = function (panel) {
4569
+ return this._mode.canReach(panel);
4570
+ };
4571
+ /**
4572
+ * Check whether the given panel element is visible at the current position
4573
+ * @ko 현재 좌표에서 해당 패널 엘리먼트를 볼 수 있는지 여부를 반환합니다
4574
+ * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>
4575
+ * @return Whether the panel element is visible at the current position<ko>현재 위치에서 해당 패널 엘리먼트가 보이는지 여부</ko>
4576
+ */
4482
4577
 
4483
- if (visibleRange.min < range.min) {
4484
- return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff);
4485
- } else if (visibleRange.max > range.max) {
4486
- return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff);
4487
- }
4488
4578
 
4489
- return visibleInCurrentRange;
4579
+ __proto.canSee = function (panel) {
4580
+ return this._mode.canSee(panel);
4490
4581
  };
4491
4582
  /**
4492
4583
  * Update {@link Camera#range range} of Camera
4493
4584
  * @ko Camera의 {@link Camera#range range}를 업데이트합니다
4585
+ * @method
4586
+ * @abstract
4587
+ * @memberof Camera
4588
+ * @instance
4589
+ * @name updateRange
4494
4590
  * @chainable
4495
4591
  * @throws {FlickingError}
4496
4592
  * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
@@ -4504,287 +4600,269 @@ function (_super) {
4504
4600
  var renderer = flicking.renderer;
4505
4601
  var panels = renderer.panels;
4506
4602
 
4507
- if (panels.length <= 0) {
4508
- this._resetInternalValues();
4509
-
4510
- return this;
4511
- }
4603
+ this._updateMode();
4512
4604
 
4513
- var firstPanel = panels[0];
4514
- var lastPanel = panels[panels.length - 1];
4515
- var firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
4516
- var lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
4517
- var visibleSize = this.size;
4518
- var panelSizeSum = lastPanelNext - firstPanelPrev;
4519
- var canSetCircularMode = panels.every(function (panel) {
4520
- return panelSizeSum - panel.size >= visibleSize;
4521
- });
4522
- this._circularEnabled = canSetCircularMode;
4605
+ this._range = this._mode.getRange();
4523
4606
 
4524
- if (canSetCircularMode) {
4525
- this._range = {
4526
- min: firstPanelPrev,
4527
- max: lastPanelNext
4528
- };
4607
+ if (this._circularEnabled) {
4529
4608
  panels.forEach(function (panel) {
4530
4609
  return panel.updateCircularToggleDirection();
4531
4610
  });
4532
- } else {
4533
- this._range = {
4534
- min: firstPanel.position,
4535
- max: lastPanel.position
4536
- };
4537
4611
  }
4538
4612
 
4539
4613
  this.updateOffset();
4540
4614
  return this;
4541
4615
  };
4616
+ /**
4617
+ * Update Camera's {@link Camera#alignPosition alignPosition}
4618
+ * @ko Camera의 {@link Camera#alignPosition alignPosition}을 업데이트합니다
4619
+ * @chainable
4620
+ * @return {this}
4621
+ */
4542
4622
 
4543
- __proto.updateOffset = function () {
4544
- this._updateCircularOffset();
4545
4623
 
4546
- return _super.prototype.updateOffset.call(this);
4624
+ __proto.updateAlignPos = function () {
4625
+ var align = this._align;
4626
+ var alignVal = typeof align === "object" ? align.camera : align;
4627
+ this._alignPos = parseAlign$1(alignVal, this.size);
4628
+ return this;
4547
4629
  };
4630
+ /**
4631
+ * Update Camera's {@link Camera#anchorPoints anchorPoints}
4632
+ * @ko Camera의 {@link Camera#anchorPoints anchorPoints}를 업데이트합니다
4633
+ * @throws {FlickingError}
4634
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
4635
+ * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
4636
+ * @chainable
4637
+ * @return {this}
4638
+ */
4548
4639
 
4549
- __proto.lookAt = function (pos) {
4550
- var _this = this;
4551
-
4552
- var flicking = getFlickingAttached(this._flicking);
4553
- var prevPos = this._position;
4554
- if (pos === prevPos) return _super.prototype.lookAt.call(this, pos);
4555
- var panels = flicking.renderer.panels;
4556
- var toggled = panels.map(function (panel) {
4557
- return panel.toggle(prevPos, pos);
4558
- });
4559
- this._position = pos;
4560
-
4561
- _super.prototype.lookAt.call(this, pos);
4562
-
4563
- if (toggled.some(function (isToggled) {
4564
- return isToggled;
4565
- })) {
4566
- void flicking.renderer.render().then(function () {
4567
- _this.updateOffset();
4568
- });
4569
- }
4570
- };
4571
4640
 
4572
- __proto.applyTransform = function () {
4573
- var el = this._el;
4574
- var flicking = getFlickingAttached(this._flicking);
4575
- var actualPosition = this._position - this._alignPos - this._offset + this._circularOffset;
4576
- el.style[this._transform] = flicking.horizontal ? "translate(" + -actualPosition + "px)" : "translate(0, " + -actualPosition + "px)";
4641
+ __proto.updateAnchors = function () {
4642
+ this._anchors = this._mode.getAnchors();
4577
4643
  return this;
4578
4644
  };
4645
+ /**
4646
+ * Update Viewport's height to active panel's height
4647
+ * @ko 현재 선택된 패널의 높이와 동일하도록 뷰포트의 높이를 업데이트합니다
4648
+ * @throws {FlickingError}
4649
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
4650
+ * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
4651
+ * @chainable
4652
+ * @return {this}
4653
+ */
4579
4654
 
4580
- __proto._resetInternalValues = function () {
4581
- _super.prototype._resetInternalValues.call(this);
4582
-
4583
- this._circularOffset = 0;
4584
- this._circularEnabled = false;
4585
- };
4586
4655
 
4587
- __proto._calcPanelAreaSum = function (panels) {
4588
- return panels.reduce(function (sum, panel) {
4589
- return sum + panel.sizeIncludingMargin;
4590
- }, 0);
4656
+ __proto.updateAdaptiveHeight = function () {
4657
+ var flicking = getFlickingAttached(this._flicking);
4658
+ var activePanel = flicking.control.activePanel;
4659
+ if (!flicking.horizontal || !flicking.adaptive || !activePanel) return;
4660
+ flicking.viewport.setSize({
4661
+ height: activePanel.height
4662
+ });
4591
4663
  };
4664
+ /**
4665
+ * Update current offset of the camera
4666
+ * @ko 현재 카메라의 오프셋을 업데이트합니다
4667
+ * @chainable
4668
+ * @return {this}
4669
+ */
4592
4670
 
4593
- __proto._updateCircularOffset = function () {
4594
- if (!this._circularEnabled) {
4595
- this._circularOffset = 0;
4596
- return;
4597
- }
4598
4671
 
4672
+ __proto.updateOffset = function () {
4599
4673
  var flicking = getFlickingAttached(this._flicking);
4600
- var toggled = flicking.panels.filter(function (panel) {
4601
- return panel.toggled;
4602
- });
4603
- var toggledPrev = toggled.filter(function (panel) {
4604
- return panel.toggleDirection === DIRECTION.PREV;
4605
- });
4606
- var toggledNext = toggled.filter(function (panel) {
4607
- return panel.toggleDirection === DIRECTION.NEXT;
4674
+ var position = this._position;
4675
+ var unRenderedPanels = flicking.panels.filter(function (panel) {
4676
+ return !panel.rendered;
4608
4677
  });
4609
- this._circularOffset = this._calcPanelAreaSum(toggledPrev) - this._calcPanelAreaSum(toggledNext);
4678
+ this._offset = unRenderedPanels.filter(function (panel) {
4679
+ return panel.position + panel.offset < position;
4680
+ }).reduce(function (offset, panel) {
4681
+ return offset + panel.sizeIncludingMargin;
4682
+ }, 0);
4683
+ this._circularOffset = this._mode.getCircularOffset();
4684
+ this.applyTransform();
4685
+ return this;
4610
4686
  };
4687
+ /**
4688
+ * Reset the history of {@link Flicking#event:needPanel needPanel} events so it can be triggered again
4689
+ * @ko 발생한 {@link Flicking#event:needPanel needPanel} 이벤트들을 초기화하여 다시 발생할 수 있도록 합니다
4690
+ * @chainable
4691
+ * @return {this}
4692
+ */
4611
4693
 
4612
- return CircularCamera;
4613
- }(Camera);
4614
-
4615
- /**
4616
- * A {@link Camera} that set range not to go out of the first/last panel, so it won't show empty spaces before/after the first/last panel
4617
- * @ko 첫번째와 마지막 패널 밖으로 넘어가지 못하도록 범위를 설정하여, 첫번째/마지막 패널 전/후의 빈 공간을 보이지 않도록 하는 종류의 {@link Camera}
4618
- */
4619
-
4620
- var BoundCamera =
4621
- /*#__PURE__*/
4622
- function (_super) {
4623
- __extends(BoundCamera, _super);
4624
4694
 
4625
- function BoundCamera() {
4626
- return _super !== null && _super.apply(this, arguments) || this;
4627
- }
4695
+ __proto.resetNeedPanelHistory = function () {
4696
+ this._needPanelTriggered = {
4697
+ prev: false,
4698
+ next: false
4699
+ };
4700
+ return this;
4701
+ };
4628
4702
  /**
4629
- * Update {@link Camera#range range} of Camera
4630
- * @ko Camera의 {@link Camera#range range}를 업데이트합니다
4703
+ * Apply "transform" style with the current position to camera element
4704
+ * @ko 현재 위치를 기준으로한 transform 스타일을 카메라 엘리먼트에 적용합니다.
4631
4705
  * @chainable
4632
- * @throws {FlickingError}
4633
- * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
4634
- * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
4635
4706
  * @return {this}
4636
4707
  */
4637
4708
 
4638
4709
 
4639
- var __proto = BoundCamera.prototype;
4640
-
4641
- __proto.updateRange = function () {
4710
+ __proto.applyTransform = function () {
4711
+ var el = this._el;
4642
4712
  var flicking = getFlickingAttached(this._flicking);
4643
- var renderer = flicking.renderer;
4644
- var alignPos = this._alignPos;
4645
- var firstPanel = renderer.getPanel(0);
4646
- var lastPanel = renderer.getPanel(renderer.panelCount - 1);
4647
-
4648
- if (!firstPanel || !lastPanel) {
4649
- this._range = {
4650
- min: 0,
4651
- max: 0
4652
- };
4653
- return this;
4654
- }
4655
-
4656
- var viewportSize = this.size;
4657
- var firstPanelPrev = firstPanel.range.min;
4658
- var lastPanelNext = lastPanel.range.max;
4659
- var panelAreaSize = lastPanelNext - firstPanelPrev;
4660
- var isBiggerThanViewport = viewportSize < panelAreaSize;
4661
- var firstPos = firstPanelPrev + alignPos;
4662
- var lastPos = lastPanelNext - viewportSize + alignPos;
4663
-
4664
- if (isBiggerThanViewport) {
4665
- this._range = {
4666
- min: firstPos,
4667
- max: lastPos
4668
- };
4669
- } else {
4670
- var align = this._align;
4671
- var alignVal = typeof align === "object" ? align.camera : align;
4672
- var pos = firstPos + parseAlign$1(alignVal, lastPos - firstPos);
4673
- this._range = {
4674
- min: pos,
4675
- max: pos
4676
- };
4677
- }
4678
-
4713
+ var actualPosition = this._position - this._alignPos - this._offset + this._circularOffset;
4714
+ el.style[this._transform] = flicking.horizontal ? "translate(" + -actualPosition + "px)" : "translate(0, " + -actualPosition + "px)";
4679
4715
  return this;
4680
4716
  };
4681
4717
 
4682
- __proto.updateAnchors = function () {
4718
+ __proto._resetInternalValues = function () {
4719
+ this._position = 0;
4720
+ this._alignPos = 0;
4721
+ this._offset = 0;
4722
+ this._circularOffset = 0;
4723
+ this._circularEnabled = false;
4724
+ this._range = {
4725
+ min: 0,
4726
+ max: 0
4727
+ };
4728
+ this._visiblePanels = [];
4729
+ this._anchors = [];
4730
+ this._needPanelTriggered = {
4731
+ prev: false,
4732
+ next: false
4733
+ };
4734
+ };
4735
+
4736
+ __proto._refreshVisiblePanels = function () {
4683
4737
  var _this = this;
4684
4738
 
4685
4739
  var flicking = getFlickingAttached(this._flicking);
4686
4740
  var panels = flicking.renderer.panels;
4687
-
4688
- if (panels.length <= 0) {
4689
- this._anchors = [];
4690
- return this;
4691
- }
4692
-
4693
- var range = this._range;
4694
- var reachablePanels = panels.filter(function (panel) {
4695
- return _this.canReach(panel);
4741
+ var newVisiblePanels = panels.filter(function (panel) {
4742
+ return _this.canSee(panel);
4743
+ });
4744
+ var prevVisiblePanels = this._visiblePanels;
4745
+ this._visiblePanels = newVisiblePanels;
4746
+ var added = newVisiblePanels.filter(function (panel) {
4747
+ return !includes(prevVisiblePanels, panel);
4748
+ });
4749
+ var removed = prevVisiblePanels.filter(function (panel) {
4750
+ return !includes(newVisiblePanels, panel);
4696
4751
  });
4697
4752
 
4698
- if (reachablePanels.length > 0) {
4699
- var shouldPrependBoundAnchor = reachablePanels[0].position !== range.min;
4700
- var shouldAppendBoundAnchor = reachablePanels[reachablePanels.length - 1].position !== range.max;
4701
- var indexOffset_1 = shouldPrependBoundAnchor ? 1 : 0;
4702
- var newAnchors = reachablePanels.map(function (panel, idx) {
4703
- return new AnchorPoint({
4704
- index: idx + indexOffset_1,
4705
- position: panel.position,
4706
- panel: panel
4707
- });
4753
+ if (added.length > 0 || removed.length > 0) {
4754
+ void flicking.renderer.render().then(function () {
4755
+ flicking.trigger(new ComponentEvent(EVENTS.VISIBLE_CHANGE, {
4756
+ added: added,
4757
+ removed: removed,
4758
+ visiblePanels: newVisiblePanels
4759
+ }));
4708
4760
  });
4761
+ }
4762
+ };
4709
4763
 
4710
- if (shouldPrependBoundAnchor) {
4711
- newAnchors.splice(0, 0, new AnchorPoint({
4712
- index: 0,
4713
- position: range.min,
4714
- panel: panels[reachablePanels[0].index - 1]
4764
+ __proto._checkNeedPanel = function () {
4765
+ var needPanelTriggered = this._needPanelTriggered;
4766
+ if (needPanelTriggered.prev && needPanelTriggered.next) return;
4767
+ var flicking = getFlickingAttached(this._flicking);
4768
+ var panels = flicking.renderer.panels;
4769
+
4770
+ if (panels.length <= 0) {
4771
+ if (!needPanelTriggered.prev) {
4772
+ flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
4773
+ direction: DIRECTION.PREV
4715
4774
  }));
4775
+ needPanelTriggered.prev = true;
4716
4776
  }
4717
4777
 
4718
- if (shouldAppendBoundAnchor) {
4719
- newAnchors.push(new AnchorPoint({
4720
- index: newAnchors.length,
4721
- position: range.max,
4722
- panel: panels[reachablePanels[reachablePanels.length - 1].index + 1]
4778
+ if (!needPanelTriggered.next) {
4779
+ flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
4780
+ direction: DIRECTION.NEXT
4723
4781
  }));
4782
+ needPanelTriggered.next = true;
4724
4783
  }
4725
4784
 
4726
- this._anchors = newAnchors;
4727
- } else if (range.min !== range.max) {
4728
- // There're more than 2 panels
4729
- var nearestPanelAtMin = this._findNearestPanel(range.min, panels);
4785
+ return;
4786
+ }
4730
4787
 
4731
- var panelAtMin = nearestPanelAtMin.index === panels.length - 1 ? nearestPanelAtMin.prev() : nearestPanelAtMin;
4732
- var panelAtMax = panelAtMin.next();
4733
- this._anchors = [new AnchorPoint({
4734
- index: 0,
4735
- position: range.min,
4736
- panel: panelAtMin
4737
- }), new AnchorPoint({
4738
- index: 1,
4739
- position: range.max,
4740
- panel: panelAtMax
4741
- })];
4742
- } else {
4743
- this._anchors = [new AnchorPoint({
4744
- index: 0,
4745
- position: range.min,
4746
- panel: this._findNearestPanel(range.min, panels)
4747
- })];
4788
+ var cameraPosition = this._position;
4789
+ var cameraSize = this.size;
4790
+ var cameraRange = this._range;
4791
+ var needPanelThreshold = flicking.needPanelThreshold;
4792
+ var cameraPrev = cameraPosition - this._alignPos;
4793
+ var cameraNext = cameraPrev + cameraSize;
4794
+ var firstPanel = panels[0];
4795
+ var lastPanel = panels[panels.length - 1];
4796
+
4797
+ if (!needPanelTriggered.prev) {
4798
+ var firstPanelPrev = firstPanel.range.min;
4799
+
4800
+ if (cameraPrev <= firstPanelPrev + needPanelThreshold || cameraPosition <= cameraRange.min + needPanelThreshold) {
4801
+ flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
4802
+ direction: DIRECTION.PREV
4803
+ }));
4804
+ needPanelTriggered.prev = true;
4805
+ }
4748
4806
  }
4749
4807
 
4750
- return this;
4808
+ if (!needPanelTriggered.next) {
4809
+ var lastPanelNext = lastPanel.range.max;
4810
+
4811
+ if (cameraNext >= lastPanelNext - needPanelThreshold || cameraPosition >= cameraRange.max - needPanelThreshold) {
4812
+ flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, {
4813
+ direction: DIRECTION.NEXT
4814
+ }));
4815
+ needPanelTriggered.next = true;
4816
+ }
4817
+ }
4751
4818
  };
4752
4819
 
4753
- __proto.findAnchorIncludePosition = function (position) {
4820
+ __proto._checkReachEnd = function (prevPos, newPos) {
4821
+ var flicking = getFlickingAttached(this._flicking);
4754
4822
  var range = this._range;
4755
- var anchors = this._anchors;
4756
- if (anchors.length <= 0) return null;
4757
-
4758
- if (position <= range.min) {
4759
- return anchors[0];
4760
- } else if (position >= range.max) {
4761
- return anchors[anchors.length - 1];
4762
- } else {
4763
- return _super.prototype.findAnchorIncludePosition.call(this, position);
4764
- }
4823
+ var wasBetweenRange = prevPos > range.min && prevPos < range.max;
4824
+ var isBetweenRange = newPos > range.min && newPos < range.max;
4825
+ if (!wasBetweenRange || isBetweenRange) return;
4826
+ var direction = newPos <= range.min ? DIRECTION.PREV : DIRECTION.NEXT;
4827
+ flicking.trigger(new ComponentEvent(EVENTS.REACH_EDGE, {
4828
+ direction: direction
4829
+ }));
4765
4830
  };
4766
4831
 
4767
- __proto._findNearestPanel = function (pos, panels) {
4768
- var prevDist = Infinity;
4832
+ __proto._updateMode = function () {
4833
+ var flicking = getFlickingAttached(this._flicking);
4769
4834
 
4770
- for (var panelIdx = 0; panelIdx < panels.length; panelIdx++) {
4771
- var panel = panels[panelIdx];
4772
- var dist = Math.abs(panel.position - pos);
4835
+ if (flicking.circular) {
4836
+ var circularMode = new CircularCameraMode(flicking);
4837
+ var canSetCircularMode = circularMode.checkAvailability();
4773
4838
 
4774
- if (dist > prevDist) {
4775
- // Return previous anchor
4776
- return panels[panelIdx - 1];
4839
+ if (canSetCircularMode) {
4840
+ this._mode = circularMode;
4841
+ } else {
4842
+ var fallbackMode = flicking.circularFallback;
4843
+ this._mode = fallbackMode === CIRCULAR_FALLBACK.BOUND ? new BoundCameraMode(flicking) : new LinearCameraMode(flicking);
4777
4844
  }
4778
4845
 
4779
- prevDist = dist;
4780
- } // Return last anchor
4781
-
4846
+ this._circularEnabled = canSetCircularMode;
4847
+ } else {
4848
+ this._mode = flicking.bound ? new BoundCameraMode(flicking) : new LinearCameraMode(flicking);
4849
+ }
4850
+ };
4782
4851
 
4783
- return panels[panels.length - 1];
4852
+ __proto._togglePanels = function (prevPos, pos) {
4853
+ if (pos === prevPos) return false;
4854
+ var flicking = getFlickingAttached(this._flicking);
4855
+ var panels = flicking.renderer.panels;
4856
+ var toggled = panels.map(function (panel) {
4857
+ return panel.toggle(prevPos, pos);
4858
+ });
4859
+ return toggled.some(function (isToggled) {
4860
+ return isToggled;
4861
+ });
4784
4862
  };
4785
4863
 
4786
- return BoundCamera;
4787
- }(Camera);
4864
+ return Camera;
4865
+ }();
4788
4866
 
4789
4867
  /**
4790
4868
  * A component that manages {@link Panel} and its elements
@@ -4983,7 +5061,7 @@ function () {
4983
5061
  flicking: flicking
4984
5062
  });
4985
5063
  });
4986
- panels.splice.apply(panels, __spreadArray([insertingIdx, 0], __read(panelsInserted)));
5064
+ panels.splice.apply(panels, __spread([insertingIdx, 0], panelsInserted));
4987
5065
 
4988
5066
  if (item.hasDOMInElements) {
4989
5067
  // Insert the actual elements as camera element's children
@@ -5006,7 +5084,7 @@ function () {
5006
5084
  panel.increaseIndex(panelsInserted.length);
5007
5085
  panel.updatePosition();
5008
5086
  });
5009
- return __spreadArray(__spreadArray([], __read(addedPanels), false), __read(panelsInserted));
5087
+ return __spread(addedPanels, panelsInserted);
5010
5088
  }, []);
5011
5089
  if (allPanelsInserted.length <= 0) return []; // Update camera & control
5012
5090
 
@@ -5085,7 +5163,7 @@ function () {
5085
5163
  control.resetActive();
5086
5164
  }
5087
5165
 
5088
- return __spreadArray(__spreadArray([], __read(removed), false), __read(panelsRemoved));
5166
+ return __spread(removed, panelsRemoved);
5089
5167
  }, []); // Update camera & control
5090
5168
 
5091
5169
  this._updateCameraAndControl();
@@ -6084,7 +6162,7 @@ function () {
6084
6162
  var notToggled = renderedPanels.filter(function (panel) {
6085
6163
  return !panel.toggled;
6086
6164
  });
6087
- return __spreadArray(__spreadArray(__spreadArray([], __read(toggledPrev), false), __read(notToggled), false), __read(toggledNext)).map(function (panel) {
6165
+ return __spread(toggledPrev, notToggled, toggledNext).map(function (panel) {
6088
6166
  return panel.index;
6089
6167
  });
6090
6168
  };
@@ -6294,7 +6372,7 @@ function () {
6294
6372
  __proto.getRenderingIndexesByOrder = function (flicking) {
6295
6373
  var virtualManager = flicking.virtual;
6296
6374
 
6297
- var visiblePanels = __spreadArray([], __read(flicking.visiblePanels)).filter(function (panel) {
6375
+ var visiblePanels = __spread(flicking.visiblePanels).filter(function (panel) {
6298
6376
  return panel.rendered;
6299
6377
  }).sort(function (panel1, panel2) {
6300
6378
  return panel1.position + panel1.offset - (panel2.position + panel2.offset);
@@ -6315,7 +6393,7 @@ function () {
6315
6393
  }).map(function (el) {
6316
6394
  return el.idx;
6317
6395
  });
6318
- return __spreadArray(__spreadArray([], __read(visibleIndexes), false), __read(invisibleIndexes));
6396
+ return __spread(visibleIndexes, invisibleIndexes);
6319
6397
  };
6320
6398
 
6321
6399
  __proto.getRenderingElementsByOrder = function (flicking) {
@@ -6424,58 +6502,60 @@ function (_super) {
6424
6502
  horizontal = _e === void 0 ? true : _e,
6425
6503
  _f = _b.circular,
6426
6504
  circular = _f === void 0 ? false : _f,
6427
- _g = _b.bound,
6428
- bound = _g === void 0 ? false : _g,
6429
- _h = _b.adaptive,
6430
- adaptive = _h === void 0 ? false : _h,
6431
- _j = _b.panelsPerView,
6432
- panelsPerView = _j === void 0 ? -1 : _j,
6433
- _k = _b.noPanelStyleOverride,
6434
- noPanelStyleOverride = _k === void 0 ? false : _k,
6435
- _l = _b.resizeOnContentsReady,
6436
- resizeOnContentsReady = _l === void 0 ? false : _l,
6437
- _m = _b.needPanelThreshold,
6438
- needPanelThreshold = _m === void 0 ? 0 : _m,
6439
- _o = _b.preventEventsBeforeInit,
6440
- preventEventsBeforeInit = _o === void 0 ? true : _o,
6441
- _p = _b.deceleration,
6442
- deceleration = _p === void 0 ? 0.0075 : _p,
6443
- _q = _b.duration,
6444
- duration = _q === void 0 ? 500 : _q,
6445
- _r = _b.easing,
6446
- easing = _r === void 0 ? function (x) {
6505
+ _g = _b.circularFallback,
6506
+ circularFallback = _g === void 0 ? CIRCULAR_FALLBACK.LINEAR : _g,
6507
+ _h = _b.bound,
6508
+ bound = _h === void 0 ? false : _h,
6509
+ _j = _b.adaptive,
6510
+ adaptive = _j === void 0 ? false : _j,
6511
+ _k = _b.panelsPerView,
6512
+ panelsPerView = _k === void 0 ? -1 : _k,
6513
+ _l = _b.noPanelStyleOverride,
6514
+ noPanelStyleOverride = _l === void 0 ? false : _l,
6515
+ _m = _b.resizeOnContentsReady,
6516
+ resizeOnContentsReady = _m === void 0 ? false : _m,
6517
+ _o = _b.needPanelThreshold,
6518
+ needPanelThreshold = _o === void 0 ? 0 : _o,
6519
+ _p = _b.preventEventsBeforeInit,
6520
+ preventEventsBeforeInit = _p === void 0 ? true : _p,
6521
+ _q = _b.deceleration,
6522
+ deceleration = _q === void 0 ? 0.0075 : _q,
6523
+ _r = _b.duration,
6524
+ duration = _r === void 0 ? 500 : _r,
6525
+ _s = _b.easing,
6526
+ easing = _s === void 0 ? function (x) {
6447
6527
  return 1 - Math.pow(1 - x, 3);
6448
- } : _r,
6449
- _s = _b.inputType,
6450
- inputType = _s === void 0 ? ["mouse", "touch"] : _s,
6451
- _t = _b.moveType,
6452
- moveType = _t === void 0 ? "snap" : _t,
6453
- _u = _b.threshold,
6454
- threshold = _u === void 0 ? 40 : _u,
6455
- _v = _b.interruptable,
6456
- interruptable = _v === void 0 ? true : _v,
6457
- _w = _b.bounce,
6458
- bounce = _w === void 0 ? "20%" : _w,
6459
- _x = _b.iOSEdgeSwipeThreshold,
6460
- iOSEdgeSwipeThreshold = _x === void 0 ? 30 : _x,
6461
- _y = _b.preventClickOnDrag,
6462
- preventClickOnDrag = _y === void 0 ? true : _y,
6463
- _z = _b.disableOnInit,
6464
- disableOnInit = _z === void 0 ? false : _z,
6465
- _0 = _b.renderOnlyVisible,
6466
- renderOnlyVisible = _0 === void 0 ? false : _0,
6467
- _1 = _b.virtual,
6468
- virtual = _1 === void 0 ? null : _1,
6469
- _2 = _b.autoInit,
6470
- autoInit = _2 === void 0 ? true : _2,
6471
- _3 = _b.autoResize,
6472
- autoResize = _3 === void 0 ? true : _3,
6473
- _4 = _b.useResizeObserver,
6474
- useResizeObserver = _4 === void 0 ? true : _4,
6475
- _5 = _b.externalRenderer,
6476
- externalRenderer = _5 === void 0 ? null : _5,
6477
- _6 = _b.renderExternal,
6478
- renderExternal = _6 === void 0 ? null : _6;
6528
+ } : _s,
6529
+ _t = _b.inputType,
6530
+ inputType = _t === void 0 ? ["mouse", "touch"] : _t,
6531
+ _u = _b.moveType,
6532
+ moveType = _u === void 0 ? "snap" : _u,
6533
+ _v = _b.threshold,
6534
+ threshold = _v === void 0 ? 40 : _v,
6535
+ _w = _b.interruptable,
6536
+ interruptable = _w === void 0 ? true : _w,
6537
+ _x = _b.bounce,
6538
+ bounce = _x === void 0 ? "20%" : _x,
6539
+ _y = _b.iOSEdgeSwipeThreshold,
6540
+ iOSEdgeSwipeThreshold = _y === void 0 ? 30 : _y,
6541
+ _z = _b.preventClickOnDrag,
6542
+ preventClickOnDrag = _z === void 0 ? true : _z,
6543
+ _0 = _b.disableOnInit,
6544
+ disableOnInit = _0 === void 0 ? false : _0,
6545
+ _1 = _b.renderOnlyVisible,
6546
+ renderOnlyVisible = _1 === void 0 ? false : _1,
6547
+ _2 = _b.virtual,
6548
+ virtual = _2 === void 0 ? null : _2,
6549
+ _3 = _b.autoInit,
6550
+ autoInit = _3 === void 0 ? true : _3,
6551
+ _4 = _b.autoResize,
6552
+ autoResize = _4 === void 0 ? true : _4,
6553
+ _5 = _b.useResizeObserver,
6554
+ useResizeObserver = _5 === void 0 ? true : _5,
6555
+ _6 = _b.externalRenderer,
6556
+ externalRenderer = _6 === void 0 ? null : _6,
6557
+ _7 = _b.renderExternal,
6558
+ renderExternal = _7 === void 0 ? null : _7;
6479
6559
 
6480
6560
  var _this = _super.call(this) || this; // Internal states
6481
6561
 
@@ -6487,6 +6567,7 @@ function (_super) {
6487
6567
  _this._defaultIndex = defaultIndex;
6488
6568
  _this._horizontal = horizontal;
6489
6569
  _this._circular = circular;
6570
+ _this._circularFallback = circularFallback;
6490
6571
  _this._bound = bound;
6491
6572
  _this._adaptive = adaptive;
6492
6573
  _this._panelsPerView = panelsPerView;
@@ -6625,7 +6706,7 @@ function (_super) {
6625
6706
  * @readonly
6626
6707
  */
6627
6708
  get: function () {
6628
- return this._camera.controlParams.circular;
6709
+ return this._camera.circularEnabled;
6629
6710
  },
6630
6711
  enumerable: false,
6631
6712
  configurable: true
@@ -6859,6 +6940,24 @@ function (_super) {
6859
6940
  enumerable: false,
6860
6941
  configurable: true
6861
6942
  });
6943
+ Object.defineProperty(__proto, "circularFallback", {
6944
+ /**
6945
+ * Set panel control mode for the case when circular cannot be enabled.
6946
+ * "linear" will set the view's range from the top of the first panel to the top of the last panel.
6947
+ * "bound" will prevent the view from going out of the first/last panel, so it won't show empty spaces before/after the first/last panel.
6948
+ * @ko 순환 모드 사용 불가능시 사용할 패널 조작 범위 설정 방식을 변경합니다.
6949
+ * "linear" 사용시 시점이 첫번째 엘리먼트 위에서부터 마지막 엘리먼트 위까지 움직일 수 있도록 설정합니다.
6950
+ * "bound" 사용시 시점이 첫번째 엘리먼트와 마지막 엘리먼트의 끝과 끝 사이에서 움직일 수 있도록 설정합니다.
6951
+ * @see CIRCULAR_FALLBACK
6952
+ * @type {string}
6953
+ * @default "linear"
6954
+ */
6955
+ get: function () {
6956
+ return this._circularFallback;
6957
+ },
6958
+ enumerable: false,
6959
+ configurable: true
6960
+ });
6862
6961
  Object.defineProperty(__proto, "bound", {
6863
6962
  /**
6864
6963
  * Prevent the view(camera element) from going out of the first/last panel, so it won't show empty spaces before/after the first/last panel
@@ -7819,7 +7918,7 @@ function (_super) {
7819
7918
  });
7820
7919
  }
7821
7920
 
7822
- (_a = this._plugins).push.apply(_a, __spreadArray([], __read(plugins)));
7921
+ (_a = this._plugins).push.apply(_a, __spread(plugins));
7823
7922
 
7824
7923
  return this;
7825
7924
  };
@@ -8066,22 +8165,14 @@ function (_super) {
8066
8165
  };
8067
8166
 
8068
8167
  __proto._createCamera = function () {
8069
- var cameraOption = {
8070
- align: this._align
8071
- };
8072
-
8073
- if (this._circular) {
8074
- if (this._bound) {
8075
- // eslint-disable-next-line no-console
8076
- console.warn("\"circular\" and \"bound\" option cannot be used together, ignoring bound.");
8077
- }
8078
-
8079
- return new CircularCamera(cameraOption);
8080
- } else if (this._bound) {
8081
- return new BoundCamera(cameraOption);
8082
- } else {
8083
- return new LinearCamera(cameraOption);
8168
+ if (this._circular && this._bound) {
8169
+ // eslint-disable-next-line no-console
8170
+ console.warn("\"circular\" and \"bound\" option cannot be used together, ignoring bound.");
8084
8171
  }
8172
+
8173
+ return new Camera({
8174
+ align: this._align
8175
+ });
8085
8176
  };
8086
8177
 
8087
8178
  __proto._createRenderer = function () {
@@ -8145,7 +8236,7 @@ function (_super) {
8145
8236
  */
8146
8237
 
8147
8238
 
8148
- Flicking.VERSION = "4.4.2";
8239
+ Flicking.VERSION = "4.5.0";
8149
8240
  return Flicking;
8150
8241
  }(Component);
8151
8242
 
@@ -8184,7 +8275,7 @@ var withFlickingMethods = function (prototype, flickingName) {
8184
8275
  args[_i] = arguments[_i];
8185
8276
  }
8186
8277
 
8187
- return (_a = descriptor.value).call.apply(_a, __spreadArray([this[flickingName]], __read(args)));
8278
+ return (_a = descriptor.value).call.apply(_a, __spread([this[flickingName]], args));
8188
8279
  }
8189
8280
  });
8190
8281
  } else {
@@ -8208,7 +8299,7 @@ var withFlickingMethods = function (prototype, flickingName) {
8208
8299
  args[_i] = arguments[_i];
8209
8300
  }
8210
8301
 
8211
- return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spreadArray([this[flickingName]], __read(args)));
8302
+ return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spread([this[flickingName]], args));
8212
8303
  };
8213
8304
  }
8214
8305
 
@@ -8222,7 +8313,7 @@ var sync = (function (flicking, diffResult, rendered) {
8222
8313
  var renderer = flicking.renderer;
8223
8314
  var panels = renderer.panels;
8224
8315
 
8225
- var prevList = __spreadArray([], __read(diffResult.prevList));
8316
+ var prevList = __spread(diffResult.prevList);
8226
8317
 
8227
8318
  if (diffResult.removed.length > 0) {
8228
8319
  var endIdx_1 = -1;
@@ -8302,13 +8393,13 @@ var sync = (function (flicking, diffResult, rendered) {
8302
8393
  });
8303
8394
 
8304
8395
  var batchInsert = function (renderer, diffResult, addedElements, startIdx, endIdx) {
8305
- renderer.batchInsert.apply(renderer, __spreadArray([], __read(diffResult.added.slice(startIdx, endIdx).map(function (index, elIdx) {
8396
+ renderer.batchInsert.apply(renderer, __spread(diffResult.added.slice(startIdx, endIdx).map(function (index, elIdx) {
8306
8397
  return {
8307
8398
  index: index,
8308
8399
  elements: [addedElements[elIdx]],
8309
8400
  hasDOMInElements: false
8310
8401
  };
8311
- }))));
8402
+ })));
8312
8403
  };
8313
8404
 
8314
8405
  var batchRemove = function (renderer, startIdx, endIdx) {
@@ -8333,16 +8424,16 @@ var getRenderingPanels = (function (flicking, diffResult) {
8333
8424
  map[prev] = current;
8334
8425
  return map;
8335
8426
  }, {});
8336
- return __spreadArray(__spreadArray([], __read(flicking.panels.filter(function (panel) {
8427
+ return __spread(flicking.panels.filter(function (panel) {
8337
8428
  return !removedPanels[panel.index];
8338
8429
  }) // Sort panels by position
8339
8430
  .sort(function (panel1, panel2) {
8340
8431
  return panel1.position + panel1.offset - (panel2.position + panel2.offset);
8341
8432
  }).map(function (panel) {
8342
8433
  return diffResult.list[maintainedMap[panel.index]];
8343
- })), false), __read(diffResult.added.map(function (idx) {
8434
+ }), diffResult.added.map(function (idx) {
8344
8435
  return diffResult.list[idx];
8345
- })));
8436
+ }));
8346
8437
  });
8347
8438
 
8348
8439
  var getDefaultCameraTransform = (function (align, horizontal, firstPanelSize) {
@@ -8396,5 +8487,5 @@ var parseAlign = function (alignVal) {
8396
8487
  * egjs projects are licensed under the MIT license
8397
8488
  */
8398
8489
 
8399
- export { ALIGN, AnchorPoint, AnimatingState, AxesController, BoundCamera, CLASS, Camera, CircularCamera, Control, DIRECTION, DisabledState, DraggingState, CODE as ERROR_CODE, EVENTS, ExternalRenderer, FlickingError, FreeControl, HoldingState, IdleState, LinearCamera, MOVE_TYPE, NormalRenderingStrategy, Panel, Renderer, SnapControl, State, StateMachine, StrictControl, VanillaElementProvider, VanillaRenderer, Viewport, VirtualElementProvider, VirtualManager, VirtualPanel, VirtualRenderingStrategy, checkExistence, circulateIndex, circulatePosition, clamp, Flicking as default, find, findIndex, findRight, getDefaultCameraTransform, getDirection, getElement, getFlickingAttached, getMinusCompensatedIndex, getProgress, getRenderingPanels, getStyle, includes, isBetween, isString, merge, parseAlign$1 as parseAlign, parseArithmeticExpression, parseArithmeticSize, parseBounce, parseCSSSizeValue, parseElement, parsePanelAlign, range, setPrototypeOf, setSize, sync, toArray, withFlickingMethods };
8490
+ export { ALIGN, AnchorPoint, AnimatingState, AxesController, BoundCameraMode, CIRCULAR_FALLBACK, CLASS, Camera, CircularCameraMode, Control, DIRECTION, DisabledState, DraggingState, CODE as ERROR_CODE, EVENTS, ExternalRenderer, FlickingError, FreeControl, HoldingState, IdleState, LinearCameraMode, MOVE_TYPE, NormalRenderingStrategy, Panel, Renderer, SnapControl, State, StateMachine, StrictControl, VanillaElementProvider, VanillaRenderer, Viewport, VirtualElementProvider, VirtualManager, VirtualPanel, VirtualRenderingStrategy, checkExistence, circulateIndex, circulatePosition, clamp, Flicking as default, find, findIndex, findRight, getDefaultCameraTransform, getDirection, getElement, getFlickingAttached, getMinusCompensatedIndex, getProgress, getRenderingPanels, getStyle, includes, isBetween, isString, merge, parseAlign$1 as parseAlign, parseArithmeticExpression, parseArithmeticSize, parseBounce, parseCSSSizeValue, parseElement, parsePanelAlign, range, setPrototypeOf, setSize, sync, toArray, withFlickingMethods };
8400
8491
  //# sourceMappingURL=flicking.esm.js.map