Skip to content

Commit

Permalink
feat: provides a callback with given distance parameter for `scroll…
Browse files Browse the repository at this point in the history
…Duration` option
  • Loading branch information
wellyshen committed Jun 12, 2021
1 parent d95c698 commit b1f96f3
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/plenty-papayas-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-cool-virtual": minor
---

feat: provides a callback with given `distance` parameter for `scrollDuration` option
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,13 +408,15 @@ const scrollToOffset = () => scrollTo({ offset: 500, smooth: true });
const scrollToItem = () => scrollToItem({ index: 10, smooth: true });
```

The default easing effect is [easeInOutCubic](https://easings.net/#easeInOutCubic), and the duration is 500 milliseconds. You can easily customize your own effect as follows:
The default easing effect is [easeInOutSine](https://easings.net/#easeInOutSine), and the duration is `100ms <= distance * 0.075 <= 500ms`. You can easily customize your own effect as follows:

```js
const { scrollTo } = useVirtual({
// For 500 milliseconds (default = 500ms)
// For 500 milliseconds
scrollDuration: 500,
// Using "easeInOutBack" effect (default = easeInOutCubic), see: https://easings.net/#easeInOutBack
// Or whatever duration you want based on the scroll distance
scrollDuration: (distance) => distance * 0.05,
// Using "easeInOutBack" effect (default = easeInOutSine), see: https://easings.net/#easeInOutSine
scrollEasingFunction: (t) => {
const c1 = 1.70158;
const c2 = c1 * 1.525;
Expand Down Expand Up @@ -676,7 +678,7 @@ const Chatroom = () => {
const { outerRef, innerRef, items, scrollToItem } = useVirtual({
// Provide the number of messages
itemCount: messages.length,
// Speed up smooth scrolling
// You can speed up smooth scrolling
scrollDuration: 50,
onScroll: ({ userScroll }) => {
// If the user scrolls and isn't automatically scrolling, cancel stick to bottom
Expand Down Expand Up @@ -863,7 +865,7 @@ const List = () => {
const { outerRef, innerRef, items } = useVirtual({
itemCount: 1000,
ssrItemCount: 30, // Renders 0th - 30th items on SSR
// or
// Or
ssrItemCount: [50, 80], // Renders 50th - 80th items on SSR
});

Expand Down Expand Up @@ -952,15 +954,15 @@ An array of indexes to make certain items in the list sticky. See the [example](
#### scrollDuration
`number`
`number | (distance: number) => number`
The duration of [smooth scrolling](#smooth-scrolling), the unit is milliseconds (default = 500ms).
The duration of [smooth scrolling](#smooth-scrolling), the unit is milliseconds (default = `100ms <= distance * 0.075 <= 500ms`).
#### scrollEasingFunction
`(time: number) => number`
A function that allows us to customize the easing effect of [smooth scrolling](#smooth-scrolling) (default = [easeInOutCubic](https://easings.net/#easeInOutCubic)).
A function that allows us to customize the easing effect of [smooth scrolling](#smooth-scrolling) (default = [easeInOutSine](https://easings.net/#easeInOutSine)).
#### loadMoreCount
Expand Down Expand Up @@ -1176,7 +1178,7 @@ const List = () => {
const { outerRef, innerRef, items } = useVirtual({
itemCount: 1000,
useIsScrolling: true, // Just use it (default = false)
// or
// Or
useIsScrolling: (speed) => speed > 50, // Use it based on the scroll speed (more user friendly)
});

Expand Down
4 changes: 3 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type UseIsScrolling = boolean | ((speed: number) => boolean);

export type ItemSize = number | ((index: number, width: number) => number);

type ScrollDuration = number | ((distance: number) => number);

interface ScrollEasingFunction {
(time: number): number;
}
Expand Down Expand Up @@ -93,7 +95,7 @@ export interface Options {
overscanCount?: number;
useIsScrolling?: UseIsScrolling;
stickyIndices?: number[];
scrollDuration?: number;
scrollDuration?: ScrollDuration;
scrollEasingFunction?: ScrollEasingFunction;
loadMoreCount?: number;
isItemLoaded?: IsItemLoaded;
Expand Down
4 changes: 3 additions & 1 deletion src/types/react-cool-virtual.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ declare module "react-cool-virtual" {

export type UseIsScrolling = boolean | UseIsScrollingFunction;

export type ScrollDuration = number | ((distance: number) => number);

export interface ScrollEasingFunction {
(time: number): number;
}
Expand Down Expand Up @@ -101,7 +103,7 @@ declare module "react-cool-virtual" {
overscanCount?: number;
useIsScrolling?: UseIsScrolling;
stickyIndices?: number[];
scrollDuration?: number;
scrollDuration?: ScrollDuration;
scrollEasingFunction?: ScrollEasingFunction;
loadMoreCount?: number;
isItemLoaded?: IsItemLoaded;
Expand Down
16 changes: 10 additions & 6 deletions src/useVirtual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
SsrItemCount,
} from "./types";
import {
easeInOutCubic,
findNearestBinarySearch,
isNumber,
now,
Expand Down Expand Up @@ -59,8 +58,8 @@ export default <
overscanCount = 1,
useIsScrolling,
stickyIndices,
scrollDuration = 500,
scrollEasingFunction = easeInOutCubic,
scrollDuration = (d) => Math.min(Math.max(d * 0.075, 100), 500),
scrollEasingFunction = (t) => -(Math.cos(Math.PI * t) - 1) / 2,
loadMoreCount = 15,
isItemLoaded,
loadMore,
Expand All @@ -84,9 +83,10 @@ export default <
const userScrollRef = useRef(true);
const scrollToRafRef = useRef<number>();
const stickyIndicesRef = useRef(stickyIndices);
const durationRef = useLatest(scrollDuration);
const easingFnRef = useLatest(scrollEasingFunction);
const isItemLoadedRef = useRef(isItemLoaded);
const loadMoreRef = useLatest(loadMore);
const easingFnRef = useLatest(scrollEasingFunction);
const itemSizeRef = useLatest(itemSize);
const useIsScrollingRef = useLatest(useIsScrolling);
const onScrollRef = useLatest(onScroll);
Expand Down Expand Up @@ -205,7 +205,11 @@ export default <

const start = now();
const scroll = () => {
const time = Math.min((now() - start) / scrollDuration, 1);
let { current: duration } = durationRef;
duration = isNumber(duration)
? duration
: duration(Math.abs(offset - prevOffset));
const time = Math.min((now() - start) / duration, 1);
const easing = easingFnRef.current(time);

scrollTo(easing * (offset - prevOffset) + prevOffset);
Expand All @@ -219,7 +223,7 @@ export default <

scrollToRafRef.current = requestAnimationFrame(scroll);
},
[easingFnRef, scrollDuration, scrollTo]
[durationRef, easingFnRef, scrollTo]
);

const scrollToItem = useCallback<ScrollToItem>(
Expand Down
9 changes: 0 additions & 9 deletions src/utils/easeInOutCubic.test.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/utils/easeInOutCubic.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { default as easeInOutCubic } from "./easeInOutCubic";
export { default as findNearestBinarySearch } from "./findNearestBinarySearch";
export { default as isNumber } from "./isNumber";
export { default as now } from "./now";
Expand Down

0 comments on commit b1f96f3

Please sign in to comment.