vevet 2.0.1-dev.2 → 2.0.1-dev.20
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/build/cdn/index.js +1 -1
- package/build/cjs/components/canvas/Ctx2DPrerender.js +20 -2
- package/build/cjs/components/loading/ProgressPreloader.js +14 -2
- package/build/cjs/components/page/Page.js +36 -8
- package/build/cjs/components/scroll/plugins/SmoothScrollDragPlugin.js +40 -5
- package/build/cjs/components/scroll/plugins/SmoothScrollKeyboardPlugin.js +9 -0
- package/build/cjs/components/scroll/scrollable/ScrollView.js +67 -53
- package/build/cjs/components/scroll/scrollbar/Bar.js +8 -2
- package/build/cjs/components/scroll/smooth-scroll/SmoothScroll.js +11 -3
- package/build/cjs/components/text/SplitText.js +18 -2
- package/build/cjs/components/timeline/Timeline.js +1 -0
- package/build/cjs/handlers/wheel/WheelHandler.js +195 -0
- package/build/cjs/index.js +3 -1
- package/build/cjs/utils/listeners/onScroll.js +65 -25
- package/build/cjs/utils/math/index.js +5 -1
- package/build/cjs/utils/math/spreadScopeProgress.js +18 -0
- package/build/cjs/utils/math/wrap.js +13 -0
- package/build/es/app/Application.js +50 -93
- package/build/es/app/events/PageLoad.js +3 -7
- package/build/es/app/events/Viewport.js +10 -34
- package/build/es/base/Callbacks.js +8 -19
- package/build/es/base/Component.js +0 -1
- package/build/es/base/Module.js +41 -61
- package/build/es/base/MutableProp.js +10 -32
- package/build/es/base/Plugin.js +0 -1
- package/build/es/components/animation-frame/AnimationFrame.js +4 -28
- package/build/es/components/canvas/Ctx2D.js +21 -49
- package/build/es/components/canvas/Ctx2DPrerender.js +21 -7
- package/build/es/components/cursor/CustomCursor.js +25 -58
- package/build/es/components/dragger/Dragger.js +20 -41
- package/build/es/components/dragger/DraggerDirection.js +1 -4
- package/build/es/components/loading/Preloader.js +26 -41
- package/build/es/components/loading/ProgressPreloader.js +31 -38
- package/build/es/components/page/Page.js +46 -41
- package/build/es/components/scroll/plugins/SmoothScrollDragPlugin.js +47 -29
- package/build/es/components/scroll/plugins/SmoothScrollKeyboardPlugin.js +9 -0
- package/build/es/components/scroll/scrollable/ScrollEventsBase.js +15 -22
- package/build/es/components/scroll/scrollable/ScrollView.js +62 -74
- package/build/es/components/scroll/scrollbar/Bar.js +43 -54
- package/build/es/components/scroll/scrollbar/ScrollBar.js +47 -73
- package/build/es/components/scroll/smooth-scroll/SmoothScroll.js +63 -135
- package/build/es/components/text/SplitText.js +38 -43
- package/build/es/components/timeline/StaticTimeline.js +11 -22
- package/build/es/components/timeline/Timeline.js +13 -28
- package/build/es/handlers/wheel/WheelHandler.js +153 -0
- package/build/es/index.js +2 -1
- package/build/es/utils/listeners/onScroll.js +64 -25
- package/build/es/utils/math/index.js +3 -1
- package/build/es/utils/math/spreadScopeProgress.js +15 -0
- package/build/es/utils/math/wrap.js +10 -0
- package/build/types/components/canvas/Ctx2DPrerender.d.ts +1 -1
- package/build/types/components/canvas/Ctx2DPrerender.d.ts.map +1 -1
- package/build/types/components/loading/ProgressPreloader.d.ts +7 -0
- package/build/types/components/loading/ProgressPreloader.d.ts.map +1 -1
- package/build/types/components/page/Page.d.ts +2 -0
- package/build/types/components/page/Page.d.ts.map +1 -1
- package/build/types/components/scroll/plugins/SmoothScrollDragPlugin.d.ts +11 -0
- package/build/types/components/scroll/plugins/SmoothScrollDragPlugin.d.ts.map +1 -1
- package/build/types/components/scroll/plugins/SmoothScrollKeyboardPlugin.d.ts.map +1 -1
- package/build/types/components/scroll/scrollable/ScrollView.d.ts +27 -13
- package/build/types/components/scroll/scrollable/ScrollView.d.ts.map +1 -1
- package/build/types/components/scroll/scrollbar/Bar.d.ts.map +1 -1
- package/build/types/components/scroll/smooth-scroll/SmoothScroll.d.ts.map +1 -1
- package/build/types/components/text/SplitText.d.ts +6 -0
- package/build/types/components/text/SplitText.d.ts.map +1 -1
- package/build/types/components/timeline/Timeline.d.ts.map +1 -1
- package/build/types/handlers/wheel/WheelHandler.d.ts +100 -0
- package/build/types/handlers/wheel/WheelHandler.d.ts.map +1 -0
- package/build/types/index.d.ts +2 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/utils/listeners/onScroll.d.ts +13 -5
- package/build/types/utils/listeners/onScroll.d.ts.map +1 -1
- package/build/types/utils/math/index.d.ts +3 -1
- package/build/types/utils/math/index.d.ts.map +1 -1
- package/build/types/utils/math/spreadScopeProgress.d.ts +5 -0
- package/build/types/utils/math/spreadScopeProgress.d.ts.map +1 -0
- package/build/types/utils/math/wrap.d.ts +5 -0
- package/build/types/utils/math/wrap.d.ts.map +1 -0
- package/package.json +4 -3
- package/src/sass/components/cursor/_custom-cursor.scss +0 -1
- package/src/ts/components/canvas/Ctx2DPrerender.ts +23 -6
- package/src/ts/components/loading/ProgressPreloader.ts +21 -2
- package/src/ts/components/page/Page.ts +34 -8
- package/src/ts/components/scroll/plugins/SmoothScrollDragPlugin.ts +58 -5
- package/src/ts/components/scroll/plugins/SmoothScrollKeyboardPlugin.ts +12 -0
- package/src/ts/components/scroll/scrollable/ScrollView.ts +78 -64
- package/src/ts/components/scroll/scrollbar/Bar.ts +8 -2
- package/src/ts/components/scroll/smooth-scroll/SmoothScroll.ts +12 -3
- package/src/ts/components/text/SplitText.ts +26 -1
- package/src/ts/components/timeline/Timeline.ts +1 -0
- package/src/ts/handlers/wheel/WheelHandler.ts +269 -0
- package/src/ts/index.ts +4 -0
- package/src/ts/utils/listeners/onScroll.ts +105 -34
- package/src/ts/utils/math/index.ts +4 -0
- package/src/ts/utils/math/spreadScopeProgress.ts +18 -0
- package/src/ts/utils/math/wrap.ts +18 -0
|
@@ -101,6 +101,9 @@ export default class Bar {
|
|
|
101
101
|
left: 0,
|
|
102
102
|
top: 0,
|
|
103
103
|
};
|
|
104
|
+
this._scrollEvent = undefined;
|
|
105
|
+
this._actionTimeout = undefined;
|
|
106
|
+
this._dragger = undefined;
|
|
104
107
|
|
|
105
108
|
// create outer
|
|
106
109
|
let outerClassNames = `${prefix} ${prefix}_${dir}`;
|
|
@@ -160,8 +163,11 @@ export default class Bar {
|
|
|
160
163
|
this._listeners.push(addEventListener(this.outer, 'mouseleave', this._handleHover.bind(this, false)));
|
|
161
164
|
|
|
162
165
|
// set scroll events
|
|
163
|
-
this._scrollEvent = onScroll(
|
|
164
|
-
this.
|
|
166
|
+
this._scrollEvent = onScroll({
|
|
167
|
+
container: this.prop.container,
|
|
168
|
+
callback: (data) => {
|
|
169
|
+
this._handleScroll(data);
|
|
170
|
+
},
|
|
165
171
|
});
|
|
166
172
|
|
|
167
173
|
// set dragger
|
|
@@ -366,6 +366,8 @@ export class SmoothScroll <
|
|
|
366
366
|
this._clientWidth = 0;
|
|
367
367
|
this._clientHeight = 0;
|
|
368
368
|
this._instant = false;
|
|
369
|
+
this._animationFrame = undefined;
|
|
370
|
+
this._outerAnimationFrameEvent = undefined;
|
|
369
371
|
this._currentFPS = 60;
|
|
370
372
|
|
|
371
373
|
// get outer elements
|
|
@@ -399,9 +401,11 @@ export class SmoothScroll <
|
|
|
399
401
|
}
|
|
400
402
|
this._elementsLength = this._elements.length;
|
|
401
403
|
// add will-change
|
|
402
|
-
this.
|
|
403
|
-
|
|
404
|
-
|
|
404
|
+
if (this.prop.useWillChange) {
|
|
405
|
+
this._elements.forEach((el) => {
|
|
406
|
+
el.style.willChange = 'transform';
|
|
407
|
+
});
|
|
408
|
+
}
|
|
405
409
|
|
|
406
410
|
// initialize the class
|
|
407
411
|
if (init) {
|
|
@@ -505,6 +509,11 @@ export class SmoothScroll <
|
|
|
505
509
|
this.targetTop = parseInt(this.targetTop.toFixed(0), 10);
|
|
506
510
|
}
|
|
507
511
|
|
|
512
|
+
// set scroll classes
|
|
513
|
+
const hasScroll = this.maxScrollableHeight > 0 || this.maxScrollableWidth > 0;
|
|
514
|
+
outer.classList.toggle('has-scroll', hasScroll);
|
|
515
|
+
outer.classList.toggle('no-scroll', !hasScroll);
|
|
516
|
+
|
|
508
517
|
// render elements
|
|
509
518
|
this._updateElementsProp();
|
|
510
519
|
// this.render();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createElement, selectOne } from 'vevet-dom';
|
|
2
|
+
import { NViewport } from '../../app/events/Viewport';
|
|
2
3
|
import { Component, NComponent } from '../../base/Component';
|
|
3
4
|
import { RequiredModuleProp } from '../../utils/types/utility';
|
|
4
5
|
|
|
@@ -25,6 +26,11 @@ export namespace NSplitText {
|
|
|
25
26
|
* @default false
|
|
26
27
|
*/
|
|
27
28
|
appendLines?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Viewport resize event target
|
|
31
|
+
* @default ''
|
|
32
|
+
*/
|
|
33
|
+
viewportTarget?: keyof NViewport.CallbacksTypes;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
/**
|
|
@@ -84,6 +90,7 @@ export class SplitText <
|
|
|
84
90
|
container: `#${this.prefix}`,
|
|
85
91
|
appendLetters: true,
|
|
86
92
|
appendLines: false,
|
|
93
|
+
viewportTarget: '',
|
|
87
94
|
};
|
|
88
95
|
}
|
|
89
96
|
|
|
@@ -174,7 +181,7 @@ export class SplitText <
|
|
|
174
181
|
// split the text
|
|
175
182
|
this.splitText();
|
|
176
183
|
if (this.prop.appendLines) {
|
|
177
|
-
this.addViewportCallback(
|
|
184
|
+
this.addViewportCallback(this.prop.viewportTarget, () => {
|
|
178
185
|
this.splitText();
|
|
179
186
|
});
|
|
180
187
|
}
|
|
@@ -228,6 +235,7 @@ export class SplitText <
|
|
|
228
235
|
// get type of the char
|
|
229
236
|
const charCode = char.charCodeAt(0);
|
|
230
237
|
const isWhitespace = charCode === 32 || charCode === 160;
|
|
238
|
+
const isSeparator = [45, 8208, 8211, 8212, 8722].includes(charCode);
|
|
231
239
|
const isNewLine = charCode === 10;
|
|
232
240
|
|
|
233
241
|
// add elements
|
|
@@ -251,6 +259,23 @@ export class SplitText <
|
|
|
251
259
|
if (!this.prop.appendLetters) {
|
|
252
260
|
currentWord.el.innerHTML = currentWord.content;
|
|
253
261
|
}
|
|
262
|
+
|
|
263
|
+
// go to next word if needed
|
|
264
|
+
if (isSeparator) {
|
|
265
|
+
wordIndex += 1;
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// only filled words
|
|
270
|
+
this._words = this._words.filter((word, index) => {
|
|
271
|
+
if (word.content.length === 0) {
|
|
272
|
+
if (index > 0) {
|
|
273
|
+
this._words[index - 1].whitespace = word.whitespace;
|
|
274
|
+
this._words[index - 1].br = word.br;
|
|
275
|
+
}
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
return true;
|
|
254
279
|
});
|
|
255
280
|
}
|
|
256
281
|
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { addEventListener, IAddEventListener } from 'vevet-dom';
|
|
2
|
+
import normalizeWheel from 'normalize-wheel';
|
|
3
|
+
import { Module, NModule } from '../../base/Module';
|
|
4
|
+
import { RequiredModuleProp } from '../../utils/types/utility';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export namespace NWheelHandler {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Static properties
|
|
12
|
+
*/
|
|
13
|
+
export interface StaticProp extends NModule.StaticProp {
|
|
14
|
+
/**
|
|
15
|
+
* Container to listen to.
|
|
16
|
+
* False for window
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
container?: false | Element | Window;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Changeable properties
|
|
24
|
+
*/
|
|
25
|
+
export interface ChangeableProp extends NModule.ChangeableProp {
|
|
26
|
+
/**
|
|
27
|
+
* If events are enabled
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
enabled?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* If need to stop propagation
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
stopPropagation?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Amount of pixels to trigger a callback
|
|
38
|
+
* @default 100
|
|
39
|
+
*/
|
|
40
|
+
threshold?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Available callbacks
|
|
45
|
+
*/
|
|
46
|
+
export interface CallbacksTypes extends NModule.CallbacksTypes {
|
|
47
|
+
'up': false;
|
|
48
|
+
'down': false;
|
|
49
|
+
'left': false;
|
|
50
|
+
'right': false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Wheel events: up & down, left & right without repeating
|
|
59
|
+
|
|
60
|
+
*/
|
|
61
|
+
export class WheelHandler <
|
|
62
|
+
StaticProp extends NWheelHandler.StaticProp = NWheelHandler.StaticProp,
|
|
63
|
+
ChangeableProp extends NWheelHandler.ChangeableProp = NWheelHandler.ChangeableProp,
|
|
64
|
+
CallbacksTypes extends NWheelHandler.CallbacksTypes = NWheelHandler.CallbacksTypes,
|
|
65
|
+
> extends Module <
|
|
66
|
+
StaticProp,
|
|
67
|
+
ChangeableProp,
|
|
68
|
+
CallbacksTypes
|
|
69
|
+
> {
|
|
70
|
+
protected _getDefaultProp <
|
|
71
|
+
T extends RequiredModuleProp<StaticProp & ChangeableProp>
|
|
72
|
+
> (): T {
|
|
73
|
+
return {
|
|
74
|
+
...super._getDefaultProp(),
|
|
75
|
+
container: false,
|
|
76
|
+
enabled: true,
|
|
77
|
+
stopPropagation: false,
|
|
78
|
+
threshold: 20,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Listener contianer
|
|
84
|
+
*/
|
|
85
|
+
get container () {
|
|
86
|
+
if (!this.prop.container) {
|
|
87
|
+
return window;
|
|
88
|
+
}
|
|
89
|
+
return this.prop.container;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Wheel listener
|
|
94
|
+
*/
|
|
95
|
+
protected _wheelListener?: IAddEventListener;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* If need to temporary disable wheel
|
|
99
|
+
*/
|
|
100
|
+
protected _lockWheel: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Used to prevent from triggering callback multiple times while wheel events
|
|
103
|
+
*/
|
|
104
|
+
protected _lockWheelTimeout?: any;
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
constructor (
|
|
109
|
+
initialProp?: (StaticProp & ChangeableProp),
|
|
110
|
+
init = true,
|
|
111
|
+
) {
|
|
112
|
+
super(initialProp, false);
|
|
113
|
+
this._wheelListener = undefined;
|
|
114
|
+
this._lockWheel = false;
|
|
115
|
+
if (init) {
|
|
116
|
+
this.init();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
// Set Module Events
|
|
123
|
+
protected _setEvents () {
|
|
124
|
+
super._setEvents();
|
|
125
|
+
|
|
126
|
+
if (!(this.container instanceof Window)) {
|
|
127
|
+
this._listeners.push(addEventListener(this.container, 'mouseenter', this._handleMouseEnter.bind(this)));
|
|
128
|
+
this._listeners.push(addEventListener(this.container, 'mouseleave', this._handleMouseLeave.bind(this)));
|
|
129
|
+
} else {
|
|
130
|
+
this._toggleWheelEvent();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
protected _onPropMutate () {
|
|
135
|
+
super._onPropMutate();
|
|
136
|
+
this._toggleWheelEvent();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Handle element mouse enter
|
|
143
|
+
*/
|
|
144
|
+
protected _handleMouseEnter () {
|
|
145
|
+
if (this.prop.enabled) {
|
|
146
|
+
this._createWheelEvent();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Handle element mouse leave
|
|
152
|
+
*/
|
|
153
|
+
protected _handleMouseLeave () {
|
|
154
|
+
this._destroyWheelEvent();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Set wheel event
|
|
161
|
+
*/
|
|
162
|
+
protected _toggleWheelEvent () {
|
|
163
|
+
if (this.prop.enabled) {
|
|
164
|
+
this._createWheelEvent();
|
|
165
|
+
} else {
|
|
166
|
+
this._destroyWheelEvent();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Create a wheel event
|
|
172
|
+
*/
|
|
173
|
+
protected _createWheelEvent () {
|
|
174
|
+
if (this._wheelListener) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// reset gaining
|
|
178
|
+
this._lockWheel = false;
|
|
179
|
+
if (this._lockWheelTimeout) {
|
|
180
|
+
clearTimeout(this._lockWheelTimeout);
|
|
181
|
+
}
|
|
182
|
+
// create a listener
|
|
183
|
+
this._wheelListener = addEventListener(
|
|
184
|
+
this.container,
|
|
185
|
+
'wheel',
|
|
186
|
+
// throttle(this._handleWheel.bind(this), 200),
|
|
187
|
+
this._handleWheel.bind(this),
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Destroy the wheel event
|
|
193
|
+
*/
|
|
194
|
+
protected _destroyWheelEvent () {
|
|
195
|
+
if (!this._wheelListener) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
this._wheelListener.remove();
|
|
199
|
+
this._wheelListener = undefined;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Handle wheel event
|
|
206
|
+
*/
|
|
207
|
+
protected _handleWheel (
|
|
208
|
+
evt: WheelEvent,
|
|
209
|
+
) {
|
|
210
|
+
if (!this._wheelListener) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// stop propagation
|
|
215
|
+
if (this.prop.stopPropagation) {
|
|
216
|
+
evt.preventDefault();
|
|
217
|
+
evt.stopPropagation();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// if locked
|
|
221
|
+
if (this._lockWheel) {
|
|
222
|
+
if (this._lockWheelTimeout) {
|
|
223
|
+
clearTimeout(this._lockWheelTimeout);
|
|
224
|
+
}
|
|
225
|
+
this._lockWheelTimeout = setTimeout(() => {
|
|
226
|
+
this._lockWheel = false;
|
|
227
|
+
}, 300);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// data
|
|
232
|
+
const delta = normalizeWheel(evt);
|
|
233
|
+
const { threshold } = this.prop;
|
|
234
|
+
|
|
235
|
+
// launch events
|
|
236
|
+
let eventFired = false;
|
|
237
|
+
// Y
|
|
238
|
+
if (delta.pixelY > threshold) {
|
|
239
|
+
this._callbacks.tbt('down', false);
|
|
240
|
+
eventFired = true;
|
|
241
|
+
} else if (delta.pixelY < threshold * -1) {
|
|
242
|
+
this._callbacks.tbt('up', false);
|
|
243
|
+
eventFired = true;
|
|
244
|
+
}
|
|
245
|
+
// X
|
|
246
|
+
if (delta.pixelX > threshold) {
|
|
247
|
+
this._callbacks.tbt('right', false);
|
|
248
|
+
eventFired = true;
|
|
249
|
+
} else if (delta.pixelX < threshold * -1) {
|
|
250
|
+
this._callbacks.tbt('left', false);
|
|
251
|
+
eventFired = true;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// lock events
|
|
255
|
+
if (eventFired) {
|
|
256
|
+
this._lockWheel = true;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Destroy the module
|
|
264
|
+
*/
|
|
265
|
+
protected _destroy () {
|
|
266
|
+
super._destroy();
|
|
267
|
+
this._destroyWheelEvent();
|
|
268
|
+
}
|
|
269
|
+
}
|
package/src/ts/index.ts
CHANGED
|
@@ -16,6 +16,8 @@ import { Plugin, NPlugin } from './base/Plugin';
|
|
|
16
16
|
|
|
17
17
|
import { Page, NPage } from './components/page/Page';
|
|
18
18
|
|
|
19
|
+
import { WheelHandler, NWheelHandler } from './handlers/wheel/WheelHandler';
|
|
20
|
+
|
|
19
21
|
import { AnimationFrame, NAnimationFrame } from './components/animation-frame/AnimationFrame';
|
|
20
22
|
|
|
21
23
|
import { StaticTimeline, NStaticTimeline } from './components/timeline/StaticTimeline';
|
|
@@ -66,6 +68,8 @@ export {
|
|
|
66
68
|
|
|
67
69
|
Page, NPage,
|
|
68
70
|
|
|
71
|
+
WheelHandler, NWheelHandler,
|
|
72
|
+
|
|
69
73
|
AnimationFrame, NAnimationFrame,
|
|
70
74
|
|
|
71
75
|
StaticTimeline, NStaticTimeline,
|
|
@@ -1,46 +1,107 @@
|
|
|
1
|
-
import { addEventListener,
|
|
2
|
-
import { SmoothScroll } from '../../components/scroll/smooth-scroll/SmoothScroll';
|
|
1
|
+
import { addEventListener, selectOne } from 'vevet-dom';
|
|
3
2
|
import { IRemovable } from '../types/general';
|
|
3
|
+
import { SmoothScroll } from '../../components/scroll/smooth-scroll/SmoothScroll';
|
|
4
|
+
import { randID } from '../common';
|
|
5
|
+
|
|
6
|
+
type Container = string | Element | SmoothScroll | Window;
|
|
7
|
+
|
|
8
|
+
interface ArgData {
|
|
9
|
+
scrollTop: number;
|
|
10
|
+
scrollLeft: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface Instance {
|
|
14
|
+
id: string;
|
|
15
|
+
container: Container;
|
|
16
|
+
callbacks: {
|
|
17
|
+
id: string;
|
|
18
|
+
callback: (
|
|
19
|
+
data: ArgData,
|
|
20
|
+
) => void;
|
|
21
|
+
}[];
|
|
22
|
+
isPassive: boolean;
|
|
23
|
+
listeners: IRemovable[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface Props {
|
|
27
|
+
container: Container;
|
|
28
|
+
callback: (data: ArgData) => void;
|
|
29
|
+
isPassive?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let instances: Instance[] = [];
|
|
4
33
|
|
|
5
34
|
/**
|
|
6
35
|
* Add OnScroll event
|
|
7
36
|
*/
|
|
8
|
-
export default function onScroll (
|
|
9
|
-
|
|
10
|
-
callback
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
export default function onScroll ({
|
|
38
|
+
container,
|
|
39
|
+
callback,
|
|
40
|
+
isPassive = false,
|
|
41
|
+
}: Props): IRemovable {
|
|
42
|
+
// check if listeners for this element already exist
|
|
43
|
+
let instance = instances.find((data) => (
|
|
44
|
+
data.container === container && data.isPassive === isPassive
|
|
45
|
+
))!;
|
|
46
|
+
const callbackId = randID('scroll-event');
|
|
47
|
+
|
|
48
|
+
// if a listener exists, we just add a new callback to its stack
|
|
49
|
+
if (instance) {
|
|
50
|
+
instance.callbacks.push({
|
|
51
|
+
id: callbackId,
|
|
52
|
+
callback,
|
|
23
53
|
});
|
|
24
54
|
} else {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
55
|
+
// otherwise we create a new instance
|
|
56
|
+
instance = {
|
|
57
|
+
id: randID('scroll-event-instance'),
|
|
58
|
+
container,
|
|
59
|
+
callbacks: [{
|
|
60
|
+
id: callbackId,
|
|
61
|
+
callback,
|
|
62
|
+
}],
|
|
63
|
+
isPassive,
|
|
64
|
+
listeners: [],
|
|
65
|
+
};
|
|
66
|
+
instances.push(instance);
|
|
67
|
+
|
|
68
|
+
// vars
|
|
69
|
+
const { listeners } = instance;
|
|
70
|
+
|
|
71
|
+
// smooth scroll events
|
|
72
|
+
if (container instanceof SmoothScroll) {
|
|
73
|
+
listeners.push(
|
|
74
|
+
container.addCallback('scroll', () => {
|
|
75
|
+
const { scrollTop, scrollLeft } = container;
|
|
76
|
+
for (let index = 0; index < instance.callbacks.length; index += 1) {
|
|
77
|
+
instance.callbacks[index].callback({
|
|
78
|
+
scrollTop,
|
|
79
|
+
scrollLeft,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}),
|
|
83
|
+
);
|
|
28
84
|
} else {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
85
|
+
// dom scroll events
|
|
86
|
+
const isWindow = container instanceof Window;
|
|
87
|
+
const domContainer = selectOne(container) as any;
|
|
32
88
|
listeners.push(addEventListener(
|
|
33
|
-
|
|
89
|
+
domContainer,
|
|
34
90
|
'scroll',
|
|
35
91
|
() => {
|
|
36
|
-
const scrollTop =
|
|
37
|
-
?
|
|
38
|
-
const scrollLeft =
|
|
39
|
-
?
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
92
|
+
const scrollTop = isWindow
|
|
93
|
+
? domContainer.pageYOffset : domContainer.scrollTop;
|
|
94
|
+
const scrollLeft = isWindow
|
|
95
|
+
? domContainer.pageXOffset : domContainer.scrollLeft;
|
|
96
|
+
for (let index = 0; index < instance.callbacks.length; index += 1) {
|
|
97
|
+
instance.callbacks[index].callback({
|
|
98
|
+
scrollTop,
|
|
99
|
+
scrollLeft,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
passive: isPassive,
|
|
44
105
|
},
|
|
45
106
|
));
|
|
46
107
|
}
|
|
@@ -48,9 +109,19 @@ export default function onScroll (
|
|
|
48
109
|
|
|
49
110
|
return {
|
|
50
111
|
remove: () => {
|
|
51
|
-
|
|
52
|
-
|
|
112
|
+
const newCallbacks = instance.callbacks.filter((item) => {
|
|
113
|
+
if (item.id !== callbackId) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
53
117
|
});
|
|
118
|
+
instance.callbacks = newCallbacks;
|
|
119
|
+
if (newCallbacks.length === 0) {
|
|
120
|
+
instance.listeners.forEach((listener) => {
|
|
121
|
+
listener.remove();
|
|
122
|
+
});
|
|
123
|
+
instances = instances.filter((item) => item.id !== instance.id);
|
|
124
|
+
}
|
|
54
125
|
},
|
|
55
126
|
};
|
|
56
127
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import boundVal from './boundVal';
|
|
2
2
|
import lerp from './lerp';
|
|
3
3
|
import scopeProgress from './scopeProgress';
|
|
4
|
+
import spreadScopeProgress from './spreadScopeProgress';
|
|
5
|
+
import wrap from './wrap';
|
|
4
6
|
|
|
5
7
|
export {
|
|
6
8
|
boundVal,
|
|
7
9
|
lerp,
|
|
8
10
|
scopeProgress,
|
|
11
|
+
spreadScopeProgress,
|
|
12
|
+
wrap,
|
|
9
13
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distribute scope progress among a certain quantity of timelines.
|
|
3
|
+
*/
|
|
4
|
+
export default function spreadScopeProgress (
|
|
5
|
+
quantity: number,
|
|
6
|
+
shift: number,
|
|
7
|
+
) {
|
|
8
|
+
const timelines: [number, number][] = [];
|
|
9
|
+
// duration for each element
|
|
10
|
+
const duration = 1 / (quantity - shift * (quantity - 1));
|
|
11
|
+
// calculate timelines
|
|
12
|
+
for (let index = 0; index < quantity; index += 1) {
|
|
13
|
+
const start = (duration * (1 - shift)) * index;
|
|
14
|
+
const end = start + duration;
|
|
15
|
+
timelines.push([start, end]);
|
|
16
|
+
}
|
|
17
|
+
return timelines;
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap values
|
|
3
|
+
*/
|
|
4
|
+
export default function wrap (
|
|
5
|
+
min: number,
|
|
6
|
+
max: number,
|
|
7
|
+
value: number,
|
|
8
|
+
) {
|
|
9
|
+
const range = max - min;
|
|
10
|
+
return conditionalReturn(value, (val) => ((range + ((val - min) % range)) % range) + min);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function conditionalReturn (
|
|
14
|
+
value: number,
|
|
15
|
+
func: (val: number) => number,
|
|
16
|
+
) {
|
|
17
|
+
return value || value === 0 ? func(value) : func;
|
|
18
|
+
}
|