@egjs/flicking 4.4.2 → 4.6.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 (57) hide show
  1. package/TODO.md +3 -0
  2. package/declaration/Flicking.d.ts +15 -2
  3. package/declaration/camera/Camera.d.ts +28 -26
  4. package/declaration/camera/index.d.ts +2 -4
  5. package/declaration/camera/mode/BoundCameraMode.d.ts +13 -0
  6. package/declaration/camera/mode/CameraMode.d.ts +19 -0
  7. package/declaration/camera/mode/CircularCameraMode.d.ts +18 -0
  8. package/declaration/camera/mode/LinearCameraMode.d.ts +9 -0
  9. package/declaration/camera/mode/index.d.ts +6 -0
  10. package/declaration/const/external.d.ts +4 -0
  11. package/declaration/control/StrictControl.d.ts +1 -0
  12. package/declaration/core/AutoResizer.d.ts +3 -0
  13. package/declaration/core/ResizeWatcher.d.ts +33 -0
  14. package/declaration/renderer/Renderer.d.ts +13 -0
  15. package/declaration/type/external.d.ts +1 -3
  16. package/{css → dist/css}/flicking-inline.css +20 -13
  17. package/dist/css/flicking-inline.min.css +1 -0
  18. package/dist/css/flicking.css +44 -0
  19. package/dist/css/flicking.min.css +1 -0
  20. package/dist/flicking.esm.js +1491 -1251
  21. package/dist/flicking.esm.js.map +1 -1
  22. package/dist/flicking.js +1494 -1253
  23. package/dist/flicking.js.map +1 -1
  24. package/dist/flicking.min.js +2 -2
  25. package/dist/flicking.min.js.map +1 -1
  26. package/dist/flicking.pkgd.js +1466 -1225
  27. package/dist/flicking.pkgd.js.map +1 -1
  28. package/dist/flicking.pkgd.min.js +2 -2
  29. package/dist/flicking.pkgd.min.js.map +1 -1
  30. package/package.json +17 -7
  31. package/sass/flicking-inline.sass +30 -0
  32. package/sass/flicking.sass +23 -0
  33. package/src/Flicking.ts +127 -35
  34. package/src/camera/Camera.ts +162 -81
  35. package/src/camera/index.ts +3 -7
  36. package/src/camera/{BoundCamera.ts → mode/BoundCameraMode.ts} +46 -43
  37. package/src/camera/mode/CameraMode.ts +77 -0
  38. package/src/camera/mode/CircularCameraMode.ts +171 -0
  39. package/src/camera/mode/LinearCameraMode.ts +23 -0
  40. package/src/camera/mode/index.ts +14 -0
  41. package/src/cfc/sync.ts +29 -23
  42. package/src/cfc/withFlickingMethods.ts +3 -2
  43. package/src/const/external.ts +12 -0
  44. package/src/control/StrictControl.ts +10 -0
  45. package/src/core/AutoResizer.ts +33 -0
  46. package/src/core/ResizeWatcher.ts +133 -0
  47. package/src/renderer/Renderer.ts +92 -43
  48. package/css/flicking.css +0 -28
  49. package/declaration/camera/BoundCamera.d.ts +0 -9
  50. package/declaration/camera/CircularCamera.d.ts +0 -37
  51. package/declaration/camera/LinearCamera.d.ts +0 -5
  52. package/dist/flicking-inline.css +0 -2
  53. package/dist/flicking-inline.css.map +0 -1
  54. package/dist/flicking.css +0 -2
  55. package/dist/flicking.css.map +0 -1
  56. package/src/camera/CircularCamera.ts +0 -268
  57. package/src/camera/LinearCamera.ts +0 -35
