@egjs/flicking 4.3.1 → 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.
- package/README.md +1 -2
- package/declaration/Flicking.d.ts +30 -12
- package/declaration/camera/Camera.d.ts +29 -26
- package/declaration/camera/index.d.ts +2 -4
- package/declaration/camera/mode/BoundCameraMode.d.ts +13 -0
- package/declaration/camera/mode/CameraMode.d.ts +19 -0
- package/declaration/camera/mode/CircularCameraMode.d.ts +18 -0
- package/declaration/camera/mode/LinearCameraMode.d.ts +9 -0
- package/declaration/camera/mode/index.d.ts +6 -0
- package/declaration/const/error.d.ts +3 -1
- package/declaration/const/external.d.ts +9 -0
- package/declaration/core/AutoResizer.d.ts +13 -0
- package/declaration/core/VirtualManager.d.ts +37 -0
- package/declaration/core/index.d.ts +2 -1
- package/declaration/core/panel/Panel.d.ts +13 -7
- package/declaration/core/panel/VirtualPanel.d.ts +19 -0
- package/declaration/core/panel/index.d.ts +4 -4
- package/declaration/core/panel/provider/ElementProvider.d.ts +8 -0
- package/declaration/core/panel/provider/VanillaElementProvider.d.ts +12 -0
- package/declaration/core/panel/provider/VirtualElementProvider.d.ts +15 -0
- package/declaration/core/panel/provider/index.d.ts +5 -0
- package/declaration/index.d.ts +11 -1
- package/declaration/renderer/ExternalRenderer.d.ts +1 -1
- package/declaration/renderer/Renderer.d.ts +17 -12
- package/declaration/renderer/VanillaRenderer.d.ts +2 -7
- package/declaration/renderer/index.d.ts +1 -0
- package/declaration/renderer/strategy/NormalRenderingStrategy.d.ts +23 -0
- package/declaration/renderer/strategy/RenderingStrategy.d.ts +15 -0
- package/declaration/renderer/strategy/VirtualRenderingStrategy.d.ts +17 -0
- package/declaration/renderer/strategy/index.d.ts +5 -0
- package/declaration/type/external.d.ts +1 -3
- package/declaration/utils.d.ts +7 -1
- package/dist/flicking.esm.js +2526 -1475
- package/dist/flicking.esm.js.map +1 -1
- package/dist/flicking.js +2561 -1485
- package/dist/flicking.js.map +1 -1
- package/dist/flicking.min.js +2 -2
- package/dist/flicking.min.js.map +1 -1
- package/dist/flicking.pkgd.js +9006 -8312
- package/dist/flicking.pkgd.js.map +1 -1
- package/dist/flicking.pkgd.min.js +2 -2
- package/dist/flicking.pkgd.min.js.map +1 -1
- package/package.json +12 -24
- package/src/Flicking.ts +172 -45
- package/src/camera/Camera.ts +201 -93
- package/src/camera/index.ts +3 -7
- package/src/camera/{BoundCamera.ts → mode/BoundCameraMode.ts} +46 -43
- package/src/camera/mode/CameraMode.ts +77 -0
- package/src/camera/mode/CircularCameraMode.ts +171 -0
- package/src/camera/mode/LinearCameraMode.ts +23 -0
- package/src/camera/mode/index.ts +14 -0
- package/src/cfc/sync.ts +10 -5
- package/src/const/error.ts +6 -3
- package/src/const/external.ts +18 -0
- package/src/control/AxesController.ts +11 -6
- package/src/control/Control.ts +6 -6
- package/src/control/FreeControl.ts +2 -2
- package/src/control/SnapControl.ts +3 -3
- package/src/control/StrictControl.ts +2 -2
- package/src/core/AutoResizer.ts +81 -0
- package/src/core/Viewport.ts +4 -4
- package/src/core/VirtualManager.ts +188 -0
- package/src/core/index.ts +3 -1
- package/src/core/panel/Panel.ts +54 -34
- package/src/core/panel/VirtualPanel.ts +110 -0
- package/src/core/panel/index.ts +5 -7
- package/src/core/panel/provider/ElementProvider.ts +14 -0
- package/src/core/panel/provider/VanillaElementProvider.ts +45 -0
- package/src/core/panel/provider/VirtualElementProvider.ts +48 -0
- package/src/core/panel/provider/index.ts +16 -0
- package/src/index.ts +12 -1
- package/src/index.umd.ts +2 -0
- package/src/renderer/ExternalRenderer.ts +7 -7
- package/src/renderer/Renderer.ts +106 -65
- package/src/renderer/VanillaRenderer.ts +28 -86
- package/src/renderer/index.ts +2 -0
- package/src/renderer/strategy/NormalRenderingStrategy.ts +106 -0
- package/src/renderer/strategy/RenderingStrategy.ts +21 -0
- package/src/renderer/strategy/VirtualRenderingStrategy.ts +110 -0
- package/src/renderer/strategy/index.ts +17 -0
- package/src/utils.ts +36 -2
- package/declaration/camera/BoundCamera.d.ts +0 -9
- package/declaration/camera/CircularCamera.d.ts +0 -36
- package/declaration/camera/LinearCamera.d.ts +0 -5
- package/declaration/core/panel/ElementPanel.d.ts +0 -14
- package/declaration/core/panel/ExternalPanel.d.ts +0 -9
- package/declaration/exports.d.ts +0 -10
- package/src/camera/CircularCamera.ts +0 -269
- package/src/camera/LinearCamera.ts +0 -35
- package/src/core/panel/ElementPanel.ts +0 -52
- package/src/core/panel/ExternalPanel.ts +0 -32
- package/src/exports.ts +0 -16
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2015 NAVER Corp.
|
|
3
|
+
* egjs projects are licensed under the MIT license
|
|
4
|
+
*/
|
|
5
|
+
import Flicking from "../../Flicking";
|
|
6
|
+
import Panel from "../../core/panel/Panel";
|
|
7
|
+
import AnchorPoint from "../../core/AnchorPoint";
|
|
8
|
+
import { clamp } from "../../utils";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A mode of camera
|
|
12
|
+
*/
|
|
13
|
+
abstract class CameraMode {
|
|
14
|
+
protected _flicking: Flicking;
|
|
15
|
+
|
|
16
|
+
/** */
|
|
17
|
+
public constructor(flicking: Flicking) {
|
|
18
|
+
this._flicking = flicking;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public abstract checkAvailability(): boolean;
|
|
22
|
+
public abstract getRange(): { min: number; max: number };
|
|
23
|
+
|
|
24
|
+
public getAnchors(): AnchorPoint[] {
|
|
25
|
+
const panels = this._flicking.renderer.panels;
|
|
26
|
+
|
|
27
|
+
return panels.map((panel, index) => new AnchorPoint({
|
|
28
|
+
index,
|
|
29
|
+
position: panel.position,
|
|
30
|
+
panel
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public findAnchorIncludePosition(position: number): AnchorPoint | null {
|
|
35
|
+
const anchors = this._flicking.camera.anchorPoints;
|
|
36
|
+
const anchorsIncludingPosition = anchors.filter(anchor => anchor.panel.includePosition(position, true));
|
|
37
|
+
|
|
38
|
+
return anchorsIncludingPosition.reduce((nearest: AnchorPoint | null, anchor) => {
|
|
39
|
+
if (!nearest) return anchor;
|
|
40
|
+
|
|
41
|
+
return Math.abs(nearest.position - position) < Math.abs(anchor.position - position)
|
|
42
|
+
? nearest
|
|
43
|
+
: anchor;
|
|
44
|
+
}, null);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public clampToReachablePosition(position: number): number {
|
|
48
|
+
const camera = this._flicking.camera;
|
|
49
|
+
const range = camera.range;
|
|
50
|
+
|
|
51
|
+
return clamp(position, range.min, range.max);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public getCircularOffset(): number {
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public canReach(panel: Panel): boolean {
|
|
59
|
+
const camera = this._flicking.camera;
|
|
60
|
+
const range = camera.range;
|
|
61
|
+
|
|
62
|
+
if (panel.removed) return false;
|
|
63
|
+
|
|
64
|
+
const panelPos = panel.position;
|
|
65
|
+
|
|
66
|
+
return panelPos >= range.min && panelPos <= range.max;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public canSee(panel: Panel): boolean {
|
|
70
|
+
const camera = this._flicking.camera;
|
|
71
|
+
const visibleRange = camera.visibleRange;
|
|
72
|
+
// Should not include margin, as we don't declare what the margin is visible as what the panel is visible.
|
|
73
|
+
return panel.isVisibleOnRange(visibleRange.min, visibleRange.max);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default CameraMode;
|
|
@@ -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
|
@@ -6,6 +6,7 @@ import Renderer from "../renderer/Renderer";
|
|
|
6
6
|
export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]) => {
|
|
7
7
|
const renderer = flicking.renderer;
|
|
8
8
|
const panels = renderer.panels;
|
|
9
|
+
const prevList = [...diffResult.prevList];
|
|
9
10
|
|
|
10
11
|
if (diffResult.removed.length > 0) {
|
|
11
12
|
let endIdx = -1;
|
|
@@ -24,6 +25,8 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
|
|
|
24
25
|
} else {
|
|
25
26
|
prevIdx = removedIdx;
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
prevList.splice(removedIdx, 1);
|
|
27
30
|
});
|
|
28
31
|
|
|
29
32
|
batchRemove(renderer, prevIdx, endIdx + 1);
|
|
@@ -56,13 +59,15 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
|
|
|
56
59
|
let startIdx = -1;
|
|
57
60
|
let prevIdx = -1;
|
|
58
61
|
|
|
62
|
+
const addedElements = rendered.slice(prevList.length);
|
|
63
|
+
|
|
59
64
|
diffResult.added.forEach((addedIdx, idx) => {
|
|
60
65
|
if (startIdx < 0) {
|
|
61
66
|
startIdx = idx;
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
if (prevIdx >= 0 && addedIdx !== prevIdx + 1) {
|
|
65
|
-
batchInsert(renderer, diffResult,
|
|
70
|
+
batchInsert(renderer, diffResult, addedElements, startIdx, idx + 1);
|
|
66
71
|
|
|
67
72
|
startIdx = -1;
|
|
68
73
|
prevIdx = -1;
|
|
@@ -72,20 +77,20 @@ export default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]
|
|
|
72
77
|
});
|
|
73
78
|
|
|
74
79
|
if (startIdx >= 0) {
|
|
75
|
-
batchInsert(renderer, diffResult,
|
|
80
|
+
batchInsert(renderer, diffResult, addedElements, startIdx);
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
};
|
|
79
84
|
|
|
80
|
-
const batchInsert = (renderer: Renderer, diffResult: DiffResult<any>,
|
|
85
|
+
const batchInsert = (renderer: Renderer, diffResult: DiffResult<any>, addedElements: any[], startIdx: number, endIdx?: number) => {
|
|
81
86
|
renderer.batchInsert(
|
|
82
|
-
...diffResult.added.slice(startIdx, endIdx).map((index, elIdx) => ({ index, elements: [
|
|
87
|
+
...diffResult.added.slice(startIdx, endIdx).map((index, elIdx) => ({ index, elements: [addedElements[elIdx]], hasDOMInElements: false }))
|
|
83
88
|
);
|
|
84
89
|
};
|
|
85
90
|
|
|
86
91
|
const batchRemove = (renderer: Renderer, startIdx: number, endIdx?: number) => {
|
|
87
92
|
const removed = renderer.panels.slice(startIdx, endIdx);
|
|
88
93
|
|
|
89
|
-
renderer.batchRemove({ index: startIdx, deleteCount: removed.length });
|
|
94
|
+
renderer.batchRemove({ index: startIdx, deleteCount: removed.length, hasDOMInElements: false });
|
|
90
95
|
};
|
|
91
96
|
|
package/src/const/error.ts
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* <ko>프레임워크(React, Angular, Vue ...)에서 사용 불가능한 메소드를 호출했을 경우</ko>
|
|
26
26
|
* @property {number} NOT_INITIALIZED When the {@link Flicking#init} is not called before but is needed<ko>{@link Flicking#init}의 호출이 필요하나, 아직 호출되지 않았을 경우</ko>
|
|
27
27
|
* @property {number} NO_ACTIVE When there're no active panel that flicking has selected. This may be due to the absence of any panels<ko>현재 Flicking이 선택한 패널이 없을 경우. 일반적으로 패널이 하나도 없는 경우에 발생할 수 있습니다</ko>
|
|
28
|
+
* @property {number} NOT_ALLOWED_IN_VIRTUAL When the non-allowed method is called while the virtual option is enabled<ko>virtual 옵션이 활성화된 상태에서 사용 불가능한 메소드가 호출되었을 경우</ko>
|
|
28
29
|
*/
|
|
29
30
|
export const CODE = {
|
|
30
31
|
WRONG_TYPE: 0,
|
|
@@ -40,14 +41,15 @@ export const CODE = {
|
|
|
40
41
|
ANIMATION_ALREADY_PLAYING: 10,
|
|
41
42
|
NOT_ALLOWED_IN_FRAMEWORK: 11,
|
|
42
43
|
NOT_INITIALIZED: 12,
|
|
43
|
-
NO_ACTIVE: 13
|
|
44
|
+
NO_ACTIVE: 13,
|
|
45
|
+
NOT_ALLOWED_IN_VIRTUAL: 14
|
|
44
46
|
} as const;
|
|
45
47
|
|
|
46
48
|
export const MESSAGE = {
|
|
47
49
|
WRONG_TYPE: (wrongVal: any, correctTypes: string[]) => `${wrongVal}(${typeof wrongVal}) is not a ${correctTypes.map(type => `"${type}"`).join(" or ")}.`,
|
|
48
50
|
ELEMENT_NOT_FOUND: (selector: string) => `Element with selector "${selector}" not found.`,
|
|
49
51
|
VAL_MUST_NOT_NULL: (val: any, name: string) => `${name} should be provided. Given: ${val}`,
|
|
50
|
-
NOT_ATTACHED_TO_FLICKING:
|
|
52
|
+
NOT_ATTACHED_TO_FLICKING: "This module is not attached to the Flicking instance. \"init()\" should be called first.",
|
|
51
53
|
WRONG_OPTION: (optionName: string, val: any) => `Option "${optionName}" is not in correct format, given: ${val}`,
|
|
52
54
|
INDEX_OUT_OF_RANGE: (val: number, min: number, max: number) => `Index "${val}" is out of range: should be between ${min} and ${max}.`,
|
|
53
55
|
POSITION_NOT_REACHABLE: (position: number) => `Position "${position}" is not reachable.`,
|
|
@@ -57,5 +59,6 @@ export const MESSAGE = {
|
|
|
57
59
|
ANIMATION_ALREADY_PLAYING: "Animation is already playing.",
|
|
58
60
|
NOT_ALLOWED_IN_FRAMEWORK: "This behavior is not allowed in the frameworks like React, Vue, or Angular.",
|
|
59
61
|
NOT_INITIALIZED: "Flicking is not initialized yet, call init() first.",
|
|
60
|
-
NO_ACTIVE: "There's no active panel that Flicking has selected. This may be due to the absence of any panels."
|
|
62
|
+
NO_ACTIVE: "There's no active panel that Flicking has selected. This may be due to the absence of any panels.",
|
|
63
|
+
NOT_ALLOWED_IN_VIRTUAL: "This behavior is not allowed when the virtual option is enabled"
|
|
61
64
|
} as const;
|
package/src/const/external.ts
CHANGED
|
@@ -92,3 +92,21 @@ export const MOVE_TYPE = {
|
|
|
92
92
|
FREE_SCROLL: "freeScroll",
|
|
93
93
|
STRICT: "strict"
|
|
94
94
|
} as const;
|
|
95
|
+
|
|
96
|
+
export const CLASS = {
|
|
97
|
+
VERTICAL: "vertical",
|
|
98
|
+
HIDDEN: "flicking-hidden",
|
|
99
|
+
DEFAULT_VIRTUAL: "flicking-panel"
|
|
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;
|
|
@@ -211,7 +211,7 @@ class AxesController {
|
|
|
211
211
|
* @return {this}
|
|
212
212
|
*/
|
|
213
213
|
public update(controlParams: ControlParams): this {
|
|
214
|
-
const flicking = getFlickingAttached(this._flicking
|
|
214
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
215
215
|
const camera = flicking.camera;
|
|
216
216
|
const axes = this._axes!;
|
|
217
217
|
const axis = axes.axis[AXES.POSITION_KEY];
|
|
@@ -231,7 +231,7 @@ class AxesController {
|
|
|
231
231
|
* @return {this}
|
|
232
232
|
*/
|
|
233
233
|
public addPreventClickHandler(): this {
|
|
234
|
-
const flicking = getFlickingAttached(this._flicking
|
|
234
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
235
235
|
const axes = this._axes!;
|
|
236
236
|
const cameraEl = flicking.camera.element;
|
|
237
237
|
|
|
@@ -248,7 +248,7 @@ class AxesController {
|
|
|
248
248
|
* @return {this}
|
|
249
249
|
*/
|
|
250
250
|
public removePreventClickHandler(): this {
|
|
251
|
-
const flicking = getFlickingAttached(this._flicking
|
|
251
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
252
252
|
const axes = this._axes!;
|
|
253
253
|
const cameraEl = flicking.camera.element;
|
|
254
254
|
|
|
@@ -282,17 +282,22 @@ class AxesController {
|
|
|
282
282
|
*/
|
|
283
283
|
public animateTo(position: number, duration: number, axesEvent?: OnRelease): Promise<void> {
|
|
284
284
|
const axes = this._axes;
|
|
285
|
+
const state = this._stateMachine.state;
|
|
285
286
|
|
|
286
287
|
if (!axes) {
|
|
287
|
-
return Promise.reject(new FlickingError(ERROR.MESSAGE.NOT_ATTACHED_TO_FLICKING
|
|
288
|
+
return Promise.reject(new FlickingError(ERROR.MESSAGE.NOT_ATTACHED_TO_FLICKING, ERROR.CODE.NOT_ATTACHED_TO_FLICKING));
|
|
288
289
|
}
|
|
289
290
|
|
|
290
291
|
const startPos = axes.get([AXES.POSITION_KEY])[AXES.POSITION_KEY];
|
|
291
292
|
|
|
292
293
|
if (startPos === position) {
|
|
293
|
-
const flicking = getFlickingAttached(this._flicking
|
|
294
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
294
295
|
|
|
295
296
|
flicking.camera.lookAt(position);
|
|
297
|
+
|
|
298
|
+
if (state.targetPanel) {
|
|
299
|
+
flicking.control.setActive(state.targetPanel, flicking.control.activePanel, axesEvent?.isTrusted ?? false);
|
|
300
|
+
}
|
|
296
301
|
return Promise.resolve();
|
|
297
302
|
}
|
|
298
303
|
|
|
@@ -317,7 +322,7 @@ class AxesController {
|
|
|
317
322
|
};
|
|
318
323
|
|
|
319
324
|
if (duration === 0) {
|
|
320
|
-
const flicking = getFlickingAttached(this._flicking
|
|
325
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
321
326
|
const camera = flicking.camera;
|
|
322
327
|
|
|
323
328
|
animate();
|
package/src/control/Control.ts
CHANGED
|
@@ -172,7 +172,7 @@ abstract class Control {
|
|
|
172
172
|
* @return {Promise<void>}
|
|
173
173
|
*/
|
|
174
174
|
public updatePosition(_progressInPanel: number): void { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
175
|
-
const flicking = getFlickingAttached(this._flicking
|
|
175
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
176
176
|
const camera = flicking.camera;
|
|
177
177
|
const activePanel = this._activePanel;
|
|
178
178
|
|
|
@@ -188,7 +188,7 @@ abstract class Control {
|
|
|
188
188
|
* @return {this}
|
|
189
189
|
*/
|
|
190
190
|
public updateInput(): this {
|
|
191
|
-
const flicking = getFlickingAttached(this._flicking
|
|
191
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
192
192
|
const camera = flicking.camera;
|
|
193
193
|
|
|
194
194
|
this._controller.update(camera.controlParams);
|
|
@@ -255,7 +255,7 @@ abstract class Control {
|
|
|
255
255
|
direction?: ValueOf<typeof DIRECTION>;
|
|
256
256
|
axesEvent?: OnRelease;
|
|
257
257
|
}) {
|
|
258
|
-
const flicking = getFlickingAttached(this._flicking
|
|
258
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
259
259
|
const camera = flicking.camera;
|
|
260
260
|
|
|
261
261
|
let position = panel.position;
|
|
@@ -299,7 +299,7 @@ abstract class Control {
|
|
|
299
299
|
* @internal
|
|
300
300
|
*/
|
|
301
301
|
public setActive(newActivePanel: Panel, prevActivePanel: Panel | null, isTrusted: boolean) {
|
|
302
|
-
const flicking = getFlickingAttached(this._flicking
|
|
302
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
303
303
|
|
|
304
304
|
this._activePanel = newActivePanel;
|
|
305
305
|
|
|
@@ -322,7 +322,7 @@ abstract class Control {
|
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
protected _triggerIndexChangeEvent(panel: Panel, position: number, axesEvent?: OnRelease): void {
|
|
325
|
-
const flicking = getFlickingAttached(this._flicking
|
|
325
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
326
326
|
const triggeringEvent = panel !== this._activePanel ? EVENTS.WILL_CHANGE : EVENTS.WILL_RESTORE;
|
|
327
327
|
const camera = flicking.camera;
|
|
328
328
|
const activePanel = this._activePanel;
|
|
@@ -351,7 +351,7 @@ abstract class Control {
|
|
|
351
351
|
newActivePanel: Panel;
|
|
352
352
|
axesEvent?: OnRelease;
|
|
353
353
|
}) {
|
|
354
|
-
const flicking = getFlickingAttached(this._flicking
|
|
354
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
355
355
|
const animate = () => this._controller.animateTo(position, duration, axesEvent);
|
|
356
356
|
const state = this._controller.state;
|
|
357
357
|
|
|
@@ -58,7 +58,7 @@ class FreeControl extends Control {
|
|
|
58
58
|
* @return {Promise<void>}
|
|
59
59
|
*/
|
|
60
60
|
public updatePosition(progressInPanel: number): void {
|
|
61
|
-
const flicking = getFlickingAttached(this._flicking
|
|
61
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
62
62
|
const camera = flicking.camera;
|
|
63
63
|
const activePanel = this._activePanel;
|
|
64
64
|
|
|
@@ -107,7 +107,7 @@ class FreeControl extends Control {
|
|
|
107
107
|
* @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
|
|
108
108
|
*/
|
|
109
109
|
public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
|
|
110
|
-
const flicking = getFlickingAttached(this._flicking
|
|
110
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
111
111
|
|
|
112
112
|
const camera = flicking.camera;
|
|
113
113
|
const targetPos = camera.clampToReachablePosition(position);
|
|
@@ -85,7 +85,7 @@ class SnapControl extends Control {
|
|
|
85
85
|
* @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
|
|
86
86
|
*/
|
|
87
87
|
public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
|
|
88
|
-
const flicking = getFlickingAttached(this._flicking
|
|
88
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
89
89
|
const camera = flicking.camera;
|
|
90
90
|
const activeAnchor = camera.findActiveAnchor();
|
|
91
91
|
const anchorAtCamera = camera.findNearestAnchor(camera.position);
|
|
@@ -128,7 +128,7 @@ class SnapControl extends Control {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
private _findSnappedAnchor(position: number, anchorAtCamera: AnchorPoint): AnchorPoint {
|
|
131
|
-
const flicking = getFlickingAttached(this._flicking
|
|
131
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
132
132
|
const camera = flicking.camera;
|
|
133
133
|
const count = this._count;
|
|
134
134
|
|
|
@@ -191,7 +191,7 @@ class SnapControl extends Control {
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
private _findAdjacentAnchor(posDelta: number, anchorAtCamera: AnchorPoint): AnchorPoint {
|
|
194
|
-
const flicking = getFlickingAttached(this._flicking
|
|
194
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
195
195
|
const camera = flicking.camera;
|
|
196
196
|
const adjacentAnchor = (posDelta > 0 ? camera.getNextAnchor(anchorAtCamera) : camera.getPrevAnchor(anchorAtCamera)) ?? anchorAtCamera;
|
|
197
197
|
|
|
@@ -66,7 +66,7 @@ class StrictControl extends Control {
|
|
|
66
66
|
* @return {this}
|
|
67
67
|
*/
|
|
68
68
|
public updateInput(): this {
|
|
69
|
-
const flicking = getFlickingAttached(this._flicking
|
|
69
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
70
70
|
const camera = flicking.camera;
|
|
71
71
|
const renderer = flicking.renderer;
|
|
72
72
|
const controller = this._controller;
|
|
@@ -178,7 +178,7 @@ class StrictControl extends Control {
|
|
|
178
178
|
* @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
|
|
179
179
|
*/
|
|
180
180
|
public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {
|
|
181
|
-
const flicking = getFlickingAttached(this._flicking
|
|
181
|
+
const flicking = getFlickingAttached(this._flicking);
|
|
182
182
|
const camera = flicking.camera;
|
|
183
183
|
const activePanel = this._activePanel;
|
|
184
184
|
const axesRange = this._controller.range;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2015 NAVER Corp.
|
|
3
|
+
* egjs projects are licensed under the MIT license
|
|
4
|
+
*/
|
|
5
|
+
import Flicking from "../Flicking";
|
|
6
|
+
|
|
7
|
+
class AutoResizer {
|
|
8
|
+
private _flicking: Flicking;
|
|
9
|
+
private _enabled: boolean;
|
|
10
|
+
private _resizeObserver: ResizeObserver | null;
|
|
11
|
+
|
|
12
|
+
public get enabled() { return this._enabled; }
|
|
13
|
+
|
|
14
|
+
public constructor(flicking: Flicking) {
|
|
15
|
+
this._flicking = flicking;
|
|
16
|
+
this._enabled = false;
|
|
17
|
+
this._resizeObserver = null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public enable(): this {
|
|
21
|
+
const flicking = this._flicking;
|
|
22
|
+
const viewport = flicking.viewport;
|
|
23
|
+
|
|
24
|
+
if (this._enabled) {
|
|
25
|
+
this.disable();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (flicking.useResizeObserver && !!window.ResizeObserver) {
|
|
29
|
+
const viewportSizeNot0 = viewport.width !== 0 || viewport.height !== 0;
|
|
30
|
+
|
|
31
|
+
const resizeObserver = viewportSizeNot0
|
|
32
|
+
? new ResizeObserver(this._skipFirstResize)
|
|
33
|
+
: new ResizeObserver(this._onResize);
|
|
34
|
+
|
|
35
|
+
resizeObserver.observe(flicking.viewport.element);
|
|
36
|
+
|
|
37
|
+
this._resizeObserver = resizeObserver;
|
|
38
|
+
} else {
|
|
39
|
+
window.addEventListener("resize", this._onResize);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this._enabled = true;
|
|
43
|
+
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public disable(): this {
|
|
48
|
+
if (!this._enabled) return this;
|
|
49
|
+
|
|
50
|
+
const resizeObserver = this._resizeObserver;
|
|
51
|
+
if (resizeObserver) {
|
|
52
|
+
resizeObserver.disconnect();
|
|
53
|
+
this._resizeObserver = null;
|
|
54
|
+
} else {
|
|
55
|
+
window.removeEventListener("resize", this._onResize);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this._enabled = false;
|
|
59
|
+
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private _onResize = () => {
|
|
64
|
+
void this._flicking.resize();
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
68
|
+
private _skipFirstResize = (() => {
|
|
69
|
+
let isFirstResize = true;
|
|
70
|
+
|
|
71
|
+
return (() => {
|
|
72
|
+
if (isFirstResize) {
|
|
73
|
+
isFirstResize = false;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this._onResize();
|
|
77
|
+
});
|
|
78
|
+
})();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default AutoResizer;
|
package/src/core/Viewport.ts
CHANGED
|
@@ -124,10 +124,10 @@ class Viewport {
|
|
|
124
124
|
this._width = el.clientWidth;
|
|
125
125
|
this._height = el.clientHeight;
|
|
126
126
|
this._padding = {
|
|
127
|
-
left: parseFloat(elStyle.paddingLeft),
|
|
128
|
-
right: parseFloat(elStyle.paddingRight),
|
|
129
|
-
top: parseFloat(elStyle.paddingTop),
|
|
130
|
-
bottom: parseFloat(elStyle.paddingBottom)
|
|
127
|
+
left: elStyle.paddingLeft ? parseFloat(elStyle.paddingLeft) : 0,
|
|
128
|
+
right: elStyle.paddingRight ? parseFloat(elStyle.paddingRight) : 0,
|
|
129
|
+
top: elStyle.paddingTop ? parseFloat(elStyle.paddingTop) : 0,
|
|
130
|
+
bottom: elStyle.paddingBottom ? parseFloat(elStyle.paddingBottom) : 0
|
|
131
131
|
};
|
|
132
132
|
this._isBorderBoxSizing = elStyle.boxSizing === "border-box";
|
|
133
133
|
}
|