1
+ "use client"
2
+
1
3
import React from 'react' ;
2
4
import { ThemeImage } from '@/components/ThemeImage'
5
+ import { useEffect , useRef } from "react"
3
6
7
+ // each of these has a png at /img/user-logos/${COMPANY}.png
4
8
const companies = [
5
9
"spacedrive" ,
6
10
"nous" ,
@@ -10,25 +14,107 @@ const companies = [
10
14
"recall"
11
15
] ;
12
16
13
- export function LogoCloud ( ) {
17
+ // interface LogoCloudProps {
18
+ // logos: string[]
19
+ // speed?: number
20
+ // height?: number
21
+ // }
22
+ export function LogoCloud ( { speed = 0.85 , height = 150 } ) {
23
+ const scrollerRef = useRef ( null )
24
+ const innerScrollerRef = useRef ( null )
25
+
26
+ useEffect ( ( ) => {
27
+ if ( ! scrollerRef . current || ! innerScrollerRef . current ) return
28
+
29
+ // Clone the content for seamless scrolling
30
+ const scrollerContent = Array . from ( innerScrollerRef . current . children )
31
+ scrollerContent . forEach ( ( item ) => {
32
+ const duplicatedItem = item . cloneNode ( true )
33
+ innerScrollerRef . current . appendChild ( duplicatedItem )
34
+ } )
35
+
36
+ // Animation function
37
+ let animationId
38
+ let startTime = null
39
+ let progress = 0
40
+
41
+ const animate = ( timestamp ) => {
42
+ if ( ! startTime ) startTime = timestamp
43
+ const elapsed = timestamp - startTime
44
+
45
+ // Calculate how much to move based on elapsed time and speed
46
+ const newProgress = ( elapsed * speed ) / 1000
47
+ const delta = newProgress - progress
48
+ progress = newProgress
49
+
50
+ // Move the scroller
51
+ if ( innerScrollerRef . current ) {
52
+ innerScrollerRef . current . style . transform = `translateX(-${ progress % 50 } %)`
53
+ }
54
+
55
+ animationId = requestAnimationFrame ( animate )
56
+ }
57
+
58
+ animationId = requestAnimationFrame ( animate )
59
+
60
+ return ( ) => {
61
+ cancelAnimationFrame ( animationId )
62
+ }
63
+ } , [ speed ] )
64
+
14
65
return (
15
- < section className = 'max-w-6xl mx-auto border-r border-t border-l border-irohGray-300 dark:border-irohGray-800 py-24 sm:py-10 md:flex' >
16
- < div className = "mx-auto max-w-2xl px-10 lg:max-w-none" >
17
- < h1 className = "text-lg font-semibold text-irohGray-600 dark:text-irohGray-200 md:mt-32" > Trusted by the world’s most innovative teams</ h1 >
18
- </ div >
19
- < div className = "mx-auto mt-10 grid grid-cols-2 md:grid-cols-3 items-start gap-x-8 gap-y-10 sm:grid-cols-3 sm:gap-x-10 lg:mx-0 lg:grid-cols-3" >
20
- { companies . map ( ( co ) => (
21
- < ThemeImage
22
- key = { co }
23
- alt = "Transistor"
24
- darkSrc = { `/img/user-logos/${ co } .png` }
25
- lightSrc = { `/img/user-logos/${ co } .png` }
26
- width = { 300 }
27
- height = { 150 }
28
- className = "col-span-2 max-h-12 w-full object-contain object-left lg:col-span-1"
29
- />
30
- ) ) }
66
+ < div >
67
+ < div className = "pl-5 md:pl-10 pt-8 lg:max-w-none" >
68
+ < h1 className = "text-lg font-medium text-irohGray-600 dark:text-irohGray-200" > Trusted by the world’s most innovative teams</ h1 >
69
+ </ div >
70
+ < div className = "relative w-full overflow-hidden py-4" >
71
+ { /* Gradient masks for fading edges */ }
72
+ < div className = "absolute left-0 top-0 z-10 h-full w-[100px] bg-gradient-to-r from-irohGray-50 dark:from-irohGray-900 to-transparent" > </ div >
73
+ < div className = "absolute right-0 top-0 z-10 h-full w-[100px] bg-gradient-to-l from-irohGray-50 dark:from-irohGray-900 to-transparent" > </ div >
74
+
75
+ { /* Scroller container */ }
76
+ < div ref = { scrollerRef } className = "flex w-full h-full overflow-hidden" >
77
+ < div ref = { innerScrollerRef } className = "flex animate-scroll whitespace-nowrap" >
78
+ { companies . map ( ( co , index ) => (
79
+ < div key = { `${ co } -${ index } ` } style = { { height, width : height * 1.4 } } className = "flex items-center justify-center px-4" >
80
+ < ThemeImage
81
+ key = { co }
82
+ alt = { `${ co } logo` }
83
+ darkSrc = { `/img/user-logos/${ co } .png` }
84
+ lightSrc = { `/img/user-logos/${ co } .png` }
85
+ width = { height * 1.4 }
86
+ height = { height }
87
+ className = "object-contain"
88
+ />
89
+ </ div >
90
+ ) ) }
91
+ </ div >
31
92
</ div >
32
- </ section >
93
+ </ div >
94
+ </ div >
33
95
)
34
96
}
97
+
98
+
99
+ // export function LogoCloud() {
100
+ // return (
101
+ // <section className='max-w-6xl mx-auto border-r border-t border-l border-irohGray-300 dark:border-irohGray-800 py-24 sm:py-10 md:flex'>
102
+ // <div className="mx-auto max-w-2xl px-10 lg:max-w-none">
103
+ // <h1 className="text-lg font-semibold text-irohGray-600 dark:text-irohGray-200 md:mt-32">Trusted by the world’s most innovative teams</h1>
104
+ // </div>
105
+ // <div className="mx-auto mt-10 grid grid-cols-2 md:grid-cols-3 items-start gap-x-8 gap-y-10 sm:grid-cols-3 sm:gap-x-10 lg:mx-0 lg:grid-cols-3">
106
+ // {companies.map((co)=> (
107
+ // <ThemeImage
108
+ // key={co}
109
+ // alt="Transistor"
110
+ // darkSrc={`/img/user-logos/${co}.png`}
111
+ // lightSrc={`/img/user-logos/${co}.png`}
112
+ // width={300}
113
+ // height={150}
114
+ // className="col-span-2 max-h-12 w-full object-contain object-left lg:col-span-1"
115
+ // />
116
+ // ))}
117
+ // </div>
118
+ // </section>
119
+ // )
120
+ // }
0 commit comments