@egjs/flicking 4.2.5 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +1 -1
  2. package/declaration/Flicking.d.ts +27 -11
  3. package/declaration/camera/Camera.d.ts +3 -2
  4. package/declaration/camera/CircularCamera.d.ts +2 -1
  5. package/declaration/const/error.d.ts +3 -1
  6. package/declaration/const/external.d.ts +5 -0
  7. package/declaration/core/AutoResizer.d.ts +13 -0
  8. package/declaration/core/VirtualManager.d.ts +37 -0
  9. package/declaration/core/index.d.ts +2 -1
  10. package/declaration/core/panel/Panel.d.ts +17 -10
  11. package/declaration/core/panel/VirtualPanel.d.ts +19 -0
  12. package/declaration/core/panel/index.d.ts +4 -4
  13. package/declaration/core/panel/provider/ElementProvider.d.ts +8 -0
  14. package/declaration/core/panel/provider/VanillaElementProvider.d.ts +12 -0
  15. package/declaration/core/panel/provider/VirtualElementProvider.d.ts +15 -0
  16. package/declaration/core/panel/provider/index.d.ts +5 -0
  17. package/declaration/index.d.ts +11 -1
  18. package/declaration/renderer/ExternalRenderer.d.ts +1 -1
  19. package/declaration/renderer/Renderer.d.ts +18 -13
  20. package/declaration/renderer/VanillaRenderer.d.ts +2 -7
  21. package/declaration/renderer/index.d.ts +1 -0
  22. package/declaration/renderer/strategy/NormalRenderingStrategy.d.ts +23 -0
  23. package/declaration/renderer/strategy/RenderingStrategy.d.ts +15 -0
  24. package/declaration/renderer/strategy/VirtualRenderingStrategy.d.ts +17 -0
  25. package/declaration/renderer/strategy/index.d.ts +5 -0
  26. package/declaration/utils.d.ts +7 -1
  27. package/dist/flicking.esm.js +1616 -562
  28. package/dist/flicking.esm.js.map +1 -1
  29. package/dist/flicking.js +1571 -494
  30. package/dist/flicking.js.map +1 -1
  31. package/dist/flicking.min.js +2 -2
  32. package/dist/flicking.min.js.map +1 -1
  33. package/dist/flicking.pkgd.js +8733 -6647
  34. package/dist/flicking.pkgd.js.map +1 -1
  35. package/dist/flicking.pkgd.min.js +2 -2
  36. package/dist/flicking.pkgd.min.js.map +1 -1
  37. package/package.json +10 -22
  38. package/src/Flicking.ts +163 -32
  39. package/src/camera/BoundCamera.ts +2 -2
  40. package/src/camera/Camera.ts +49 -26
  41. package/src/camera/CircularCamera.ts +52 -27
  42. package/src/camera/LinearCamera.ts +1 -1
  43. package/src/cfc/sync.ts +2 -2
  44. package/src/const/error.ts +6 -3
  45. package/src/const/external.ts +6 -0
  46. package/src/control/AxesController.ts +15 -8
  47. package/src/control/Control.ts +7 -7
  48. package/src/control/FreeControl.ts +2 -2
  49. package/src/control/SnapControl.ts +3 -3
  50. package/src/control/StrictControl.ts +2 -2
  51. package/src/core/AutoResizer.ts +81 -0
  52. package/src/core/Viewport.ts +4 -4
  53. package/src/core/VirtualManager.ts +188 -0
  54. package/src/core/index.ts +3 -1
  55. package/src/core/panel/Panel.ts +68 -60
  56. package/src/core/panel/VirtualPanel.ts +110 -0
  57. package/src/core/panel/index.ts +5 -7
  58. package/src/core/panel/provider/ElementProvider.ts +14 -0
  59. package/src/core/panel/provider/VanillaElementProvider.ts +45 -0
  60. package/src/core/panel/provider/VirtualElementProvider.ts +48 -0
  61. package/src/core/panel/provider/index.ts +16 -0
  62. package/src/index.ts +12 -1
  63. package/src/index.umd.ts +2 -0
  64. package/src/renderer/ExternalRenderer.ts +7 -7
  65. package/src/renderer/Renderer.ts +173 -68
  66. package/src/renderer/VanillaRenderer.ts +28 -86
  67. package/src/renderer/index.ts +2 -0
  68. package/src/renderer/strategy/NormalRenderingStrategy.ts +106 -0
  69. package/src/renderer/strategy/RenderingStrategy.ts +21 -0
  70. package/src/renderer/strategy/VirtualRenderingStrategy.ts +110 -0
  71. package/src/renderer/strategy/index.ts +17 -0
  72. package/src/utils.ts +36 -2
  73. package/declaration/core/panel/ElementPanel.d.ts +0 -14
  74. package/declaration/core/panel/ExternalPanel.d.ts +0 -9
  75. package/declaration/exports.d.ts +0 -10
  76. package/src/core/panel/ElementPanel.ts +0 -52
  77. package/src/core/panel/ExternalPanel.ts +0 -32
  78. package/src/exports.ts +0 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@egjs/flicking",