@@ -0,0 +1,171 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import Panel from "../../core/panel/Panel";
6
+ import AnchorPoint from "../../core/AnchorPoint";
7
+ import { DIRECTION } from "../../const/external";
8
+ import { circulatePosition } from "../../utils";
9
+
10
+ import CameraMode from "./CameraMode";
11
+
12
+ /**
13
+ * A {@link Camera} mode that connects the last panel and the first panel, enabling continuous loop
14
+ * @ko 첫번째 패널과 마지막 패널이 이어진 상태로, 무한히 회전할 수 있는 종류의 {@link Camera} 모드
15
+ */
16
+ class CircularCameraMode extends CameraMode {
17
+ public checkAvailability(): boolean {
18
+ const flicking = this._flicking;
19
+ const renderer = flicking.renderer;
20
+ const panels = renderer.panels;
21
+
22
+ if (panels.length <= 0) {
23
+ return false;
24
+ }
25
+
26
+ const firstPanel = panels[0];
27
+ const lastPanel = panels[panels.length - 1];
28
+ const firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
29
+ const lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
30
+
31
+ const visibleSize = flicking.camera.size;
32
+ const panelSizeSum = lastPanelNext - firstPanelPrev;
33
+
34
+ const canSetCircularMode = panels
35
+ .every(panel => panelSizeSum - panel.size >= visibleSize);
36
+
37
+ return canSetCircularMode;
38
+ }
39
+
40
+ public getRange(): { min: number; max: number } {
41
+ const flicking = this._flicking;
42
+ const panels = flicking.renderer.panels;
43
+
44
+ if (panels.length <= 0) {
45
+ return { min: 0, max: 0 };
46
+ }
47
+
48
+ const firstPanel = panels[0];
49
+ const lastPanel = panels[panels.length - 1];
50
+ const firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
51
+ const lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
52
+
53
+ return { min: firstPanelPrev, max: lastPanelNext };
54
+ }
55
+
56
+ public getAnchors(): AnchorPoint[] {
57
+ const flicking = this._flicking;
58
+ const panels = flicking.renderer.panels;
59
+
60
+ return panels.map((panel, index) => new AnchorPoint({
61
+ index,
62
+ position: panel.position,
63
+ panel
64
+ }));
65
+ }
66
+
67
+ public findAnchorIncludePosition(position: number): AnchorPoint | null {
68
+ const camera = this._flicking.camera;
69
+ const range = camera.range;
70
+ const anchors = camera.anchorPoints;
71
+ const rangeDiff = camera.rangeDiff;
72
+ const anchorCount = anchors.length;
73
+ const positionInRange = circulatePosition(position, range.min, range.max);
74
+
75
+ let anchorInRange: AnchorPoint | null = super.findAnchorIncludePosition(positionInRange);
76
+
77
+ if (anchorCount > 0 && (position === range.min || position === range.max)) {
78
+ const possibleAnchors = [
79
+ anchorInRange,
80
+ new AnchorPoint({
81
+ index: 0,
82
+ position: anchors[0].position + rangeDiff,
83
+ panel: anchors[0].panel
84
+ }),
85
+ new AnchorPoint({
86
+ index: anchorCount - 1,
87
+ position: anchors[anchorCount - 1].position - rangeDiff,
88
+ panel: anchors[anchorCount - 1].panel
89
+ })
90
+ ].filter(anchor => !!anchor) as AnchorPoint[];
91
+
92
+ anchorInRange = possibleAnchors.reduce((nearest: AnchorPoint | null, anchor) => {
93
+ if (!nearest) return anchor;
94
+
95
+ return Math.abs(nearest.position - position) < Math.abs(anchor.position - position)
96
+ ? nearest
97
+ : anchor;
98
+ }, null);
99
+ }
100
+
101
+ if (!anchorInRange) return null;
102
+
103
+ if (position < range.min) {
104
+ const loopCount = -Math.floor((range.min - position) / rangeDiff) - 1;
105
+
106
+ return new AnchorPoint({
107
+ index: anchorInRange.index,
108
+ position: anchorInRange.position + rangeDiff * loopCount,
109
+ panel: anchorInRange.panel
110
+ });
111
+ } else if (position > range.max) {
112
+ const loopCount = Math.floor((position - range.max) / rangeDiff) + 1;
113
+
114
+ return new AnchorPoint({
115
+ index: anchorInRange.index,
116
+ position: anchorInRange.position + rangeDiff * loopCount,
117
+ panel: anchorInRange.panel
118
+ });
119
+ }
120
+
121
+ return anchorInRange;
122
+ }
123
+
124
+ public getCircularOffset(): number {
125
+ const flicking = this._flicking;
126
+ const camera = flicking.camera;
127
+
128
+ if (!camera.circularEnabled) return 0;
129
+
130
+ const toggled = flicking.panels.filter(panel => panel.toggled);
131
+ const toggledPrev = toggled.filter(panel => panel.toggleDirection === DIRECTION.PREV);
132
+ const toggledNext = toggled.filter(panel => panel.toggleDirection === DIRECTION.NEXT);
133
+
134
+ return this._calcPanelAreaSum(toggledPrev) - this._calcPanelAreaSum(toggledNext);
135
+ }
136
+
137
+ public clampToReachablePosition(position: number): number {
138
+ // Basically all position is reachable for circular camera
139
+ return position;
140
+ }
141
+
142
+ public canReach(panel: Panel): boolean {
143
+ if (panel.removed) return false;
144
+
145
+ // Always reachable on circular mode
146
+ return true;
147
+ }
148
+
149
+ public canSee(panel: Panel): boolean {
150
+ const camera = this._flicking.camera;
151
+ const range = camera.range;
152
+ const rangeDiff = camera.rangeDiff;
153
+ const visibleRange = camera.visibleRange;
154
+ const visibleInCurrentRange = super.canSee(panel);
155
+
156
+ // Check looped visible area for circular case
157
+ if (visibleRange.min < range.min) {
158
+ return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff);
159
+ } else if (visibleRange.max > range.max) {
160
+ return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff);
161
+ }
162
+
163
+ return visibleInCurrentRange;
164
+ }
165
+
166
+ private _calcPanelAreaSum(panels: Panel[]) {
167
+ return panels.reduce((sum: number, panel: Panel) => sum + panel.sizeIncludingMargin, 0);
168
+ }
169
+ }
170
+
171
+ export default CircularCameraMode;
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import CameraMode from "./CameraMode";
6
+
7
+ class LinearCameraMode extends CameraMode {
8
+ public checkAvailability(): boolean {
9
+ // It's always available
10
+ return true;
11
+ }
12
+
13
+ public getRange(): { min: number; max: number } {
14
+ const renderer = this._flicking.renderer;
15
+
16
+ const firstPanel = renderer.getPanel(0);
17
+ const lastPanel = renderer.getPanel(renderer.panelCount - 1);
18
+
19
+ return { min: firstPanel?.position ?? 0, max: lastPanel?.position ?? 0 };
20
+ }
21
+ }
22
+
23
+ export default LinearCameraMode;
@@ -0,0 +1,14 @@
1
+ import CameraMode from "./CameraMode";
2
+ import LinearCameraMode from "./LinearCameraMode";
3
+ import CircularCameraMode from "./CircularCameraMode";
4
+ import BoundCameraMode from "./BoundCameraMode";
5
+
6
+ export {
7
+ LinearCameraMode,
8
+ CircularCameraMode,
9
+ BoundCameraMode
10
+ };
11
+
12
+ export type {
13
+ CameraMode
14
+ };
package/src/cfc/sync.ts CHANGED
@@ -2,12 +2,16 @@ import { DiffResult } from "@egjs/list-differ";
2
2
 
