vevet 2.0.1-dev.2 → 2.0.1-dev.23

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 (96) hide show
  1. package/build/cdn/index.js +1 -1
  2. package/build/cjs/components/canvas/Ctx2DPrerender.js +20 -2
  3. package/build/cjs/components/loading/ProgressPreloader.js +14 -2
  4. package/build/cjs/components/page/Page.js +36 -8
  5. package/build/cjs/components/scroll/plugins/SmoothScrollDragPlugin.js +40 -5
  6. package/build/cjs/components/scroll/plugins/SmoothScrollKeyboardPlugin.js +9 -0
  7. package/build/cjs/components/scroll/scrollable/ScrollView.js +80 -53
  8. package/build/cjs/components/scroll/scrollbar/Bar.js +8 -2
  9. package/build/cjs/components/scroll/smooth-scroll/SmoothScroll.js +11 -3
  10. package/build/cjs/components/text/SplitText.js +19 -3
  11. package/build/cjs/components/timeline/Timeline.js +1 -0
  12. package/build/cjs/handlers/wheel/WheelHandler.js +195 -0
  13. package/build/cjs/index.js +3 -1
  14. package/build/cjs/utils/listeners/onScroll.js +65 -25
  15. package/build/cjs/utils/math/index.js +5 -1
  16. package/build/cjs/utils/math/spreadScopeProgress.js +18 -0
  17. package/build/cjs/utils/math/wrap.js +13 -0
  18. package/build/es/app/Application.js +50 -93
  19. package/build/es/app/events/PageLoad.js +3 -7
  20. package/build/es/app/events/Viewport.js +10 -34
  21. package/build/es/base/Callbacks.js +8 -19
  22. package/build/es/base/Component.js +0 -1
  23. package/build/es/base/Module.js +41 -61
  24. package/build/es/base/MutableProp.js +10 -32
  25. package/build/es/base/Plugin.js +0 -1
  26. package/build/es/components/animation-frame/AnimationFrame.js +4 -28
  27. package/build/es/components/canvas/Ctx2D.js +21 -49
  28. package/build/es/components/canvas/Ctx2DPrerender.js +21 -7
  29. package/build/es/components/cursor/CustomCursor.js +25 -58
  30. package/build/es/components/dragger/Dragger.js +20 -41
  31. package/build/es/components/dragger/DraggerDirection.js +1 -4
  32. package/build/es/components/loading/Preloader.js +26 -41
  33. package/build/es/components/loading/ProgressPreloader.js +31 -38
  34. package/build/es/components/page/Page.js +46 -41
  35. package/build/es/components/scroll/plugins/SmoothScrollDragPlugin.js +47 -29
  36. package/build/es/components/scroll/plugins/SmoothScrollKeyboardPlugin.js +9 -0
  37. package/build/es/components/scroll/scrollable/ScrollEventsBase.js +15 -22
  38. package/build/es/components/scroll/scrollable/ScrollView.js +74 -74
  39. package/build/es/components/scroll/scrollbar/Bar.js +43 -54
  40. package/build/es/components/scroll/scrollbar/ScrollBar.js +47 -73
  41. package/build/es/components/scroll/smooth-scroll/SmoothScroll.js +63 -135
  42. package/build/es/components/text/SplitText.js +39 -44
  43. package/build/es/components/timeline/StaticTimeline.js +11 -22
  44. package/build/es/components/timeline/Timeline.js +13 -28
  45. package/build/es/handlers/wheel/WheelHandler.js +153 -0
  46. package/build/es/index.js +2 -1
  47. package/build/es/utils/listeners/onScroll.js +64 -25
  48. package/build/es/utils/math/index.js +3 -1
  49. package/build/es/utils/math/spreadScopeProgress.js +15 -0
  50. package/build/es/utils/math/wrap.js +10 -0
  51. package/build/types/components/canvas/Ctx2DPrerender.d.ts +1 -1
  52. package/build/types/components/canvas/Ctx2DPrerender.d.ts.map +1 -1
  53. package/build/types/components/loading/ProgressPreloader.d.ts +7 -0
  54. package/build/types/components/loading/ProgressPreloader.d.ts.map +1 -1
  55. package/build/types/components/page/Page.d.ts +2 -0
  56. package/build/types/components/page/Page.d.ts.map +1 -1
  57. package/build/types/components/scroll/plugins/SmoothScrollDragPlugin.d.ts +11 -0
  58. package/build/types/components/scroll/plugins/SmoothScrollDragPlugin.d.ts.map +1 -1
  59. package/build/types/components/scroll/plugins/SmoothScrollKeyboardPlugin.d.ts.map +1 -1
  60. package/build/types/components/scroll/scrollable/ScrollView.d.ts +27 -13
  61. package/build/types/components/scroll/scrollable/ScrollView.d.ts.map +1 -1
  62. package/build/types/components/scroll/scrollbar/Bar.d.ts.map +1 -1
  63. package/build/types/components/scroll/smooth-scroll/SmoothScroll.d.ts.map +1 -1
  64. package/build/types/components/text/SplitText.d.ts +6 -0
  65. package/build/types/components/text/SplitText.d.ts.map +1 -1
  66. package/build/types/components/timeline/Timeline.d.ts.map +1 -1
  67. package/build/types/handlers/wheel/WheelHandler.d.ts +100 -0
  68. package/build/types/handlers/wheel/WheelHandler.d.ts.map +1 -0
  69. package/build/types/index.d.ts +2 -1
  70. package/build/types/index.d.ts.map +1 -1
  71. package/build/types/utils/listeners/onScroll.d.ts +13 -5
  72. package/build/types/utils/listeners/onScroll.d.ts.map +1 -1
  73. package/build/types/utils/math/index.d.ts +3 -1
  74. package/build/types/utils/math/index.d.ts.map +1 -1
  75. package/build/types/utils/math/spreadScopeProgress.d.ts +5 -0
  76. package/build/types/utils/math/spreadScopeProgress.d.ts.map +1 -0
  77. package/build/types/utils/math/wrap.d.ts +5 -0
  78. package/build/types/utils/math/wrap.d.ts.map +1 -0
  79. package/package.json +4 -3
  80. package/src/sass/components/cursor/_custom-cursor.scss +0 -1
  81. package/src/ts/components/canvas/Ctx2DPrerender.ts +23 -6
  82. package/src/ts/components/loading/ProgressPreloader.ts +21 -2
  83. package/src/ts/components/page/Page.ts +34 -8
  84. package/src/ts/components/scroll/plugins/SmoothScrollDragPlugin.ts +58 -5
  85. package/src/ts/components/scroll/plugins/SmoothScrollKeyboardPlugin.ts +12 -0
  86. package/src/ts/components/scroll/scrollable/ScrollView.ts +90 -64
  87. package/src/ts/components/scroll/scrollbar/Bar.ts +8 -2
  88. package/src/ts/components/scroll/smooth-scroll/SmoothScroll.ts +12 -3
  89. package/src/ts/components/text/SplitText.ts +27 -2
  90. package/src/ts/components/timeline/Timeline.ts +1 -0
  91. package/src/ts/handlers/wheel/WheelHandler.ts +269 -0
  92. package/src/ts/index.ts +4 -0
  93. package/src/ts/utils/listeners/onScroll.ts +105 -34
  94. package/src/ts/utils/math/index.ts +4 -0
  95. package/src/ts/utils/math/spreadScopeProgress.ts +18 -0
  96. 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(this.prop.container, (data) => {
164
- this._handleScroll(data);
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._elements.forEach((el) => {
403
- el.style.willChange = 'transform';
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
 
@@ -153,7 +160,7 @@ export class SplitText <
153
160
 
154
161
  // get initial text
155
162
  this._initHTML = this._container.innerHTML;
156
- this._initText = (this._container.innerText || 'no rendered text').trim();
163
+ this._initText = (this._container.innerText || this._container.innerHTML || 'no rendered text').trim();
157
164
  this._initText = this._initText.replace(/\s+\n/gm, '\n');
158
165
 
159
166
  // set default vars
@@ -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
 
@@ -126,6 +126,7 @@ export class Timeline <
126
126
  this._isPlaying = false;
127
127
  this._isReversed = false;
128
128
  this._isPaused = false;
129
+ this._animationFrame = undefined;
129
130
  this._animationFrameLastTime = 0;
130
131
 
131
132
  if (init) {
@@ -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, IAddEventListener, selectOne } from 'vevet-dom';
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
- selector: string | Element | SmoothScroll | Window,
10
- callback: (arg: {
11
- scrollTop: number,
12
- scrollLeft: number
13
- }) => void,
14
- ): IRemovable {
15
- const listeners: IAddEventListener[] = [];
16
-
17
- if (selector instanceof SmoothScroll) {
18
- selector.addCallback('scroll', () => {
19
- callback({
20
- scrollTop: selector.scrollTop,
21
- scrollLeft: selector.scrollLeft,
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
- let outer: Element | Window;
26
- if (typeof selector === 'string') {
27
- outer = selectOne(selector) as Element;
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
- outer = selector;
30
- }
31
- if (outer) {
85
+ // dom scroll events
86
+ const isWindow = container instanceof Window;
87
+ const domContainer = selectOne(container) as any;
32
88
  listeners.push(addEventListener(
33
- outer,
89
+ domContainer,
34
90
  'scroll',
35
91
  () => {
36
- const scrollTop = outer instanceof Window
37
- ? outer.pageYOffset : outer.scrollTop;
38
- const scrollLeft = outer instanceof Window
39
- ? outer.pageXOffset : outer.scrollLeft;
40
- callback({
41
- scrollTop,
42
- scrollLeft,
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
- listeners.forEach((listener) => {
52
- listener.remove();
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
+ }