Infinite Carousel
import { Children, cloneElement, ReactNode } from 'react'
import { cn } from '@/lib/utils'
interface MarqueeProps {
className?: string
children?: ReactNode
reverseDirection?: boolean
pauseOnHover?: boolean
}
export const InfiniteCarousel = ({
className,
children,
reverseDirection,
pauseOnHover,
}: MarqueeProps) => {
return (
<div
className={cn(
'flex w-full overflow-x-hidden [--duration:20s] [--gap:3rem]',
className
)}
>
<div
className={cn(
'animate-infinite-scroll flex w-max items-stretch gap-[--gap]',
{
'[animation-direction:reverse]': reverseDirection,
'hover:[animation-play-state:paused]': pauseOnHover,
}
)}
>
{children}
{Children.map(children, (child) => cloneElement(child as any))}
</div>
</div>
)
}
tailwind.config.js
{
"module.exports": {
"theme": {
"extend": {
"keyframes": {
"infinite-scroll": {
"from": {
"transform": "translateX(0)"
},
"to": {
"transform": "translateX(calc(-50% - var(--gap)/2))"
}
}
},
"animation": {
"infinite-scroll": "infinite-scroll var(--duration) linear infinite"
}
}
}
}
}