3
3
  import Flicking from "../Flicking";
4
4
  import Renderer from "../renderer/Renderer";
5
+ import Panel from "../core/panel/Panel";
5
6
 
6
7
  export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]) => {
7
8
  const renderer = flicking.renderer;
8
9
  const panels = renderer.panels;
9
10
  const prevList = [...diffResult.prevList];
10
11
 
12
+ const added: Panel[] = [];
13
+ const removed: Panel[] = [];
14
+
11
15
  if (diffResult.removed.length > 0) {
12
16
  let endIdx = -1;
13
17
  let prevIdx = -1;
@@ -18,7 +22,7 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
18
22
  }
19
23
 
20
24
  if (prevIdx >= 0 && removedIdx !== prevIdx - 1) {
21
- batchRemove(renderer, prevIdx, endIdx + 1);
25
+ removed.push(...batchRemove(renderer, prevIdx, endIdx + 1));
22
26
 
23
27
  endIdx = removedIdx;
24
28
  prevIdx = removedIdx;
@@ -29,30 +33,30 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
29
33
  prevList.splice(removedIdx, 1);
30
34
  });
31
35
 
32
- batchRemove(renderer, prevIdx, endIdx + 1);
36
+ removed.push(...batchRemove(renderer, prevIdx, endIdx + 1));
33
37
  }
34
38
 
