'use client'; import * as React from 'react'; import { motion, MotionValue, useScroll, useTransform } from 'motion/react'; import { cn } from '@/utils/cn'; type StretchingGradientProps = { className?: string; gradientClassName?: string; scrollGradientClassName?: string; }; const DEFAULT_GRADIENT_CLASS_NAME = 'bg-linear-to-t from-[#F5F5F5] via-[#92AEFF] to-[#96E7F9]'; const BAR_COUNT = 27; const CENTER_INDEX = Math.floor(BAR_COUNT / 2); const BAR_WIDTH = 'clamp(56px, 4.17vw, 80px)'; const START_Y = 720; const BAR_OFFSETS = Array.from({ length: BAR_COUNT }, (_, index) => Math.round(Math.abs(index - CENTER_INDEX) * 26.7), ); export default function StretchingGradient({ className, gradientClassName = DEFAULT_GRADIENT_CLASS_NAME, scrollGradientClassName, }: StretchingGradientProps) { const containerRef = React.useRef(null); const { scrollYProgress } = useScroll({ target: containerRef, offset: ['0 0', '1 1'], }); return (
{BAR_OFFSETS.map((offset, index) => ( ))}
); } function GradientBar({ gradientClassName, scrollGradientClassName, index, finalY, progress, }: { gradientClassName: string; scrollGradientClassName?: string; index: number; finalY: number; progress: MotionValue; }) { const y = useTransform( progress, [0, 0.72, 1], [START_Y, finalY + 150, finalY], ); const scrollGradientOpacity = useTransform(progress, [0.18, 0.86], [0, 1]); const baseGradientOpacity = useTransform( scrollGradientOpacity, [0, 1], [1, 0], ); const opacity = 1 - Math.abs(index - CENTER_INDEX) * 0.006; return (