initial dev
This commit is contained in:
100
src/pages/home/components/ScrollLockedSection.tsx
Normal file
100
src/pages/home/components/ScrollLockedSection.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { motion, useScroll, useSpring, useTransform, useMotionValueEvent } from 'framer-motion';
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
type ScrollLockedSectionProps = {
|
||||
id: string;
|
||||
eyebrow: string;
|
||||
title: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export const ScrollLockedSection = ({
|
||||
id,
|
||||
eyebrow,
|
||||
title,
|
||||
description,
|
||||
}: ScrollLockedSectionProps) => {
|
||||
const sectionRef = useRef<HTMLElement | null>(null);
|
||||
const { scrollYProgress } = useScroll({
|
||||
target: sectionRef,
|
||||
offset: ['start start', 'end end'],
|
||||
});
|
||||
const smoothProgress = useSpring(scrollYProgress, { stiffness: 120, damping: 30, mass: 0.4 });
|
||||
const cardFillWidth = useTransform(smoothProgress, [0, 1], ['12%', '100%']);
|
||||
const cardFillOpacity = useTransform(smoothProgress, [0, 1], [0.25, 0.85]);
|
||||
const barScale = useTransform(smoothProgress, [0, 1], [0.3, 1]);
|
||||
const [percent, setPercent] = useState(0);
|
||||
|
||||
useMotionValueEvent(smoothProgress, 'change', (value) => {
|
||||
setPercent(Math.round(value * 100));
|
||||
});
|
||||
|
||||
return (
|
||||
<section id={id} ref={sectionRef} className="relative h-[200vh] snap-start">
|
||||
<div className="sticky top-0 flex h-screen flex-col">
|
||||
<div className="mx-auto flex h-full w-full max-w-7xl flex-col justify-between px-6 py-24 sm:px-10 lg:px-20">
|
||||
<div className="space-y-4">
|
||||
<span className="text-xs font-semibold uppercase tracking-[0.45em] text-ink/50">
|
||||
{eyebrow}
|
||||
</span>
|
||||
<div className="max-w-3xl space-y-4">
|
||||
<h2 className="text-3xl font-medium leading-tight text-ink sm:text-4xl md:text-5xl">
|
||||
{title}
|
||||
</h2>
|
||||
<p className="text-lg text-ink/75">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 flex flex-1 flex-col justify-end">
|
||||
<div className="space-y-8 rounded-3xl border border-ink/10 bg-white/60 p-8 shadow-[0_22px_48px_-32px_rgba(0,0,0,0.28)] backdrop-blur">
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-sm font-semibold uppercase tracking-[0.35em] text-ink/60">
|
||||
Animation Placeholder
|
||||
</p>
|
||||
<motion.span
|
||||
className="text-xs font-medium uppercase tracking-[0.35em] text-ink/50"
|
||||
style={{ opacity: smoothProgress }}
|
||||
>
|
||||
{percent}%
|
||||
</motion.span>
|
||||
</div>
|
||||
<div className="h-1.5 w-full overflow-hidden rounded-full bg-ink/10">
|
||||
<motion.div
|
||||
className="h-full origin-left rounded-full bg-ink"
|
||||
style={{ scaleX: smoothProgress }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative h-56 w-full overflow-hidden rounded-2xl border border-ink/10 bg-mist/70">
|
||||
<div className="absolute inset-0 grid grid-cols-12 gap-2 px-8 py-10">
|
||||
{Array.from({ length: 12 }).map((_, index) => (
|
||||
<motion.span
|
||||
key={index}
|
||||
className="flex h-full w-full origin-bottom items-end justify-center rounded-full bg-ink/15"
|
||||
style={{ opacity: cardFillOpacity, scaleY: barScale }}
|
||||
>
|
||||
<span className="sr-only">Placeholder animation bar</span>
|
||||
</motion.span>
|
||||
))}
|
||||
</div>
|
||||
<div className="absolute bottom-8 left-1/2 flex w-11/12 -translate-x-1/2 items-center gap-3">
|
||||
<div className="h-1 w-full rounded-full bg-ink/10">
|
||||
<motion.div
|
||||
className="h-full rounded-full bg-ink"
|
||||
style={{ width: cardFillWidth, opacity: cardFillOpacity }}
|
||||
/>
|
||||
</div>
|
||||
<motion.span className="text-[10px] font-semibold uppercase tracking-[0.3em] text-ink/50">
|
||||
{percent}%
|
||||
</motion.span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user