35
- diffResult.ordered.forEach(([prevIdx, newIdx]) => {
36
- const prevPanel = panels[prevIdx];
37
- const indexDiff = newIdx - prevIdx;
38
-
39
- if (indexDiff > 0) {
40
- const middlePanels = panels.slice(prevIdx + 1, newIdx + 1);
41
-
42
- prevPanel.increaseIndex(indexDiff);
43
- middlePanels.forEach(panel => panel.decreaseIndex(1));
44
- } else {
45
- const middlePanels = panels.slice(newIdx, prevIdx);
46
-
47
- prevPanel.decreaseIndex(-indexDiff);
48
- middlePanels.forEach(panel => panel.increaseIndex(1));
49
- }
50
- // Update position
51
- prevPanel.resize();
39
+ diffResult.ordered.forEach(([from, to]) => {
40
+ const prevPanel = panels.splice(from, 1)[0];
41
+ panels.splice(to, 0, prevPanel);
52
42
  });
53
43
 
54
44
  if (diffResult.ordered.length > 0) {
45
+ panels.forEach((panel, idx) => {
46
+ const indexDiff = idx - panel.index;
47
+
48
+ if (indexDiff > 0) {
49
+ panel.increaseIndex(indexDiff);
50
+ } else {
51
+ panel.decreaseIndex(-indexDiff);
52
+ }
53
+ });
54
+
55
55
  panels.sort((panel1, panel2) => panel1.index - panel2.index);
56
+
57
+ panels.forEach(panel => {
58
+ panel.updatePosition();
59
+ });
56
60
  }
57
61
 
58
62
  if (diffResult.added.length > 0) {
@@ -67,7 +71,7 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
67
71
  }
68
72
 
69
73
  if (prevIdx >= 0 && addedIdx !== prevIdx + 1) {
70
- batchInsert(renderer, diffResult, addedElements, startIdx, idx + 1);
74
+ added.push(...batchInsert(renderer, diffResult, addedElements, startIdx, idx + 1));
71
75
 
72
76
  startIdx = -1;
73
77
  prevIdx = -1;
@@ -77,13 +81,15 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
77
81
  });
78
82
 
79
83
  if (startIdx >= 0) {
80
- batchInsert(renderer, diffResult, addedElements, startIdx);
84
+ added.push(...batchInsert(renderer, diffResult, addedElements, startIdx));
81
85
  }
82
86
  }
87
+
88
+ renderer.updateAfterPanelChange(added, removed);
83
89
  };
84
90
 
