"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 4000ms, add 60ms per pixel of scroll distance. The duration // includes start and end pauses. const baseDuration = 4000 const durationPerPixel = 60 const calculatedDuration = baseDuration + scrollDistance * durationPerPixel parentElement.style.setProperty( "--animation-duration", `${calculatedDuration}ms` ) } }) resizeObserver.observe(element) return () => resizeObserver.disconnect() }, []) return (
{children}
) }