@@ -7,10 +7,20 @@ import scrollIntoView, {
7
7
export interface CustomEasing {
8
8
( t : number ) : number
9
9
}
10
+
11
+ type OnScrollChangeCallback = ( scrollState : {
12
+ target : Element
13
+ elapsed : number
14
+ value : number
15
+ left : number
16
+ top : number
17
+ } ) => void
18
+
10
19
export interface SmoothBehaviorOptions extends Options {
11
20
behavior ?: 'smooth'
12
21
duration ?: number
13
22
ease ?: CustomEasing
23
+ onScrollChange ?: OnScrollChangeCallback
14
24
}
15
25
16
26
// Memoize so we're much more friendly to non-dom envs
@@ -32,7 +42,7 @@ type SmoothScrollAction = {
32
42
33
43
type Context = {
34
44
scrollable : Element
35
- method : Function
45
+ method : ( elapsed : number , value : number , x : number , y : number ) => void
36
46
startTime : number
37
47
startX : number
38
48
startY : number
@@ -51,7 +61,7 @@ function step(context: Context) {
51
61
const currentX = context . startX + ( context . x - context . startX ) * value
52
62
const currentY = context . startY + ( context . y - context . startY ) * value
53
63
54
- context . method ( currentX , currentY )
64
+ context . method ( currentX , currentY , elapsed , value )
55
65
56
66
// scroll more if we have not reached our destination
57
67
if ( currentX !== context . x || currentY !== context . y ) {
@@ -68,22 +78,29 @@ function smoothScroll(
68
78
y : number ,
69
79
duration = 600 ,
70
80
ease : CustomEasing = t => 1 + -- t * t * t * t * t ,
71
- cb : Function
81
+ cb : Function ,
82
+ onScrollChange ?: OnScrollChangeCallback
72
83
) {
73
- let scrollable
74
- let startX
75
- let startY
76
- let method
77
-
78
84
// define scroll context
79
- scrollable = el
80
- startX = el . scrollLeft
81
- startY = el . scrollTop
82
- method = ( x : number , y : number ) => {
85
+ const scrollable = el
86
+ const startX = el . scrollLeft
87
+ const startY = el . scrollTop
88
+ const method = ( x : number , y : number , elapsed : number , value : number , ) => {
83
89
// @TODO use Element.scroll if it exists, as it is potentially better performing
84
90
// use ceil to include the the fractional part of the number for the scrolling
85
- el . scrollLeft = Math . ceil ( x )
86
- el . scrollTop = Math . ceil ( y )
91
+ const left = Math . ceil ( x )
92
+ const top = Math . ceil ( y )
93
+
94
+ el . scrollLeft = left
95
+ el . scrollTop = top
96
+
97
+ onScrollChange ?.( {
98
+ target : el ,
99
+ elapsed,
100
+ value,
101
+ left,
102
+ top,
103
+ } )
87
104
}
88
105
89
106
// scroll looping over a frame if needed
@@ -139,7 +156,8 @@ function scroll<T>(target: Element, options?: any) {
139
156
el,
140
157
left : [ startLeft , left ] ,
141
158
top : [ startTop , top ] ,
142
- } )
159
+ } ) ,
160
+ overrides . onScrollChange
143
161
)
144
162
} ) ,
145
163
]
0 commit comments