3
- "version": "4.2.5",
3
+ "version": "4.4.1",
4
4
  "description": "Everyday 30 million people experience. It's reliable, flexible and extendable carousel.",
5
5
  "main": "dist/flicking.js",
6
6
  "module": "dist/flicking.esm.js",
@@ -13,9 +13,9 @@
13
13
  "declaration": "rm -rf declaration && tsc -p tsconfig.declaration.json",
14
14
  "css": "postcss css/*.css --use autoprefixer postcss-clean -d dist/ -m",
15
15
  "printsizes": "print-sizes ./dist --exclude=\\.map",
16
- "test": "karma start",
17
- "test:chrome": "karma start --chrome",
18
- "coverage": "karma start --coverage && print-coveralls --sort=desc",
16
+ "test": "npm run test --prefix test/unit",
17
+ "test:chrome": "npm run test:chrome --prefix test/unit",
18
+ "test:cfc": "npm run test --prefix test/cfc",
19
19
  "lint": "eslint 'src/**/*.ts'",
20
20
  "lint:test": "eslint 'test/unit/**/*.ts'",
21
21
  "jsdoc": "jsdoc -c jsdoc.json",
@@ -69,26 +69,22 @@
69
69
  "egjs"
70
70
  ],
71
71
  "devDependencies": {
72
+ "@babel/preset-env": "^7.16.0",
72
73
  "@daybrush/jsdoc": "^0.3.10",
73
- "@egjs/flicking-plugins": "^4.0.0-beta.1",
74
+ "@egjs/flicking-plugins": "^4.2.2",
74
75
  "@egjs/release-helper": "0.0.3",
75
76
  "@rollup/plugin-babel": "^5.3.0",
76
77
  "@rollup/plugin-commonjs": "^11.1.0",
77
78
  "@rollup/plugin-node-resolve": "^7.1.3",
78
79
  "@rollup/plugin-replace": "^2.4.1",
79
- "@types/chai": "^4.2.15",
80
80
  "@types/fs-extra": "^9.0.11",
81
- "@types/karma-chai": "^0.1.1",
82
- "@types/mocha": "^5.2.5",
83
81
  "@types/node": "^14.14.35",
84
- "@types/sinon": "^7.0.3",
85
82
  "@typescript-eslint/eslint-plugin": "^4.18.0",
86
83
  "@typescript-eslint/eslint-plugin-tslint": "^4.18.0",
87
84
  "@typescript-eslint/parser": "^4.18.0",
88
85
  "autoprefixer": "^9.8.5",
89
86
  "babel-loader": "^8.2.2",
90
- "chai": "^4.3.4",
91
- "chalk": "^2.4.2",
87
+ "babel-preset-env": "^1.7.0",
92
88
  "concurrently": "^6.0.0",
93
89
  "core-js": "^3.9.1",
94
90
  "coveralls": "^3.0.2",
@@ -105,15 +101,7 @@
105
101
  "http-serve": "^1.0.1",
106
102
  "husky": "^1.3.1",
107
103
  "jsdoc-to-mdx": "^1.0.5",
108
- "karma": "^3.1.4",
109
- "karma-chai": "^0.1.0",
110
- "karma-chrome-launcher": "^2.2.0",
111
- "karma-mocha": "^1.3.0",
112
- "karma-mocha-reporter": "^2.2.5",
113
- "karma-sinon": "^1.0.5",
114
- "karma-typescript-egjs": "^4.0.0",
115
- "karma-viewport": "^1.0.8",
116
- "mocha": "^5.2.0",
104
+ "karma-typescript-es6-transform": "^5.5.2",
117
105
  "postcss-clean": "^1.2.2",
118
106
  "postcss-cli": "^7.1.1",
119
107
  "print-coveralls": "^1.2.2",
@@ -124,10 +112,9 @@
124
112
  "rollup-plugin-postcss": "^3.1.3",
125
113
  "rollup-plugin-prototype-minify": "^1.1.0",
126
114
  "rollup-plugin-serve": "^1.1.0",
115
+ "rollup-plugin-terser": "^7.0.2",
127
116
  "rollup-plugin-typescript2": "^0.30.0",
128
- "rollup-plugin-uglify": "^6.0.4",
129
117
  "rollup-plugin-visualizer": "^4.2.1",
130
- "sinon": "^7.2.3",
131
118
  "sync-exec": "^0.6.2",
132
119
  "ts-mock-imports": "^1.3.3",
133
120
  "tsconfig-paths-webpack-plugin": "^3.5.1",
@@ -140,6 +127,7 @@
140
127
  "dependencies": {
141
128
  "@egjs/axes": "^2.8.0",
142
129
  "@egjs/component": "^3.0.1",
130
+ "@egjs/imready": "^1.1.3",
143
131
  "@egjs/list-differ": "^1.0.0"
144
132
  },
145
133
  "husky": {
package/src/Flicking.ts CHANGED
@@ -6,10 +6,13 @@ import Component, { ComponentEvent } from "@egjs/component";
6
6
 
7
7
  import FlickingError from "./core/FlickingError";
8
8
  import Viewport from "./core/Viewport";
9
+ import AutoResizer from "./core/AutoResizer";
9
10
  import { Panel } from "./core/panel";
11
+ import { VanillaElementProvider } from "./core/panel/provider";
12
+ import VirtualManager, { VirtualOptions } from "./core/VirtualManager";
10
13
  import { Control, SnapControl, SnapControlOptions, FreeControl, StrictControl, FreeControlOptions, StrictControlOptions } from "./control";
11
14
  import { BoundCamera, Camera, CircularCamera, LinearCamera } from "./camera";
12
- import { Renderer, VanillaRenderer, ExternalRenderer } from "./renderer";
15
+ import { Renderer, VanillaRenderer, ExternalRenderer, RendererOptions, NormalRenderingStrategy, VirtualRenderingStrategy } from "./renderer";
13
16
  import { EVENTS, ALIGN, MOVE_TYPE, DIRECTION } from "./const/external";
14
17
  import * as ERROR from "./const/error";
15
18
  import { findIndex, getElement, includes, parseElement } from "./utils";
@@ -53,6 +56,7 @@ export interface FlickingOptions {
53
56
  adaptive: boolean;
54
57
  panelsPerView: number;
55
58
  noPanelStyleOverride: boolean;
59
+ resizeOnContentsReady: boolean;
56
60
  // EVENT
57
61
  needPanelThreshold: number;
58
62
  preventEventsBeforeInit: boolean;
@@ -71,12 +75,16 @@ export interface FlickingOptions {
71
75
  disableOnInit: boolean;
72
76
  // PERFORMANCE
73
77
  renderOnlyVisible: boolean;
78
+ virtual: VirtualOptions | null;
74
79
  // OTHERS
75
80
  autoInit: boolean;
76
81
  autoResize: boolean;
82
+ useResizeObserver: boolean;
83
+ externalRenderer: ExternalRenderer | null;
84
+ // @deprecated
77
85
  renderExternal: {
78
- renderer: typeof ExternalRenderer;
79
- rendererOptions: {[key: string]: any};
86
+ renderer: new (options: RendererOptions) => ExternalRenderer;
87
+ rendererOptions: RendererOptions;
80
88
  } | null;
81
89
  }
82
90
 
@@ -101,9 +109,11 @@ class Flicking extends Component<FlickingEvents> {
101
109
 
102
110
  // Core components
103
111
  private _viewport: Viewport;
112
+ private _autoResizer: AutoResizer;
104
113
  private _camera: Camera;
105
114
  private _control: Control;
106
115
  private _renderer: Renderer;
116
+ private _virtualManager: VirtualManager;
107
117
 
108
118
  // Options
109
119
  private _align: FlickingOptions["align"];
@@ -114,6 +124,8 @@ class Flicking extends Component<FlickingEvents> {
114
124
  private _adaptive: FlickingOptions["adaptive"];
115
125
  private _panelsPerView: FlickingOptions["panelsPerView"];
116
126
  private _noPanelStyleOverride: FlickingOptions["noPanelStyleOverride"];
127
+ private _resizeOnContentsReady: FlickingOptions["resizeOnContentsReady"];
128
+ private _virtual: FlickingOptions["virtual"];
117
129
 
118
130
  private _needPanelThreshold: FlickingOptions["needPanelThreshold"];
119
131
  private _preventEventsBeforeInit: FlickingOptions["preventEventsBeforeInit"];
@@ -133,8 +145,10 @@ class Flicking extends Component<FlickingEvents> {
133
145
 
134
146
  private _renderOnlyVisible: FlickingOptions["renderOnlyVisible"];
135
147
 
136
- private _autoResize: FlickingOptions["autoResize"];
137
148
  private _autoInit: FlickingOptions["autoInit"];
149
+ private _autoResize: FlickingOptions["autoResize"];
150
+ private _useResizeObserver: FlickingOptions["useResizeObserver"];
151
+ private _externalRenderer: FlickingOptions["externalRenderer"];
138
152
  private _renderExternal: FlickingOptions["renderExternal"];
139
153
 
140
154
  // Internal State
@@ -205,6 +219,16 @@ class Flicking extends Component<FlickingEvents> {
205
219
  * @readonly
206
220
  */
207
221
  public get circularEnabled() { return this._camera.controlParams.circular; }
222
+ /**
223
+ * Whether the `virtual` option is enabled.
224
+ * The {@link Flicking#virtual virtual} option can't be enabled when {@link Flicking#panelsPerView panelsPerView} is less or equal than zero.
225
+ * @ko {@link Flicking#virtual virtual} 옵션이 활성화되었는지 여부를 나타내는 멤버 변수.
226
+ * {@link Flicking#virtual virtual} 옵션은 {@link Flicking#panelsPerView panelsPerView} 옵션의 값이 0보다 같거나 작으면 비활성화됩니다.
227
+ * @type {boolean}
228
+ * @default false
229
+ * @readonly
230
+ */
231
+ public get virtualEnabled() { return this._panelsPerView > 0 && this._virtual != null; }
208
232
  /**
209
233
  * Index number of the {@link Flicking#currentPanel currentPanel}
210
234
  * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호
@@ -356,6 +380,15 @@ class Flicking extends Component<FlickingEvents> {
356
380
  * @default false
357
381
  */
358
382
  public get noPanelStyleOverride() { return this._noPanelStyleOverride; }
383
+ /**
384
+ * Enabling this option will automatically call {@link Flicking#resize} when all image/video inside panels are loaded.
385
+ * This can be useful when you have contents inside Flicking that changes its size when it's loaded
386
+ * @ko 이 옵션을 활성화할 경우, Flicking 패널 내부의 이미지/비디오들이 로드되었을 때 자동으로 {@link Flicking#resize}를 호출합니다.
387
+ * 이 동작은 Flicking 내부에 로드 전/후로 크기가 변하는 콘텐츠를 포함하고 있을 때 유용하게 사용하실 수 있습니다.
388
+ * @type {boolean}
389
+ * @default false
390
+ */
391
+ public get resizeOnContentsReady() { return this._resizeOnContentsReady; }
359
392
  // EVENTS
360
393
  /**
361
394
  * A Threshold from viewport edge before triggering `needPanel` event
@@ -504,12 +537,45 @@ class Flicking extends Component<FlickingEvents> {
504
537
  public get disableOnInit() { return this._disableOnInit; }
505
538
  // PERFORMANCE
506
539
  /**
507
- * Whether to render visible panels only. This can dramatically increase performance when there're many panels.
508
- * @ko 보이는 패널만 렌더링할지 여부를 설정합니다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있습니다.
540
+ * Whether to render visible panels only. This can dramatically increase performance when there're many panels
541
+ * @ko 보이는 패널만 렌더링할지 여부를 설정합니다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있습니다
509
542
  * @type {boolean}
510
543
  * @default false
511
544
  */
512
545
  public get renderOnlyVisible() { return this._renderOnlyVisible; }
546
+ /**
547
+ * By enabling this option, it will reduce memory consumption by restricting the number of DOM elements to `panelsPerView + 1`
548
+ * Must be used with `panelsPerview`.
549
+ * After Flicking's initialized, this property can be used to add/remove the panel count.
550
+ * @ko 이 옵션을 활성화할 경우 패널 엘리먼트의 개수를 `panelsPerView + 1` 개로 고정함으로써, 메모리 사용량을 줄일 수 있습니다.
551
+ * `panelsPerView` 옵션과 함께 사용되어야만 합니다.
552
+ * Flicking 초기화 이후에, 이 프로퍼티는 렌더링하는 패널의 개수를 추가/제거하기 위해 사용될 수 있습니다.
553
+ * @type {VirtualManager}
554
+ * @property {function} renderPanel A rendering function for the panel element's innerHTML<ko>패널 엘리먼트의 innerHTML을 렌더링하는 함수</ko>
555
+ * @property {number} initialPanelCount Initial panel count to render<ko>최초로 렌더링할 패널의 개수</ko>
556
+ * @property {boolean} [cache=false] Whether to cache rendered panel's innerHTML<ko>렌더링된 패널의 innerHTML 정보를 캐시할지 여부</ko>
557
+ * @property {string} [panelClass="flicking-panel"] The class name that will be applied to rendered panel elements<ko>렌더링되는 패널 엘리먼트에 적용될 클래스 이름</ko>
558
+ * @example
559
+ * ```ts
560
+ * import Flicking, { VirtualPanel } from "@egjs/flicking";
561
+ *
562
+ * const flicking = new Flicking("#some_el", {
563
+ * panelsPerView: 3,
564
+ * virtual: {
565
+ * renderPanel: (panel: VirtualPanel, index: number) => `Panel ${index}`,
566
+ * initialPanelCount: 100
567
+ * }
568
+ * });
569
+ *
570
+ * // Add 100 virtual panels (at the end)
571
+ * flicking.virtual.append(100);
572
+ *
573
+ * // Remove 100 virtual panels from 0 to 100
574
+ * flicking.virtual.remove(0, 100);
575
+ * ```
576
+ */
577
+ public get virtual() { return this._virtualManager; }
578
+
513
579
  // OTHERS
514
580
  /**
515
581
  * Call {@link Flicking#init init()} automatically when creating Flicking's instance
@@ -520,22 +586,35 @@ class Flicking extends Component<FlickingEvents> {
520
586
  */
521
587
  public get autoInit() { return this._autoInit; }
522
588
  /**
523
- * Attach Flicking's {@link Flicking#resize resize} method to window's resize event.
524
- * Flicking will automatically call {@link Flicking#resize resize} window size and orientation change.
525
- * @ko Flicking의 {@link Flicking#resize resize} 메소드를 window의 resize 이벤트 핸들러로 등록합니다.
526
- * 설정시 window 창 크기 및 orientation 변경에 의해 자동으로 {@link Flicking#resize resize}를 호출합니다.
589
+ * Whether to automatically call {@link Flicking#resize resize()} when the viewport element(.flicking-viewport)'s size is changed
590
+ * @ko 뷰포트 엘리먼트(.flicking-viewport)의 크기 변경시 {@link Flicking#resize resize()} 메소드를 자동으로 호출할지 여부를 설정합니다
527
591
  * @type {boolean}
528
592
  * @default true
529
593
  */
530
594
  public get autoResize() { return this._autoResize; }
595
+ /**
596
+ * Whether to listen {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}'s event instead of Window's {@link https://developer.mozilla.org/ko/docs/Web/API/Window/resize_event resize} event when using the `autoResize` option
597
+ * @ko autoResize 옵션 사용시 {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}의 이벤트를 Window객체의 {@link https://developer.mozilla.org/ko/docs/Web/API/Window/resize_event resize} 이벤트 대신 수신할지 여부를 설정합니다
598
+ * @type {boolean}
599
+ * @default true
600
+ */
601
+ public get useResizeObserver() { return this._useResizeObserver; }
531
602
  /**
532
603
  * This is an option for the frameworks(React, Vue, Angular, ...). Don't set it as it's automatically managed by Flicking.
533
604
  * @ko 프레임워크(React, Vue, Angular, ...)에서만 사용하는 옵션으로, 자동으로 설정되므로 따로 사용하실 필요 없습니다!
534
- * @type {boolean}
535
- * @default false
605
+ * @default null
536
606
  * @internal
537
607
  * @readonly
538
608
  */
609
+ public get externalRenderer() { return this._externalRenderer; }
610
+ /**
611
+ * This is an option for the frameworks(React, Vue, Angular, ...). Don't set it as it's automatically managed by Flicking.
612
+ * @ko 프레임워크(React, Vue, Angular, ...)에서만 사용하는 옵션으로, 자동으로 설정되므로 따로 사용하실 필요 없습니다!
613
+ * @default null
614
+ * @internal
615
+ * @readonly
616
+ * @deprecated
617
+ */
539
618
  public get renderExternal() { return this._renderExternal; }
540
619
 
541
620
  // Options Setter
@@ -553,6 +632,7 @@ class Flicking extends Component<FlickingEvents> {
553
632
  public set adaptive(val: FlickingOptions["adaptive"]) { this._adaptive = val; }
554
633
  public set panelsPerView(val: FlickingOptions["panelsPerView"]) { this._panelsPerView = val; }
555
634
  public set noPanelStyleOverride(val: FlickingOptions["noPanelStyleOverride"]) { this._noPanelStyleOverride = val; }
635
+ public set resizeOnContentsReady(val: FlickingOptions["resizeOnContentsReady"]) { this._resizeOnContentsReady = val; }
556
636
  // EVENTS
557
637
  public set needPanelThreshold(val: FlickingOptions["needPanelThreshold"]) { this._needPanelThreshold = val; }
558
638
  public set preventEventsBeforeInit(val: FlickingOptions["preventEventsBeforeInit"]) { this._preventEventsBeforeInit = val; }
@@ -587,7 +667,23 @@ class Flicking extends Component<FlickingEvents> {
587
667
  // PERFORMANCE
588
668
  public set renderOnlyVisible(val: FlickingOptions["renderOnlyVisible"]) { this._renderOnlyVisible = val; }
589
669
  // OTHERS
590
- public set autoResize(val: FlickingOptions["autoResize"]) { this._autoResize = val; }
670
+ public set autoResize(val: FlickingOptions["autoResize"]) {
671
+ this._autoResize = val;
672
+
673
+ if (val) {
674
+ this._autoResizer.enable();
675
+ } else {
676
+ this._autoResizer.disable();
677
+ }
678
+ }
679
+
680
+ public set useResizeObserver(val: FlickingOptions["useResizeObserver"]) {
681
+ this._useResizeObserver = val;
682
+
683
+ if (this._autoResize) {
684
+ this._autoResizer.enable();
685
+ }
686
+ }
591
687
 
592
688
  /**
593
689
  * @param root A root HTMLElement to initialize Flicking on it. When it's a typeof `string`, it should be a css selector string
@@ -626,6 +722,7 @@ class Flicking extends Component<FlickingEvents> {
626
722
  adaptive = false,
627
723
  panelsPerView = -1,
628
724
  noPanelStyleOverride = false,
725
+ resizeOnContentsReady = false,
629
726
  needPanelThreshold = 0,
630
727
  preventEventsBeforeInit = true,
631
728
  deceleration = 0.0075,
@@ -640,8 +737,11 @@ class Flicking extends Component<FlickingEvents> {
640
737
  preventClickOnDrag = true,
641
738
  disableOnInit = false,
642
739
  renderOnlyVisible = false,
740
+ virtual = null,
643
741
  autoInit = true,
644
742
  autoResize = true,
743
+ useResizeObserver = true,
744
+ externalRenderer = null,
645
745
  renderExternal = null
646
746
  }: Partial<FlickingOptions> = {}) {
647
747
  super();
@@ -659,6 +759,8 @@ class Flicking extends Component<FlickingEvents> {
659
759
  this._adaptive = adaptive;
660
760
  this._panelsPerView = panelsPerView;
661
761
  this._noPanelStyleOverride = noPanelStyleOverride;
762
+ this._resizeOnContentsReady = resizeOnContentsReady;
763
+ this._virtual = virtual;
662
764
  this._needPanelThreshold = needPanelThreshold;
663
765
  this._preventEventsBeforeInit = preventEventsBeforeInit;
664
766
  this._deceleration = deceleration;
@@ -673,17 +775,19 @@ class Flicking extends Component<FlickingEvents> {
673
775
  this._preventClickOnDrag = preventClickOnDrag;
674
776
  this._disableOnInit = disableOnInit;
675
777
  this._renderOnlyVisible = renderOnlyVisible;
676
- this._autoResize = autoResize;
677
778
  this._autoInit = autoInit;
779
+ this._autoResize = autoResize;
780
+ this._useResizeObserver = useResizeObserver;
781
+ this._externalRenderer = externalRenderer;
678
782
  this._renderExternal = renderExternal;
679
783
 
680
784
  // Create core components
681
785
  this._viewport = new Viewport(getElement(root));
786
+ this._autoResizer = new AutoResizer(this);
682
787
  this._renderer = this._createRenderer();
683
788
  this._camera = this._createCamera();
684
789
  this._control = this._createControl();
685
-
686
- this.resize = this.resize.bind(this);
790
+ this._virtualManager = new VirtualManager(this, virtual);
687
791
 
688
792
  if (this._autoInit) {
689
793
  void this.init();
@@ -704,10 +808,12 @@ class Flicking extends Component<FlickingEvents> {
704
808
  const camera = this._camera;
705
809
  const renderer = this._renderer;
706
810
  const control = this._control;
811
+ const virtualManager = this._virtualManager;
707
812
  const originalTrigger = this.trigger;
708
813
  const preventEventsBeforeInit = this._preventEventsBeforeInit;
709
814
 
710
815
  camera.init(this);
816
+ virtualManager.init();
711
817
  renderer.init(this);
712
818
  control.init(this);
713
819
 
@@ -721,7 +827,7 @@ class Flicking extends Component<FlickingEvents> {
721
827
  await this._moveToInitialPanel();
722
828
 
723
829
  if (this._autoResize) {
724
- window.addEventListener("resize", this.resize);
830
+ this._autoResizer.enable();
725
831
  }
726
832
  if (this._preventClickOnDrag) {
727
833
  control.controller.addPreventClickHandler();
@@ -729,6 +835,7 @@ class Flicking extends Component<FlickingEvents> {
729
835
  if (this._disableOnInit) {
730
836
  this.disableInput();
731
837
  }
838
+ renderer.checkPanelContentsReady(renderer.panels);
732
839
 
733
840
  this._plugins.forEach(plugin => plugin.init(this));
734
841
 
@@ -748,11 +855,9 @@ class Flicking extends Component<FlickingEvents> {
748
855
  * @return {void}
749
856
  */
750
857
  public destroy(): void {
751
- if (!this._initialized) return;
752
-
753
858
  this.off();
754
- window.removeEventListener("resize", this.resize);
755
859
 
860
+ this._autoResizer.disable();
756
861
  this._control.destroy();
757
862
  this._camera.destroy();
758
863
  this._renderer.destroy();
@@ -938,7 +1043,7 @@ class Flicking extends Component<FlickingEvents> {
938
1043
  * @param {boolean} [options.includePanelHTML=false] Include panel's `outerHTML` to the returning status<ko>패널의 `outerHTML`을 반환값에 포함시킵니다</ko>
939
1044
  * @param {boolean} [options.visiblePanelsOnly=false] Include only {@link Flicking#visiblePanel visiblePanel}'s HTML. This option is available only when the `includePanelHTML` is true
940
1045
  * <ko>현재 보이는 패널({@link Flicking#visiblePanel visiblePanel})의 HTML만 반환합니다. `includePanelHTML`이 `true`일 경우에만 동작합니다.</ko>
941
- * @return {Partial<Status>} An object with current status value information<ko>현재 상태값 정보를 가진 객체.</ko>
1046
+ * @return {Status} An object with current status value information<ko>현재 상태값 정보를 가진 객체.</ko>
942
1047
  */
943
1048
  public getStatus({
944
1049
  index = true,
@@ -1013,8 +1118,8 @@ class Flicking extends Component<FlickingEvents> {
1013
1118
 
1014
1119
  // Can't add/remove panels on external rendering
1015
1120
  if (panels[0]?.html && !this._renderExternal) {
1016
- renderer.batchRemove({ index: 0, deleteCount: this.panels.length });
1017
- renderer.batchInsert({ index: 0, elements: parseElement(panels.map(panel => panel.html!)) });
1121
+ renderer.batchRemove({ index: 0, deleteCount: this.panels.length, hasDOMInElements: true });
1122
+ renderer.batchInsert({ index: 0, elements: parseElement(panels.map(panel => panel.html!)), hasDOMInElements: true });
1018
1123
  }
1019
1124
 
1020
1125
  if (index) {
@@ -1206,7 +1311,7 @@ class Flicking extends Component<FlickingEvents> {
1206
1311
  throw new FlickingError(ERROR.MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, ERROR.CODE.NOT_ALLOWED_IN_FRAMEWORK);
1207
1312
  }
1208
1313
 
1209
- return this._renderer.batchInsert({ index, elements: parseElement(element) });
1314
+ return this._renderer.batchInsert({ index, elements: parseElement(element), hasDOMInElements: true });
1210
1315
  }
1211
1316
 
1212
1317
  /**
@@ -1223,7 +1328,7 @@ class Flicking extends Component<FlickingEvents> {
1223
1328
  throw new FlickingError(ERROR.MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, ERROR.CODE.NOT_ALLOWED_IN_FRAMEWORK);
1224
1329
  }
1225
1330
 
1226
- return this._renderer.batchRemove({ index, deleteCount });
1331
+ return this._renderer.batchRemove({ index, deleteCount, hasDOMInElements: true });
1227
1332
  }
1228
1333
 
1229
1334
  private _createControl(): Control {
@@ -1269,15 +1374,39 @@ class Flicking extends Component<FlickingEvents> {
1269
1374
  }
1270
1375
 
1271
1376
  private _createRenderer(): Renderer {
1272
- const rendererOptions = {
1273
- align: this._align
1274
- };
1377
+ const externalRenderer = this._externalRenderer;
1378
+ if (this._virtual && this._panelsPerView <= 0) {
1379
+ // eslint-disable-next-line no-console
1380
+ console.warn("\"virtual\" and \"panelsPerView\" option should be used together, ignoring virtual.");
1381
+ }
1382
+
1383
+ return externalRenderer
1384
+ ? externalRenderer
1385
+ : this._renderExternal
1386
+ ? this._createExternalRenderer()
1387
+ : this._createVanillaRenderer();
1388
+ }
1275
1389
 
1276
- const renderExternal = this._renderExternal;
1390
+ private _createExternalRenderer(): ExternalRenderer {
1391
+ const {
1392
+ renderer,
1393
+ rendererOptions
1394
+ } = this._renderExternal!;
1277
1395
 
1278
- return renderExternal
1279
- ? new (renderExternal.renderer as any)({ ...rendererOptions, ...renderExternal.rendererOptions })
1280
- : new VanillaRenderer(rendererOptions);
1396
+ return new (renderer)({ align: this._align, ...rendererOptions });
1397
+ }
1398
+
1399
+ private _createVanillaRenderer(): VanillaRenderer {
1400
+ const virtual = this.virtualEnabled;
1401
+
1402
+ return new VanillaRenderer({
1403
+ align: this._align,
1404
+ strategy: virtual
1405
+ ? new VirtualRenderingStrategy()
1406
+ : new NormalRenderingStrategy({
1407
+ providerCtor: VanillaElementProvider
1408
+ })
1409
+ });
1281
1410
  }
1282
1411
 
1283
1412
  private async _moveToInitialPanel(): Promise<void> {
@@ -1287,6 +1416,8 @@ class Flicking extends Component<FlickingEvents> {
1287
1416
 
1288
1417
  if (!initialPanel) return;
1289
1418
 
1419
+ control.setActive(initialPanel, null, false);
1420
+
1290
1421
  return control.moveToPanel(initialPanel, {
1291
1422
  duration: 0
1292
1423
  });
@@ -23,7 +23,7 @@ class BoundCamera extends Camera {
23
23
  * @return {this}
24
24
  */
25
25
  public updateRange() {
26
- const flicking = getFlickingAttached(this._flicking, "Camera");
26
+ const flicking = getFlickingAttached(this._flicking);
27
27
  const renderer = flicking.renderer;
28
28
  const alignPos = this._alignPos;
29
29
 
@@ -61,7 +61,7 @@ class BoundCamera extends Camera {
61
61
  }
62
62
 
63
63
  public updateAnchors(): this {
64
- const flicking = getFlickingAttached(this._flicking, "Camera");
64
+ const flicking = getFlickingAttached(this._flicking);
65
65
  const panels = flicking.renderer.panels;
66
66
 
67
67
  if (panels.length <= 0) {