Skip to content

Commit 92e9c46

Browse files
committed
implement IntersectionObserverReveal component and integrate it with ValuesMarquee for lazy loading on the page
1 parent f974c63 commit 92e9c46

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

app/[locale]/page.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import Twitter from "@/components/icons/twitter.svg"
3535
import Whitepaper from "@/components/icons/whitepaper.svg"
3636
import { Image } from "@/components/Image"
3737
import CardImage from "@/components/Image/CardImage"
38+
import IntersectionObserverReveal from "@/components/IntersectionObserverReveal"
3839
import MainArticle from "@/components/MainArticle"
3940
import { ButtonLink } from "@/components/ui/buttons/Button"
4041
import SvgButtonLink, {
@@ -649,14 +650,16 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
649650
</SectionContent>
650651

651652
{/* dynamic / lazy loaded */}
652-
<ValuesMarquee
653-
pairings={valuesPairings}
654-
eventCategory={eventCategory}
655-
categoryLabels={{
656-
ethereum: tCommon("ethereum"),
657-
legacy: t("page-index-values-legacy"),
658-
}}
659-
/>
653+
<IntersectionObserverReveal rootMargin="-50% 0px 0px 0px">
654+
<ValuesMarquee
655+
pairings={valuesPairings}
656+
eventCategory={eventCategory}
657+
categoryLabels={{
658+
ethereum: tCommon("ethereum"),
659+
legacy: t("page-index-values-legacy"),
660+
}}
661+
/>
662+
</IntersectionObserverReveal>
660663
</Section>
661664

662665
{/* Builders - Blockchain's biggest builder community */}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"use client"
2+
3+
import { ReactNode, useState } from "react"
4+
import { useIntersectionObserver } from "usehooks-ts"
5+
6+
import { cn } from "@/lib/utils/cn"
7+
8+
interface IntersectionObserverRevealProps {
9+
children: ReactNode
10+
threshold?: number
11+
className?: string
12+
rootMargin?: string
13+
}
14+
15+
const IntersectionObserverReveal = ({
16+
children,
17+
threshold = 0,
18+
className,
19+
rootMargin,
20+
}: IntersectionObserverRevealProps) => {
21+
const { ref, isIntersecting } = useIntersectionObserver({
22+
threshold,
23+
root: null,
24+
rootMargin,
25+
})
26+
27+
// once the element is visible, set a flag to prevent the element from being hidden again
28+
const [hasBeenVisible, setHasBeenVisible] = useState(false)
29+
30+
if (isIntersecting && !hasBeenVisible) {
31+
setHasBeenVisible(true)
32+
}
33+
34+
return (
35+
<div ref={ref} className={cn("w-full", className)}>
36+
{(isIntersecting || hasBeenVisible) && (
37+
<div
38+
className={cn(
39+
"transition-opacity duration-700",
40+
isIntersecting || hasBeenVisible ? "opacity-100" : "opacity-0"
41+
)}
42+
>
43+
{children}
44+
</div>
45+
)}
46+
</div>
47+
)
48+
}
49+
50+
export default IntersectionObserverReveal

0 commit comments

Comments
 (0)