85
91
  const batchInsert = (renderer: Renderer, diffResult: DiffResult<any>, addedElements: any[], startIdx: number, endIdx?: number) => {
86
- renderer.batchInsert(
92
+ return renderer.batchInsertDefer(
87
93
  ...diffResult.added.slice(startIdx, endIdx).map((index, elIdx) => ({ index, elements: [addedElements[elIdx]], hasDOMInElements: false }))
88
94
  );
89
95
  };
@@ -91,6 +97,6 @@ const batchInsert = (renderer: Renderer, diffResult: DiffResult<any>, addedEleme
91
97
  const batchRemove = (renderer: Renderer, startIdx: number, endIdx?: number) => {
92
98
  const removed = renderer.panels.slice(startIdx, endIdx);
93
99
 
94
- renderer.batchRemove({ index: startIdx, deleteCount: removed.length, hasDOMInElements: false });
100
+ return renderer.batchRemoveDefer({ index: startIdx, deleteCount: removed.length, hasDOMInElements: false });
95
101
  };
96
102
 
@@ -19,7 +19,7 @@ import Flicking from "../Flicking";
19
19
  */
20
20
  const withFlickingMethods = (prototype: any, flickingName: string) => {
21
21
  [Component.prototype, Flicking.prototype].forEach(proto => {
22
- Object.getOwnPropertyNames(proto).filter(name => !prototype[name] && !name.startsWith("_") && name !== "constructor")
22
+ Object.getOwnPropertyNames(proto).filter(name => !prototype[name] && name.indexOf("_") !== 0 && name !== "constructor")
23
23
  .forEach((name: string) => {
24
24
  const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;
25
25
 
@@ -34,7 +34,8 @@ const withFlickingMethods = (prototype: any, flickingName: string) => {
34
34
  const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};
35
35
  if (descriptor.get) {
36
36
  getterDescriptor.get = function() {
37
- return descriptor.get?.call(this[flickingName]);
37
+ const flicking = this[flickingName];
38
+ return flicking && descriptor.get?.call(flicking);
38
39
  };
39
40
  }
40
41
  if (descriptor.set) {
@@ -98,3 +98,15 @@ export const CLASS = {
98
98
  HIDDEN: "flicking-hidden",
99
99
  DEFAULT_VIRTUAL: "flicking-panel"
100
100
  };
101
+
102
+ /**
103
+ * An object with all possible {@link Flicking#circularFallback circularFallback}s
104
+ * @ko Flicking의 {@link Flicking#circularFallback circularFallback}에 설정 가능한 값들을 담고 있는 객체
105
+ * @type {object}
106
+ * @property {string} LINEAR "linear"
107
+ * @property {string} BOUND "bound"
108
+ */
109
+ export const CIRCULAR_FALLBACK = {
110
+ LINEAR: "linear",
111
+ BOUND: "bound"
112
+ } as const;
@@ -141,6 +141,16 @@ class StrictControl extends Control {
141
141
  return this;
142
142
  }
143
143
 
144
+ public async moveToPanel(panel: Panel, options: Parameters<Control["moveToPanel"]>[1]): Promise<void> {
145
+ const flicking = getFlickingAttached(this._flicking);
146
+ const camera = flicking.camera;
147
+ const controller = this._controller;
148
+
149
+ controller.update(camera.controlParams);
150
+
151
+ return super.moveToPanel(panel, options);
152
+ }
153
+
144
154
  /**
145
155
  * Move {@link Camera} to the given position
146
156
  * @ko {@link Camera}를 주어진 좌표로 이동합니다
@@ -8,6 +8,8 @@ class AutoResizer {
8
8
  private _flicking: Flicking;
9
9
  private _enabled: boolean;
10
10
  private _resizeObserver: ResizeObserver | null;
11
+ private _resizeTimer: number;
12
+ private _maxResizeDebounceTimer: number;
11
13
 
12
14
  public get enabled() { return this._enabled; }
13
15
 
@@ -15,6 +17,8 @@ class AutoResizer {
15
17
  this._flicking = flicking;
16
18
  this._enabled = false;
17
19
  this._resizeObserver = null;
20
+ this._resizeTimer = -1;
21
+ this._maxResizeDebounceTimer = -1;
18
22
  }
19
23
 
20
24
  public enable(): this {
@@ -61,6 +65,35 @@ class AutoResizer {
61
65
  }
62
66
 
63
67
  private _onResize = () => {
68
+ const flicking = this._flicking;
69
+ const resizeDebounce = flicking.resizeDebounce;
70
+ const maxResizeDebounce = flicking.maxResizeDebounce;
71
+
72
+ if (resizeDebounce <= 0) {
73
+ void flicking.resize();
74
+ } else {
75
+ if (this._maxResizeDebounceTimer <= 0) {
76
+ if (maxResizeDebounce > 0 && maxResizeDebounce >= resizeDebounce) {
77
+ this._maxResizeDebounceTimer = window.setTimeout(this._doScheduledResize, maxResizeDebounce);
78
+ }
79
+ }
80
+
81
+ if (this._resizeTimer > 0) {
82
+ clearTimeout(this._resizeTimer);
83
+ this._resizeTimer = 0;
84
+ }
85
+
86
+ this._resizeTimer = window.setTimeout(this._doScheduledResize, resizeDebounce);
87
+ }
88
+ };
89
+
90
+ private _doScheduledResize = () => {
91
+ clearTimeout(this._resizeTimer);
92
+ clearTimeout(this._maxResizeDebounceTimer);
93
+
94
+ this._maxResizeDebounceTimer = -1;
95
+ this._resizeTimer = -1;
96
+
64
97
  void this._flicking.resize();
65
98
  };
66
99
 
@@ -0,0 +1,133 @@
1
+ /*
2
+ * Copyright (c) 2015 NAVER Corp.
3
+ * egjs projects are licensed under the MIT license
4
+ */
5
+ import Component from "@egjs/component";
6
+
7
+ import { isString } from "../utils";
8
+
9
+ export interface ResizeWatherOptions {
10
+ resizeDebounce?: number;
11
+ maxResizeDebounce?: number;
12
+ useResizeObserver?: boolean;
13
+ useWindowResize?: boolean;
14
+ watchDirection?: "width" | "height" | "box" | false;
15
+ rectBox?: "border-box" | "content-box";
16
+ }
17
+
18
+ class ResizeWatcher {
19
+ private _container: HTMLElement;
20
+ private _rect = { width: 0, height: 0 };
21
+ private _resizeTimer = 0;
22
+ private _maxResizeDebounceTimer = 0;
23
+ private _emitter: Component<{ resize: void }>;
24
+ private _observer: ResizeObserver | null;
25
+ private _options!: Required<ResizeWatherOptions>;
26
+
27
+ public constructor(container: HTMLElement | string, options: ResizeWatherOptions = {}) {
28
+ this._options = {
29
+ resizeDebounce: 100,
30
+ maxResizeDebounce: 0,
31
+ useResizeObserver: false,
32
+ useWindowResize: true,
33
+ watchDirection: false,
34
+ rectBox: "content-box",
35
+ ...options
36
+ };
37
+
38
+ this._container = isString(container) ? document.querySelector<HTMLElement>(container)! : container;
39
+ this._init();
40
+ }
41
+
42
+ public getRect() {
43
+ return this._rect;
44
+ }
45
+
46
+ public setRect(rect: { width: number; height: number }) {
47
+ this._rect = { ...rect };
48
+ }
49
+
50
+ public resize() {
51
+ const container = this._container;
52
+
53
+ this.setRect(this._options.rectBox === "border-box" ? {
54
+ width: container.offsetWidth,
55
+ height: container.offsetHeight
56
+ } : {
57
+ width: container.clientWidth,
58
+ height: container.clientHeight
59
+ });
60
+ }
61
+
62
+ public listen(callback: () => void) {
63
+ this._emitter.on("resize", callback);
64
+ return this;
65
+ }
66
+
67
+ public destroy() {
68
+ this._observer?.disconnect();
69
+ if (this._options.useWindowResize) {
70
+ window.removeEventListener("reisze", this._onResize);
71
+ }
72
+ }
73
+
74
+ private _init() {
75
+ const container = this._container;
76
+ const options = this._options;
77
+
78
+ this._emitter = new Component();
79
+ if (options.useResizeObserver && !!window.ResizeObserver) {
80
+ this._observer = new window.ResizeObserver(this._scheduleResize);
81
+ this._observer.observe(container, {
82
+ box: options.rectBox
83
+ });
84
+ }
85
+ if (options.useWindowResize) {
86
+ window.addEventListener("resize", this._scheduleResize);
87
+ }
88
+ this.resize();
89
+ }
90
+
91
+ private _onResize = () => {
92
+ clearTimeout(this._resizeTimer);
93
+ clearTimeout(this._maxResizeDebounceTimer);
94
+
95
+ this._maxResizeDebounceTimer = 0;
96
+ this._resizeTimer = 0;
97
+
98
+ const watchDirection = this._options.watchDirection;
99
+ const prevRect = this._rect;
100
+ this.resize();
101
+ const rect = this._rect;
102
+ const isWatchWidth = watchDirection === "box" || watchDirection === "width";
103
+ const isWatchHeight = watchDirection === "box" || watchDirection === "height";
104
+ const isResize = !watchDirection
105
+ || (isWatchWidth && prevRect.width !== rect.width)
106
+ || (isWatchHeight && prevRect.height !== rect.height);
107
+
108
+ if (isResize) {
109
+ this._emitter.trigger("resize");
110
+ }
111
+ };
112
+
113
+ private _scheduleResize = () => {
114
+ const {
115
+ resizeDebounce,
116
+ maxResizeDebounce
117
+ } = this._options;
118
+
119
+
120
+ if (!this._maxResizeDebounceTimer && maxResizeDebounce >= resizeDebounce) {
121
+ this._maxResizeDebounceTimer = window.setTimeout(this._onResize, maxResizeDebounce);
122
+ }
123
+
124
+ if (this._resizeTimer) {
125
+ clearTimeout(this._resizeTimer);
126
+ this._resizeTimer = 0;
127
+ }
128
+
129
+ this._resizeTimer = window.setTimeout(this._onResize, resizeDebounce);
130
+ };
131
+ }
132
+
133
+ export default ResizeWatcher;