Logo Cloud 04
Logo Cloud 04 é um componente de marquee para React e Tailwind CSS, da biblioteca Eldora UI, com licença MIT. Copia e cola no teu projeto.
Eldora UI
MIT
marquee
O que é
Logo Cloud 04 é um componente de marquee para React e Tailwind CSS, da biblioteca Eldora UI, com licença MIT. Copia e cola no teu projeto.
Como usar
Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.
Cinco cópias grátis por mês. Sem cartão.
Precisa de
npm i motion/react
Licença
Este componente vem de Eldora UI e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.
Logo Cloud 04
import { LogoCarousel } from "@/registry/blocks/logo-cloud-04/components/logo-cloud-04"
// ensure to make equal number of logos
export function LogoCloud04() {
return (
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
<div className="w-full max-w-sm md:max-w-3xl">
<section
id="clients"
className="mx-auto max-w-7xl px-6 text-center md:px-8"
>
<div className="py-14">
<div className="mx-auto max-w-screen-xl px-4 md:px-8">
<h2 className="text-center text-sm font-semibold text-gray-600">
TRUSTED BY TEAMS FROM AROUND THE WORLD
</h2>
<LogoCarousel columns={3} />
</div>
</div>
</section>
</div>
</div>
)
}
"use client"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { cn } from "@/lib/utils"
import { AnimatedLogoColumn, type Logo } from "./animated-logo-column"
const LOGOS: Logo[] = [
{
id: 1,
name: "Google",
src: "https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Google.svg",
},
{
id: 2,
name: "GitHub",
src: "https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/GitHub.svg",
},
{
id: 3,
name: "Amazon",
src: "https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Amazon.svg",
},
{
id: 4,
name: "Netflix",
src: "https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Netflix.svg",
},
{
id: 5,
name: "YouTube",
src: "https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/YouTube.svg",
},
{
id: 6,
name: "Instagram",
src: "https://pub-b3533f2e1c954842824758490b95c9d5.r2.dev/Instagram.svg",
},
]
const TICK_MS = 100
/**
* Deterministic distribution (no Math.random) so server and client
* render the same columns and hydration matches.
*/
function distributeLogos(logos: Logo[], columnCount: number): Logo[][] {
const result: Logo[][] = Array.from({ length: columnCount }, () => [])
logos.forEach((logo, index) => {
result[index % columnCount].push(logo)
})
const maxLength = Math.max(...result.map((col) => col.length))
result.forEach((col, colIndex) => {
while (col.length < maxLength) {
col.push(logos[(col.length * columnCount + colIndex) % logos.length])
}
})
return result
}
export type LogoCarouselVariant = "default" | "compact"
interface LogoCarouselProps {
columns?: number
logos?: Logo[]
variant?: LogoCarouselVariant
className?: string
}
export function LogoCarousel({
columns = 4,
logos: logosProp,
variant = "default",
className,
}: LogoCarouselProps) {
const logos = useMemo(() => logosProp ?? LOGOS, [logosProp])
const distribute = useCallback(
(count: number) => distributeLogos(logos, count),
[logos]
)
const [logoColumns, setLogoColumns] = useState<Logo[][]>(() =>
distributeLogos(logos, columns)
)
const [time, setTime] = useState(0)
const prevColumnsRef = useRef(columns)
useEffect(() => {
if (prevColumnsRef.current !== columns) {
prevColumnsRef.current = columns
setLogoColumns(distribute(columns))
}
}, [columns, distribute])
useEffect(() => {
const interval = setInterval(() => {
setTime((prev) => prev + TICK_MS)
}, TICK_MS)
return () => clearInterval(interval)
}, [])
return (
<div
className={cn(
"flex flex-wrap justify-center gap-6 py-8 sm:gap-8",
className
)}
>
{logoColumns.map((columnLogos, index) => (
<AnimatedLogoColumn
key={`col-${index}`}
logos={columnLogos}
columnIndex={index}
currentTime={time}
variant={variant}
/>
))}
</div>
)
}