"use client" import { cx } from "class-variance-authority" import { useEffect, useRef, useState } from "react" import styles from "./marqueeText.module.css" interface MarqueeTextProps extends React.PropsWithChildren> { backgroundColor: string textWrapperClassName?: string } export function MarqueeText({ backgroundColor, children, className, textWrapperClassName, ...props }: MarqueeTextProps) { const textContainerRef = useRef(null) const [dimensions, setDimensions] = useState({ containerWidth: 0, contentWidth: 0, isOverflowing: false, }) useEffect(() => { const element = textContainerRef.current const parentElement = element?.parentElement if (!parentElement) { return } const resizeObserver = new ResizeObserver(() => { const containerWidth = element.clientWidth const contentWidth = element.scrollWidth const isOverflowing = contentWidth > containerWidth setDimensions({ containerWidth, contentWidth, isOverflowing, }) if (isOverflowing && containerWidth > 0) { const scrollDistance = contentWidth - containerWidth parentElement.style.setProperty( "--scroll-distance", `${scrollDistance}px` ) // Calculate dynamic animation duration based on scroll distance // This is done to avoid long scrolling durations for small distances and vice versa // Base formula: minimum 2s, add 50ms per pixel of scroll distance const baseDuration = 2 const durationPerPixel = 0.05 const calculatedDuration = Math.max( baseDuration, baseDuration + scrollDistance * durationPerPixel ) parentElement.style.setProperty( "--animation-duration", `${calculatedDuration}s` ) } }) resizeObserver.observe(element) return () => resizeObserver.disconnect() }, []) return (
{children}
) }