Skip to content

Commit

Permalink
✨ : add a react-spring group tracking helper
Browse files Browse the repository at this point in the history
  • Loading branch information
hsunpei committed Nov 1, 2024
1 parent 0755e92 commit f0358ba
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 3 deletions.
41 changes: 41 additions & 0 deletions apps/docs/components/grouped/ActiveSectionInfoSpring.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useActiveSectionSpring } from '@react-scrollytelling/react-spring';
import { animated } from '@react-spring/web';

const TEXT_COLOR = {
RED: 'text-rose-500',
ORANGE: 'text-orange-500',
YELLOW: 'text-yellow-500',
GREEN: 'text-green-500',
BLUE: 'text-blue-500',
PURPLE: 'text-purple-500',
};

export const ActiveSectionInfoSpring = () => {
const { trackingId, scrolledRatioSpring } = useActiveSectionSpring();

return (
<div className="flex h-screen items-center justify-center">
<ul className="list-disc text-xl leading-9 marker:text-slate-400">
<small>
Active Section = <b>{trackingId}</b>:
</small>
<li>
You are viewing{' '}
<span className="rounded-md bg-slate-100 px-2 py-1 dark:bg-slate-800">
<b className={TEXT_COLOR[trackingId]}>{trackingId}</b>
</span>{' '}
section
<br />
</li>
<li>
Reading ratio:
<animated.b>
{scrolledRatioSpring.to((val) => {
return `${Math.round(val * 10000) / 10000}`;
})}
</animated.b>
</li>
</ul>
</div>
);
};
1 change: 0 additions & 1 deletion apps/docs/components/single/SectionScrollSpring.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export const SectionScrollSpring = ({ className }: { className: string }) => {
scrolledRatio:{' '}
<animated.span>
{scrolledRatioSpring.to((val) => {
console.log(val, Math.round(val * 10000) / 10000);
return `${Math.round(val * 10000) / 10000}`;
})}
</animated.span>
Expand Down
52 changes: 52 additions & 0 deletions apps/docs/pages/react-spring.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { TrackedSection } from '../components/grouped/TrackedSection';
import { ActiveSectionInfoSpring } from '../components/grouped/ActiveSectionInfoSpring';

import { ScrollytellingProvider } from '@react-scrollytelling/grouped';
import { StickyContainerTailwind } from '@react-scrollytelling/layout';

import {
SectionScrollSpring
} from '../components/single/SectionScrollSpring';
Expand Down Expand Up @@ -38,4 +44,50 @@ export const Section = () => {
};
```

### Example

<SectionScrollSpring className="border-green-400 dark:border-green-700 bg-green-200 dark:bg-green-800" />


## Multiple Sections

### Example

<div className="mx-2 my-12">
<ScrollytellingProvider>
<StickyContainerTailwind
overlay={
<>
<TrackedSection
sectionID="RED"
className="border-rose-400 dark:border-rose-700 bg-rose-200 dark:bg-rose-800 rounded-t-lg pt-[50vh]"
/>
<TrackedSection
sectionID="ORANGE"
className="-mt-[3px] border-orange-400 dark:border-orange-700 bg-orange-200 dark:bg-orange-800"
/>
<TrackedSection
sectionID="YELLOW"
className="-mt-[3px] border-yellow-400 dark:border-yellow-700 bg-yellow-200 dark:bg-yellow-800"
/>
<TrackedSection
sectionID="GREEN"
className="-mt-[3px] border-green-400 dark:border-green-700 bg-green-200 dark:bg-green-800"
/>
<TrackedSection
sectionID="BLUE"
className="-mt-[3px] border-blue-400 dark:border-blue-700 bg-blue-200 dark:bg-blue-800"
/>
<TrackedSection
sectionID="PURPLE"
className="-mt-[3px] border-purple-400 dark:border-purple-700 bg-purple-200 dark:bg-purple-800 rounded-b-lg pt-[10vh]"
/>
</>
}
>
{/* Background */}
<ActiveSectionInfoSpring />
</StickyContainerTailwind>
</ScrollytellingProvider>
</div>

Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export function useSectionScroll(
- `options`: Allow customizing the observer. You can pass an `IntersectionObserverOptions` [object to configure the observer](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver#instance_properties).


## Example

<SectionScroll className="border-green-400 dark:border-green-700 bg-green-200 dark:bg-green-800" />

Expand Down
2 changes: 2 additions & 0 deletions packages/react-spring/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
"vite": "^5.2.11"
},
"peerDependencies": {
"@react-scrollytelling/core": "workspace:^",
"@react-scrollytelling/grouped": "workspace:^",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-spring": "^9.7.5"
Expand Down
1 change: 1 addition & 0 deletions packages/react-spring/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './useSectionScrollSpring';
export * from './useActiveSectionSpring';
38 changes: 38 additions & 0 deletions packages/react-spring/src/hooks/useActiveSectionSpring.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useCallback, useRef, useState } from 'react';

import {
ActiveSectionScrollInfo,
useActiveSection,
ActiveSectionObserver,
} from '@react-scrollytelling/grouped';
import { SpringValue } from '@react-spring/web';

/**
* Watches for all tracked sections to find the section closet to the bottom of the viewport
* through ScrollytellingProvider.
* It invokes the onActiveSectionChange when the active section changes.
* Returns the Spring value (react-spring) of the section scroll.
* @param onActiveSectionChange - The callback needs to be memoized
* @returns The trackingId of the active section and the Spring value of the section scroll
*/
export function useActiveSectionSpring(onActiveSectionChange?: ActiveSectionObserver) {
const scrolledRatioSpringRef = useRef(new SpringValue(0));
const [trackingId, setTrackingId] = useState<string | null>(null);

const onSectionScroll = useCallback(
(scrollInfo: ActiveSectionScrollInfo) => {
const { trackingId: id, scrolledRatio } = scrollInfo;
setTrackingId(id);
scrolledRatioSpringRef.current.set(scrolledRatio);

if (onActiveSectionChange) {
onActiveSectionChange(scrollInfo);
}
},
[onActiveSectionChange]
);

useActiveSection(onSectionScroll);

return { trackingId, scrolledRatioSpring: scrolledRatioSpringRef.current };
}
3 changes: 1 addition & 2 deletions packages/react-spring/src/hooks/useSectionScrollSpring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { SpringValue } from '@react-spring/web';

/**
* Get the state of the section scroll
* Get the Spring value (react-spring) of the section scroll
* @param sectionRef - The reference to the section element
* @param shouldObserve - Whether the underlying IntersectionObserver should be active
* @param onScroll - The callback to track the scroll ratio
Expand All @@ -24,7 +24,6 @@ export function useSectionScrollSpring(
const onSectionScroll = useCallback(
(scrollInfo: SectionScrollInfo) => {
const { scrolledRatio } = scrollInfo;
console.log('onSectionScroll', scrolledRatio);
scrolledRatioSpringRef.current.set(scrolledRatio);

if (onScroll) {
Expand Down
2 changes: 2 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3660,6 +3660,8 @@ __metadata:
ts-jest: ^29.2.4
vite: ^5.2.11
peerDependencies:
"@react-scrollytelling/core": "workspace:^"
"@react-scrollytelling/grouped": "workspace:^"
react: ^18.2.0
react-dom: ^18.2.0
react-spring: ^9.7.5
Expand Down

0 comments on commit f0358ba

Please sign in to comment.