Skip to content

Commit a6ad6ff

Browse files
authored
feat: add onScrollChange callback (#1040)
1 parent 587255e commit a6ad6ff

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

src/index.ts

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,20 @@ import scrollIntoView, {
77
export interface CustomEasing {
88
(t: number): number
99
}
10+
11+
type OnScrollChangeCallback = (scrollState: {
12+
target: Element
13+
elapsed: number
14+
value: number
15+
left: number
16+
top: number
17+
}) => void
18+
1019
export interface SmoothBehaviorOptions extends Options {
1120
behavior?: 'smooth'
1221
duration?: number
1322
ease?: CustomEasing
23+
onScrollChange?: OnScrollChangeCallback
1424
}
1525

1626
// Memoize so we're much more friendly to non-dom envs
@@ -32,7 +42,7 @@ type SmoothScrollAction = {
3242

3343
type Context = {
3444
scrollable: Element
35-
method: Function
45+
method: (elapsed: number, value: number, x: number, y: number) => void
3646
startTime: number
3747
startX: number
3848
startY: number
@@ -51,7 +61,7 @@ function step(context: Context) {
5161
const currentX = context.startX + (context.x - context.startX) * value
5262
const currentY = context.startY + (context.y - context.startY) * value
5363

54-
context.method(currentX, currentY)
64+
context.method(currentX, currentY, elapsed, value)
5565

5666
// scroll more if we have not reached our destination
5767
if (currentX !== context.x || currentY !== context.y) {
@@ -68,22 +78,29 @@ function smoothScroll(
6878
y: number,
6979
duration = 600,
7080
ease: CustomEasing = t => 1 + --t * t * t * t * t,
71-
cb: Function
81+
cb: Function,
82+
onScrollChange?: OnScrollChangeCallback
7283
) {
73-
let scrollable
74-
let startX
75-
let startY
76-
let method
77-
7884
// 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, ) => {
8389
// @TODO use Element.scroll if it exists, as it is potentially better performing
8490
// 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+
})
87104
}
88105

89106
// scroll looping over a frame if needed
@@ -139,7 +156,8 @@ function scroll<T>(target: Element, options?: any) {
139156
el,
140157
left: [startLeft, left],
141158
top: [startTop, top],
142-
})
159+
}),
160+
overrides.onScrollChange
143161
)
144162
}),
145163
]

0 commit comments

Comments
 (0)