@egjs/flicking 4.12.0-beta.0 → 4.12.0-beta.10
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/declaration/CrossFlicking.d.ts +77 -0
- package/declaration/camera/Camera.d.ts +1 -0
- package/declaration/const/external.d.ts +6 -0
- package/declaration/index.d.ts +3 -1
- package/declaration/utils.d.ts +2 -0
- package/dist/flicking.cjs.js +393 -7
- package/dist/flicking.cjs.js.map +1 -1
- package/dist/flicking.esm.js +383 -7
- package/dist/flicking.esm.js.map +1 -1
- package/dist/flicking.js +393 -7
- 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 +1160 -767
- 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 +3 -2
- package/sass/flicking.sass +13 -0
- package/src/CrossFlicking.ts +439 -0
- package/src/camera/Camera.ts +24 -4
- package/src/const/external.ts +14 -0
- package/src/index.ts +4 -1
- package/src/index.umd.ts +2 -0
- package/src/utils.ts +21 -0
- package/dist/flicking-inline.css +0 -45
- package/dist/flicking-inline.min.css +0 -1
- package/dist/flicking.css +0 -44
- package/dist/flicking.min.css +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@egjs/flicking",
|
|
3
|
-
"version": "4.12.0-beta.
|
|
3
|
+
"version": "4.12.0-beta.10",
|
|
4
4
|
"description": "Everyday 30 million people experience. It's reliable, flexible and extendable carousel.",
|
|
5
5
|
"main": "dist/flicking.cjs.js",
|
|
6
6
|
"module": "dist/flicking.esm.js",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"types": "declaration/index.d.ts",
|
|
13
13
|
"scripts": {
|
|
14
14
|
"start": "concurrently \"rollup -w --config ./rollup.config.dev.js\" \"http-serve\"",
|
|
15
|
-
"build": "run-s build:bundle build:declaration
|
|
15
|
+
"build": "run-s build:bundle build:declaration printsizes",
|
|
16
|
+
"build-react": "run-s build:bundle build:declaration && pvu --build=react-flicking",
|
|
16
17
|
"build:bundle": "rm -rf ./dist && rollup -c",
|
|
17
18
|
"build:declaration": "rm -rf ./declaration && tsc -p tsconfig.declaration.json",
|
|
18
19
|
"build:css": "run-s build:css-clear build:sass build:css-prefix build:css-min",
|
package/sass/flicking.sass
CHANGED
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
position: relative
|
|
3
3
|
overflow: hidden
|
|
4
4
|
&.vertical
|
|
5
|
+
display: -webkit-inline-box
|
|
6
|
+
display: -ms-inline-flexbox
|
|
5
7
|
display: inline-flex
|
|
6
8
|
>.flicking-camera
|
|
9
|
+
display: -webkit-inline-box
|
|
10
|
+
display: -ms-inline-flexbox
|
|
7
11
|
display: inline-flex
|
|
12
|
+
-webkit-box-orient: vertical
|
|
13
|
+
-webkit-box-direction: normal
|
|
14
|
+
-ms-flex-direction: column
|
|
8
15
|
flex-direction: column
|
|
9
16
|
&.flicking-hidden
|
|
10
17
|
>.flicking-camera
|
|
@@ -14,10 +21,16 @@
|
|
|
14
21
|
.flicking-camera
|
|
15
22
|
width: 100%
|
|
16
23
|
height: 100%
|
|
24
|
+
display: -webkit-box
|
|
25
|
+
display: -ms-flexbox
|
|
17
26
|
display: flex
|
|
18
27
|
position: relative
|
|
28
|
+
-webkit-box-orient: horizontal
|
|
29
|
+
-webkit-box-direction: normal
|
|
30
|
+
-ms-flex-direction: row
|
|
19
31
|
flex-direction: row
|
|
20
32
|
z-index: 1
|
|
21
33
|
will-change: transform
|
|
22
34
|
>*
|
|
35
|
+
-ms-flex-negative: 0
|
|
23
36
|
flex-shrink: 0
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2015 NAVER Corp.
|
|
3
|
+
* egjs projects are licensed under the MIT license
|
|
4
|
+
*/
|
|
5
|
+
import { ComponentEvent } from "@egjs/component";
|
|
6
|
+
import { EventKey } from "@egjs/component/declaration/types";
|
|
7
|
+
|
|
8
|
+
import Flicking, { FlickingEvents, FlickingOptions } from "./Flicking";
|
|
9
|
+
import {
|
|
10
|
+
ChangedEvent,
|
|
11
|
+
HoldEndEvent,
|
|
12
|
+
HoldStartEvent,
|
|
13
|
+
MoveEndEvent,
|
|
14
|
+
MoveEvent,
|
|
15
|
+
MoveStartEvent,
|
|
16
|
+
WillChangeEvent
|
|
17
|
+
} from "./type/event";
|
|
18
|
+
import { LiteralUnion, ValueOf } from "./type/internal";
|
|
19
|
+
import { CLASS, EVENTS, MOVE_DIRECTION } from "./const/external";
|
|
20
|
+
import { getDataAttributes, includes, toArray } from "./utils";
|
|
21
|
+
|
|
22
|
+
export const SIDE_EVENTS = {
|
|
23
|
+
HOLD_START: "sideHoldStart",
|
|
24
|
+
HOLD_END: "sideHoldEnd",
|
|
25
|
+
MOVE_START: "sideMoveStart",
|
|
26
|
+
MOVE: "sideMove",
|
|
27
|
+
MOVE_END: "sideMoveEnd",
|
|
28
|
+
WILL_CHANGE: "sideWillChange",
|
|
29
|
+
CHANGED: "sideChanged"
|
|
30
|
+
} as const;
|
|
31
|
+
|
|
32
|
+
export type CrossFlickingEvent<T> = { mainIndex: number } & T;
|
|
33
|
+
|
|
34
|
+
export interface CrossFlickingEvents extends FlickingEvents {
|
|
35
|
+
[SIDE_EVENTS.HOLD_START]: CrossFlickingEvent<HoldStartEvent>;
|
|
36
|
+
[SIDE_EVENTS.HOLD_END]: CrossFlickingEvent<HoldEndEvent>;
|
|
37
|
+
[SIDE_EVENTS.MOVE_START]: CrossFlickingEvent<MoveStartEvent>;
|
|
38
|
+
[SIDE_EVENTS.MOVE]: CrossFlickingEvent<MoveEvent>;
|
|
39
|
+
[SIDE_EVENTS.MOVE_END]: CrossFlickingEvent<MoveEndEvent>;
|
|
40
|
+
[SIDE_EVENTS.WILL_CHANGE]: CrossFlickingEvent<WillChangeEvent>;
|
|
41
|
+
[SIDE_EVENTS.CHANGED]: CrossFlickingEvent<ChangedEvent>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CrossFlickingOptions extends FlickingOptions {
|
|
45
|
+
sideOptions: Partial<FlickingOptions> | undefined;
|
|
46
|
+
preserveIndex: boolean | undefined;
|
|
47
|
+
disableSlideOnHold: boolean | undefined;
|
|
48
|
+
disableIndexSync: boolean | undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface SideState {
|
|
52
|
+
key: string;
|
|
53
|
+
start: number;
|
|
54
|
+
end: number;
|
|
55
|
+
element: HTMLElement;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export class CrossFlicking extends Flicking {
|
|
59
|
+
// Core components
|
|
60
|
+
private _sideFlicking: Flicking[];
|
|
61
|
+
|
|
62
|
+
// Options
|
|
63
|
+
private _sideOptions: CrossFlickingOptions["sideOptions"];
|
|
64
|
+
private _preserveIndex: CrossFlickingOptions["preserveIndex"];
|
|
65
|
+
private _disableSlideOnHold: CrossFlickingOptions["disableSlideOnHold"];
|
|
66
|
+
private _disableIndexSync: CrossFlickingOptions["disableIndexSync"];
|
|
67
|
+
|
|
68
|
+
// Internal State
|
|
69
|
+
private _sideState: SideState[];
|
|
70
|
+
private _moveDirection: LiteralUnion<ValueOf<typeof MOVE_DIRECTION>> | null;
|
|
71
|
+
private _originalDragThreshold: number;
|
|
72
|
+
private _nextIndex: number;
|
|
73
|
+
|
|
74
|
+
// Components
|
|
75
|
+
public get sideFlicking() {
|
|
76
|
+
return this._sideFlicking;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public get sideState() {
|
|
80
|
+
return this._sideState;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Options Getter
|
|
84
|
+
public get sideOptions() { return this._sideOptions; }
|
|
85
|
+
|
|
86
|
+
public get preserveIndex() { return this._preserveIndex; }
|
|
87
|
+
|
|
88
|
+
public get disableSlideOnHold() { return this._disableSlideOnHold; }
|
|
89
|
+
|
|
90
|
+
public get disableIndexSync() { return this._disableIndexSync; }
|
|
91
|
+
|
|
92
|
+
// Options Setter
|
|
93
|
+
public set sideOptions(val: CrossFlickingOptions["sideOptions"]) {
|
|
94
|
+
this._sideOptions = val;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public set preserveIndex(val: CrossFlickingOptions["preserveIndex"]) {
|
|
98
|
+
this._preserveIndex = val;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public set disableSlideOnHold(val: CrossFlickingOptions["disableSlideOnHold"]) {
|
|
102
|
+
this._disableSlideOnHold = val;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public set disableIndexSync(val: CrossFlickingOptions["disableIndexSync"]) {
|
|
106
|
+
this._disableIndexSync = val;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public constructor(
|
|
110
|
+
root: HTMLElement | string,
|
|
111
|
+
options: Partial<CrossFlickingOptions>
|
|
112
|
+
) {
|
|
113
|
+
super(root, options);
|
|
114
|
+
const {
|
|
115
|
+
sideOptions = {},
|
|
116
|
+
preserveIndex = true,
|
|
117
|
+
disableSlideOnHold = true,
|
|
118
|
+
disableIndexSync = false
|
|
119
|
+
} = options;
|
|
120
|
+
|
|
121
|
+
// Internal states
|
|
122
|
+
this._moveDirection = null;
|
|
123
|
+
this._nextIndex = 0;
|
|
124
|
+
this._originalDragThreshold = this.dragThreshold;
|
|
125
|
+
|
|
126
|
+
// Bind options
|
|
127
|
+
this._sideOptions = sideOptions;
|
|
128
|
+
this._preserveIndex = preserveIndex;
|
|
129
|
+
this._disableSlideOnHold = disableSlideOnHold;
|
|
130
|
+
this._disableIndexSync = disableIndexSync;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public init(): Promise<void> {
|
|
134
|
+
return super.init().then(() => {
|
|
135
|
+
this._sideState = this._createSideState();
|
|
136
|
+
this._sideFlicking = this._createSideFlicking();
|
|
137
|
+
this._addComponentEvents();
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public destroy(): void {
|
|
142
|
+
this._sideFlicking.forEach((flicking) => {
|
|
143
|
+
flicking.destroy();
|
|
144
|
+
});
|
|
145
|
+
super.destroy();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private _addComponentEvents(): void {
|
|
149
|
+
this.on(EVENTS.HOLD_START, this._onHorizontalHoldStart);
|
|
150
|
+
this.on(EVENTS.MOVE, this._onHorizontalMove);
|
|
151
|
+
this.on(EVENTS.MOVE_END, this._onHorizontalMoveEnd);
|
|
152
|
+
|
|
153
|
+
this._sideFlicking.forEach((flicking, mainIndex) => {
|
|
154
|
+
flicking.on(EVENTS.HOLD_START, this._onSideHoldStart);
|
|
155
|
+
flicking.on(EVENTS.MOVE, this._onSideMove);
|
|
156
|
+
flicking.on(EVENTS.MOVE_END, this._onSideMoveEnd);
|
|
157
|
+
flicking.on(EVENTS.CHANGED, this._onSideChanged);
|
|
158
|
+
|
|
159
|
+
Object.keys(SIDE_EVENTS).forEach((name: EventKey<FlickingEvents>) => {
|
|
160
|
+
flicking.on(EVENTS[name], (event) => {
|
|
161
|
+
this.trigger(
|
|
162
|
+
new ComponentEvent(SIDE_EVENTS[name], {
|
|
163
|
+
mainIndex,
|
|
164
|
+
...event
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private _createSideState(): SideState[] {
|
|
173
|
+
const viewportEl = this.element;
|
|
174
|
+
const cameraEl = this.camera.element;
|
|
175
|
+
const panels = toArray(cameraEl.children) as HTMLElement[];
|
|
176
|
+
const isCrossStructure = getDataAttributes(
|
|
177
|
+
viewportEl,
|
|
178
|
+
"data-cross-"
|
|
179
|
+
).structure;
|
|
180
|
+
let sideState: SideState[] = [];
|
|
181
|
+
|
|
182
|
+
if (!isCrossStructure) {
|
|
183
|
+
const groupPanels = this._getGroupFromAttribute(panels);
|
|
184
|
+
const groupKeys = Object.keys(groupPanels);
|
|
185
|
+
|
|
186
|
+
if (groupKeys.length) {
|
|
187
|
+
sideState = this._getSideStateFromGroup(groupPanels);
|
|
188
|
+
this.remove(0, this.panelCount - groupKeys.length);
|
|
189
|
+
} else {
|
|
190
|
+
sideState = this._getSideStateFromPanels(panels);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
this._createCrossStructure(sideState);
|
|
194
|
+
} else {
|
|
195
|
+
sideState = this._getSideStateFromCrossStructure(panels);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
void this.resize();
|
|
199
|
+
|
|
200
|
+
return sideState;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private _createCrossStructure(sideState: SideState[]) {
|
|
204
|
+
const sideCamera = document.createElement("div");
|
|
205
|
+
let sidePanels: string = "";
|
|
206
|
+
|
|
207
|
+
sideCamera.classList.add(CLASS.CAMERA);
|
|
208
|
+
sideState.forEach((state, i) => {
|
|
209
|
+
const panel = this.camera.children[i];
|
|
210
|
+
sidePanels += state.element.innerHTML;
|
|
211
|
+
Array.from(panel.attributes).forEach((attribute) =>
|
|
212
|
+
panel.removeAttribute(attribute.name)
|
|
213
|
+
);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
sideCamera.innerHTML = sidePanels;
|
|
217
|
+
|
|
218
|
+
sideState.forEach((_, i) => {
|
|
219
|
+
const panel = this.camera.children[i];
|
|
220
|
+
[CLASS.VIEWPORT, CLASS.VERTICAL].forEach((className) => {
|
|
221
|
+
if (!panel.classList.contains(className)) {
|
|
222
|
+
panel.classList.add(className);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
panel.innerHTML = sideCamera.outerHTML;
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
this.element.setAttribute("data-cross-structure", "true");
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private _getGroupFromAttribute(
|
|
232
|
+
panels: HTMLElement[]
|
|
233
|
+
): Record<string, HTMLElement[]> {
|
|
234
|
+
const groupKeys: string[] = [];
|
|
235
|
+
const groupPanels: Record<string, HTMLElement[]> = {};
|
|
236
|
+
|
|
237
|
+
panels.forEach((panel) => {
|
|
238
|
+
const groupKey = getDataAttributes(panel, "data-cross-").groupkey;
|
|
239
|
+
if (groupKey && !includes(groupKeys, groupKey)) {
|
|
240
|
+
groupKeys.push(groupKey);
|
|
241
|
+
groupPanels[groupKey] = [panel];
|
|
242
|
+
} else if (groupKey) {
|
|
243
|
+
groupPanels[groupKey].push(panel);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
return groupPanels;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
private _getSideStateFromGroup(
|
|
251
|
+
groupPanels: Record<string, HTMLElement[]>
|
|
252
|
+
): SideState[] {
|
|
253
|
+
return Object.keys(groupPanels).reduce(
|
|
254
|
+
(state: SideState[], key: string) => {
|
|
255
|
+
const start = state.length ? +state[state.length - 1].end + 1 : 0;
|
|
256
|
+
const element = groupPanels[key].reduce(
|
|
257
|
+
(el: HTMLElement, panel: HTMLElement) => {
|
|
258
|
+
el.innerHTML += panel.outerHTML;
|
|
259
|
+
return el;
|
|
260
|
+
},
|
|
261
|
+
document.createElement("div")
|
|
262
|
+
);
|
|
263
|
+
return [
|
|
264
|
+
...state,
|
|
265
|
+
{
|
|
266
|
+
key,
|
|
267
|
+
start,
|
|
268
|
+
end: start + groupPanels[key].length - 1,
|
|
269
|
+
element: element
|
|
270
|
+
}
|
|
271
|
+
];
|
|
272
|
+
},
|
|
273
|
+
[]
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private _getSideStateFromPanels(panels: HTMLElement[]): SideState[] {
|
|
278
|
+
return panels.reduce(
|
|
279
|
+
(state: SideState[], panel: HTMLElement, i: number) => {
|
|
280
|
+
const start = state.length ? +state[state.length - 1].end + 1 : 0;
|
|
281
|
+
return [
|
|
282
|
+
...state,
|
|
283
|
+
{
|
|
284
|
+
key: i.toString(),
|
|
285
|
+
start,
|
|
286
|
+
end: start + panel.children.length - 1,
|
|
287
|
+
element: panel
|
|
288
|
+
}
|
|
289
|
+
];
|
|
290
|
+
},
|
|
291
|
+
[]
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private _getSideStateFromCrossStructure(panels: HTMLElement[]): SideState[] {
|
|
296
|
+
const groupPanels = this._getGroupFromAttribute(panels);
|
|
297
|
+
return this._getSideStateFromGroup(groupPanels);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private _createSideFlicking(): Flicking[] {
|
|
301
|
+
return this.sideState.map((state, i) => {
|
|
302
|
+
return new Flicking(this.camera.children[i], {
|
|
303
|
+
...this.sideOptions,
|
|
304
|
+
horizontal: false,
|
|
305
|
+
panelsPerView: 1,
|
|
306
|
+
defaultIndex: state.start
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
private _syncToCategory = (index: number, outerIndex: number): void => {
|
|
312
|
+
if (this._disableIndexSync) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
this.stopAnimation();
|
|
317
|
+
this._sideFlicking.forEach((child, i) => {
|
|
318
|
+
const { start, end } = this._sideState[i];
|
|
319
|
+
|
|
320
|
+
if (start <= index && end >= index && outerIndex !== i) {
|
|
321
|
+
child.stopAnimation();
|
|
322
|
+
void child.moveTo(index, 0);
|
|
323
|
+
void this.moveTo(i, 0);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
private _setDraggable = (
|
|
329
|
+
direction: ValueOf<typeof MOVE_DIRECTION>,
|
|
330
|
+
draggable: boolean
|
|
331
|
+
): void => {
|
|
332
|
+
if (!this._disableSlideOnHold) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const dragThreshold = this._originalDragThreshold;
|
|
337
|
+
const threshold = draggable
|
|
338
|
+
? dragThreshold && dragThreshold >= 10
|
|
339
|
+
? dragThreshold
|
|
340
|
+
: 10
|
|
341
|
+
: Infinity;
|
|
342
|
+
|
|
343
|
+
if ((direction === MOVE_DIRECTION.HORIZONTAL) === this.horizontal) {
|
|
344
|
+
this.dragThreshold = threshold;
|
|
345
|
+
} else if ((direction === MOVE_DIRECTION.VERTICAL) === this.horizontal) {
|
|
346
|
+
this._sideFlicking.forEach((child) => {
|
|
347
|
+
child.dragThreshold = threshold;
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
private _setPreviousSideIndex = () => {
|
|
353
|
+
this._sideFlicking.forEach((child, i) => {
|
|
354
|
+
const { start, end } = this._sideState[i];
|
|
355
|
+
|
|
356
|
+
if (this._preserveIndex) {
|
|
357
|
+
if (this._nextIndex !== i) {
|
|
358
|
+
if (child.index < start) {
|
|
359
|
+
child.stopAnimation();
|
|
360
|
+
void child.moveTo(start, 0);
|
|
361
|
+
} else if (child.index > end) {
|
|
362
|
+
child.stopAnimation();
|
|
363
|
+
void child.moveTo(end, 0);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
if (this._nextIndex !== i) {
|
|
368
|
+
void child.moveTo(start, 0);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
private _onHorizontalHoldStart = (): void => {
|
|
375
|
+
this._setDraggable(MOVE_DIRECTION.HORIZONTAL, true);
|
|
376
|
+
this._moveDirection = null;
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
private _onHorizontalMove = (e: MoveEvent): void => {
|
|
380
|
+
if (e.isTrusted && !this._moveDirection) {
|
|
381
|
+
this._setDraggable(MOVE_DIRECTION.VERTICAL, false);
|
|
382
|
+
this._moveDirection = MOVE_DIRECTION.HORIZONTAL;
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
private _onHorizontalMoveEnd = (e: MoveEndEvent): void => {
|
|
387
|
+
const visiblePanels = this.visiblePanels;
|
|
388
|
+
|
|
389
|
+
if (visiblePanels.length > 1) {
|
|
390
|
+
this._nextIndex =
|
|
391
|
+
e.direction === "NEXT"
|
|
392
|
+
? visiblePanels[1].index
|
|
393
|
+
: visiblePanels[0].index;
|
|
394
|
+
} else {
|
|
395
|
+
this._nextIndex = visiblePanels[0].index;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
this._setDraggable(MOVE_DIRECTION.VERTICAL, true);
|
|
399
|
+
this._moveDirection = null;
|
|
400
|
+
|
|
401
|
+
// _syncToCategory에서 완전히 가로 이동이 이루어지기 전에 세로 방향 index가 변하는 경우가 있어 requestAnimationFrame 처리
|
|
402
|
+
requestAnimationFrame(() => this._setPreviousSideIndex());
|
|
403
|
+
|
|
404
|
+
if (e.isTrusted) {
|
|
405
|
+
this._syncToCategory(
|
|
406
|
+
this._sideFlicking[this._nextIndex].index,
|
|
407
|
+
this._nextIndex
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
private _onSideHoldStart = (): void => {
|
|
413
|
+
this._setDraggable(MOVE_DIRECTION.VERTICAL, true);
|
|
414
|
+
this._moveDirection = null;
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
private _onSideMove = (e: MoveEvent): void => {
|
|
418
|
+
if (e.isTrusted && !this._moveDirection) {
|
|
419
|
+
this._setDraggable(MOVE_DIRECTION.HORIZONTAL, false);
|
|
420
|
+
this._moveDirection = MOVE_DIRECTION.VERTICAL;
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
private _onSideMoveEnd = (): void => {
|
|
425
|
+
this._setDraggable(MOVE_DIRECTION.HORIZONTAL, true);
|
|
426
|
+
this._moveDirection = null;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
private _onSideChanged = (e: ChangedEvent): void => {
|
|
430
|
+
// If this.visiblePanels.length >= 2, it means that horizontal flicking is being dragged.
|
|
431
|
+
// In this case, syncToCategory in _onHorizontalMoveEnd will fire after moving finishes, so we don't fire it here.
|
|
432
|
+
if (
|
|
433
|
+
this.visiblePanels.length < 2 &&
|
|
434
|
+
this._sideFlicking[this.index] === e.currentTarget
|
|
435
|
+
) {
|
|
436
|
+
this._syncToCategory(e.index, this.index);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
}
|
package/src/camera/Camera.ts
CHANGED
|
@@ -32,6 +32,7 @@ class Camera {
|
|
|
32
32
|
private _mode: CameraMode;
|
|
33
33
|
private _el: HTMLElement;
|
|
34
34
|
private _transform: string;
|
|
35
|
+
private _lookedOffset = 0;
|
|
35
36
|
private _position: number;
|
|
36
37
|
private _alignPos: number;
|
|
37
38
|
private _offset: number;
|
|
@@ -292,6 +293,8 @@ class Camera {
|
|
|
292
293
|
* @return {this}
|
|
293
294
|
*/
|
|
294
295
|
public lookAt(pos: number): void {
|
|
296
|
+
const prevOffset = this._offset;
|
|
297
|
+
const isChangedOffset = this._lookedOffset !== prevOffset;
|
|
295
298
|
const flicking = getFlickingAttached(this._flicking);
|
|
296
299
|
const prevPos = this._position;
|
|
297
300
|
|
|
@@ -304,7 +307,12 @@ class Camera {
|
|
|
304
307
|
if (toggled) {
|
|
305
308
|
void flicking.renderer.render().then(() => {
|
|
306
309
|
this.updateOffset();
|
|
310
|
+
this._lookedOffset = this._offset;
|
|
307
311
|
});
|
|
312
|
+
} else if (isChangedOffset) {
|
|
313
|
+
// sync offset for renderOnlyVisible on resize
|
|
314
|
+
this.updateOffset();
|
|
315
|
+
this._lookedOffset = this._offset;
|
|
308
316
|
} else {
|
|
309
317
|
this.applyTransform();
|
|
310
318
|
}
|
|
@@ -502,8 +510,8 @@ class Camera {
|
|
|
502
510
|
}
|
|
503
511
|
|
|
504
512
|
/**
|
|
505
|
-
* Update Viewport's height to
|
|
506
|
-
* @ko 현재
|
|
513
|
+
* Update Viewport's height to visible panel's max height
|
|
514
|
+
* @ko 현재 활성화된 패널과 보이는 패널의 최대 높이와 동일하도록 뷰포트의 높이를 업데이트합니다
|
|
507
515
|
* @throws {FlickingError}
|
|
508
516
|
* {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
|
|
509
517
|
* <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
|
|
@@ -513,11 +521,22 @@ class Camera {
|
|
|
513
521
|
public updateAdaptiveHeight() {
|
|
514
522
|
const flicking = getFlickingAttached(this._flicking);
|
|
515
523
|
const activePanel = flicking.control.activePanel;
|
|
524
|
+
const visiblePanels = flicking.visiblePanels;
|
|
525
|
+
|
|
526
|
+
const selectedPanels = [...visiblePanels];
|
|
527
|
+
|
|
528
|
+
if (activePanel) {
|
|
529
|
+
selectedPanels.push(activePanel);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (!flicking.horizontal || !flicking.adaptive || !selectedPanels.length) return;
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
const maxHeight = Math.max(...selectedPanels.map(panel => panel.height));
|
|
516
536
|
|
|
517
|
-
if (!flicking.horizontal || !flicking.adaptive || !activePanel) return;
|
|
518
537
|
|
|
519
538
|
flicking.viewport.setSize({
|
|
520
|
-
height:
|
|
539
|
+
height: maxHeight
|
|
521
540
|
});
|
|
522
541
|
}
|
|
523
542
|
|
|
@@ -599,6 +618,7 @@ class Camera {
|
|
|
599
618
|
|
|
600
619
|
private _resetInternalValues() {
|
|
601
620
|
this._position = 0;
|
|
621
|
+
this._lookedOffset = 0;
|
|
602
622
|
this._alignPos = 0;
|
|
603
623
|
this._offset = 0;
|
|
604
624
|
this._circularOffset = 0;
|
package/src/const/external.ts
CHANGED
|
@@ -94,6 +94,8 @@ export const MOVE_TYPE = {
|
|
|
94
94
|
} as const;
|
|
95
95
|
|
|
96
96
|
export const CLASS = {
|
|
97
|
+
VIEWPORT: "flicking-viewport",
|
|
98
|
+
CAMERA: "flicking-camera",
|
|
97
99
|
VERTICAL: "vertical",
|
|
98
100
|
HIDDEN: "flicking-hidden",
|
|
99
101
|
DEFAULT_VIRTUAL: "flicking-panel"
|
|
@@ -122,3 +124,15 @@ export const ORDER = {
|
|
|
122
124
|
LTR: "ltr",
|
|
123
125
|
RTL: "rtl"
|
|
124
126
|
} as const;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* An object that contains the direction that {@link Flicking} is moving
|
|
130
|
+
* @ko {@link Flicking}이 움직이는 방향을 담고 있는 객체
|
|
131
|
+
* @type {object}
|
|
132
|
+
* @property {"horizontal"} HORIZONTAL horizontal<ko>수평 방향</ko>
|
|
133
|
+
* @property {"vertical"} VERTICAL vertical<ko>수직 방향</ko>
|
|
134
|
+
*/
|
|
135
|
+
export const MOVE_DIRECTION = {
|
|
136
|
+
HORIZONTAL: "horizontal",
|
|
137
|
+
VERTICAL: "vertical"
|
|
138
|
+
} as const;
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import Flicking from "./Flicking";
|
|
6
6
|
import type { FlickingOptions, FlickingEvents } from "./Flicking";
|
|
7
|
+
import type { CrossFlickingOptions } from "./CrossFlicking";
|
|
8
|
+
|
|
9
|
+
export * from "./CrossFlicking";
|
|
7
10
|
|
|
8
11
|
export * from "./core";
|
|
9
12
|
export * from "./camera";
|
|
@@ -15,6 +18,6 @@ export * from "./utils";
|
|
|
15
18
|
|
|
16
19
|
export * from "./type/event";
|
|
17
20
|
export * from "./type/external";
|
|
18
|
-
export type { FlickingOptions, FlickingEvents };
|
|
21
|
+
export type { FlickingOptions, FlickingEvents, CrossFlickingOptions };
|
|
19
22
|
|
|
20
23
|
export default Flicking;
|
package/src/index.umd.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* egjs projects are licensed under the MIT license
|
|
4
4
|
*/
|
|
5
5
|
import Flicking from "./Flicking";
|
|
6
|
+
import * as CrossFlicking from "./CrossFlicking";
|
|
6
7
|
import * as Core from "./core";
|
|
7
8
|
import * as Camera from "./camera";
|
|
8
9
|
import * as Control from "./control";
|
|
@@ -19,5 +20,6 @@ merge(Flicking, Renderer);
|
|
|
19
20
|
merge(Flicking, Constants);
|
|
20
21
|
merge(Flicking, CFC);
|
|
21
22
|
merge(Flicking, Utils);
|
|
23
|
+
merge(Flicking, CrossFlicking);
|
|
22
24
|
|
|
23
25
|
export default Flicking;
|
package/src/utils.ts
CHANGED
|
@@ -349,3 +349,24 @@ export const setPrototypeOf = Object.setPrototypeOf || ((obj, proto) => {
|
|
|
349
349
|
obj.__proto__ = proto;
|
|
350
350
|
return obj;
|
|
351
351
|
});
|
|
352
|
+
|
|
353
|
+
export const camelize = (str: string): string => {
|
|
354
|
+
return str.replace(/[\s-_]([a-z])/g, (all, letter) => letter.toUpperCase());
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
export const getDataAttributes = (element: HTMLElement, attributePrefix: string): Record<string, string> => {
|
|
358
|
+
const dataAttributes: Record<string, string> = {};
|
|
359
|
+
const attributes = element.attributes;
|
|
360
|
+
const length = attributes.length;
|
|
361
|
+
|
|
362
|
+
for (let i = 0; i < length; ++i) {
|
|
363
|
+
const attribute = attributes[i];
|
|
364
|
+
const { name, value } = attribute;
|
|
365
|
+
if (name.indexOf(attributePrefix) === -1) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
dataAttributes[camelize(name.replace(attributePrefix, ""))] = value;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return dataAttributes;
|
|
372
|
+
};
|
package/dist/flicking-inline.css
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
.flicking-viewport {
|
|
2
|
-
position: relative;
|
|
3
|
-
overflow: hidden;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.flicking-viewport:not(.vertical) {
|
|
7
|
-
width: 100%;
|
|
8
|
-
height: 100%;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.flicking-viewport.vertical,
|
|
12
|
-
.flicking-viewport.vertical > .flicking-camera {
|
|
13
|
-
display: inline-block;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.flicking-viewport.vertical.middle > .flicking-camera > * {
|
|
17
|
-
vertical-align: middle;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.flicking-viewport.vertical.bottom > .flicking-camera > * {
|
|
21
|
-
vertical-align: bottom;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.flicking-viewport.vertical > .flicking-camera > * {
|
|
25
|
-
display: block;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.flicking-viewport.flicking-hidden > .flicking-camera > * {
|
|
29
|
-
visibility: hidden;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.flicking-camera {
|
|
33
|
-
width: 100%;
|
|
34
|
-
height: 100%;
|
|
35
|
-
position: relative;
|
|
36
|
-
z-index: 1;
|
|
37
|
-
white-space: nowrap;
|
|
38
|
-
will-change: transform;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.flicking-camera > * {
|
|
42
|
-
display: inline-block;
|
|
43
|
-
white-space: normal;
|
|
44
|
-
vertical-align: top;
|
|
45
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.flicking-viewport{position:relative;overflow:hidden}.flicking-viewport:not(.vertical){width:100%;height:100%}.flicking-viewport.vertical,.flicking-viewport.vertical>.flicking-camera{display:inline-block}.flicking-viewport.vertical.middle>.flicking-camera>*{vertical-align:middle}.flicking-viewport.vertical.bottom>.flicking-camera>*{vertical-align:bottom}.flicking-viewport.vertical>.flicking-camera>*{display:block}.flicking-viewport.flicking-hidden>.flicking-camera>*{visibility:hidden}.flicking-camera{width:100%;height:100%;position:relative;z-index:1;white-space:nowrap;will-change:transform}.flicking-camera>*{display:inline-block;white-space:normal;vertical-align:top}
|