Skip to content

Commit f35d20e

Browse files
authored
Merge pull request #70 from IRISX-AI/feat-fix/about-page-re-chore
Feat fix/about page re chore
2 parents f6142d4 + 69b6984 commit f35d20e

8 files changed

Lines changed: 1890 additions & 228 deletions

File tree

client/app/Components/UI/IrisHero.tsx

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Link from "next/link";
44
import { Command, Download, FileCode2, ArrowRight, Mic } from "lucide-react";
55
import MagneticButton from "../../utils/MagneticButton";
66
import GhostEther from "../GhostEther";
7-
import RippleGrid from "../../constants/RippleGrid";
7+
import FloatingLines from "../core/FloationgLines";
88

99
interface IrisHeroProps {
1010
heroTextRef: React.RefObject<HTMLDivElement | null>;
@@ -24,19 +24,16 @@ export default function IrisHero({
2424
className="hero-section sticky top-0 h-screen w-full flex flex-col justify-center items-center z-0 overflow-hidden bg-black"
2525
>
2626
<div className="hidden md:block w-full h-full absolute inset-0 z-0 bg-black">
27-
<RippleGrid
28-
enableRainbow={false}
29-
gridColor="#0f8218"
30-
rippleIntensity={0.05}
31-
gridSize={10}
32-
gridThickness={5}
33-
mouseInteraction={true}
34-
mouseInteractionRadius={2}
35-
opacity={0.8}
36-
fadeDistance={1.5}
37-
vignetteStrength={5}
38-
glowIntensity={0.9}
39-
gridRotation={0}
27+
<FloatingLines
28+
enabledWaves={["top", "middle", "bottom"]}
29+
lineCount={6}
30+
lineDistance={8}
31+
bendRadius={8}
32+
bendStrength={-2}
33+
interactive
34+
parallax={true}
35+
animationSpeed={1}
36+
linesGradient={["#24d307", "#144f01", "#2a8f2c"]}
4037
/>
4138
</div>
4239
<div
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
"use client";
2+
import React, { useEffect, useId, useState } from "react";
3+
import { AnimatePresence, motion } from "motion/react";
4+
import { useRef } from "react";
5+
import { SparklesCore } from "./sparkles";
6+
import { cn } from "@/app/lib/utils";
7+
8+
export const Cover = ({
9+
children,
10+
className,
11+
}: {
12+
children?: React.ReactNode;
13+
className?: string;
14+
}) => {
15+
const [hovered, setHovered] = useState(false);
16+
17+
const ref = useRef<HTMLDivElement>(null);
18+
19+
const [containerWidth, setContainerWidth] = useState(0);
20+
const [beamPositions, setBeamPositions] = useState<number[]>([]);
21+
22+
useEffect(() => {
23+
if (ref.current) {
24+
setContainerWidth(ref.current?.clientWidth ?? 0);
25+
26+
const height = ref.current?.clientHeight ?? 0;
27+
const numberOfBeams = Math.floor(height / 10); // Adjust the divisor to control the spacing
28+
const positions = Array.from(
29+
{ length: numberOfBeams },
30+
(_, i) => (i + 1) * (height / (numberOfBeams + 1)),
31+
);
32+
setBeamPositions(positions);
33+
}
34+
}, [ref.current]);
35+
36+
return (
37+
<div
38+
onMouseEnter={() => setHovered(true)}
39+
onMouseLeave={() => setHovered(false)}
40+
ref={ref}
41+
className="relative hover:bg-[#0ac529] cursor-pointer group/cover inline-block dark:bg-green-950 bg-black px-2 py-2 transition duration-200 rounded-sm"
42+
>
43+
<AnimatePresence>
44+
{hovered && (
45+
<motion.div
46+
initial={{ opacity: 0 }}
47+
animate={{ opacity: 1 }}
48+
exit={{ opacity: 0 }}
49+
transition={{
50+
opacity: {
51+
duration: 0.2,
52+
},
53+
}}
54+
className="h-full w-full overflow-hidden absolute inset-0"
55+
>
56+
<motion.div
57+
animate={{
58+
translateX: ["-50%", "0%"],
59+
}}
60+
transition={{
61+
translateX: {
62+
duration: 10,
63+
ease: "linear",
64+
repeat: Infinity,
65+
},
66+
}}
67+
className="w-[200%] h-full flex"
68+
>
69+
<SparklesCore
70+
background="transparent"
71+
minSize={0.4}
72+
maxSize={1}
73+
particleDensity={500}
74+
className="w-full h-full"
75+
particleColor="#000"
76+
/>
77+
<SparklesCore
78+
background="transparent"
79+
minSize={0.4}
80+
maxSize={1}
81+
particleDensity={500}
82+
className="w-full h-full"
83+
particleColor="#000"
84+
/>
85+
</motion.div>
86+
</motion.div>
87+
)}
88+
</AnimatePresence>
89+
{beamPositions.map((position, index) => (
90+
<Beam
91+
key={index}
92+
hovered={hovered}
93+
duration={Math.random() * 2 + 1}
94+
delay={Math.random() * 2 + 1}
95+
width={containerWidth}
96+
style={{
97+
top: `${position}px`,
98+
}}
99+
/>
100+
))}
101+
<motion.span
102+
key={String(hovered)}
103+
animate={{
104+
scale: hovered ? 0.8 : 1,
105+
x: hovered ? [0, -30, 30, -30, 30, 0] : 0,
106+
y: hovered ? [0, 30, -30, 30, -30, 0] : 0,
107+
}}
108+
exit={{
109+
filter: "none",
110+
scale: 1,
111+
x: 0,
112+
y: 0,
113+
}}
114+
transition={{
115+
duration: 0.2,
116+
x: {
117+
duration: 0.2,
118+
repeat: Infinity,
119+
repeatType: "loop",
120+
},
121+
y: {
122+
duration: 0.2,
123+
repeat: Infinity,
124+
repeatType: "loop",
125+
},
126+
scale: {
127+
duration: 0.2,
128+
},
129+
filter: {
130+
duration: 0.2,
131+
},
132+
}}
133+
className={cn(
134+
"dark:text-white inline-block text-neutral-900 relative z-20 group-hover/cover:text-black transition duration-200",
135+
className,
136+
)}
137+
>
138+
{children}
139+
</motion.span>
140+
<CircleIcon className="absolute -right-0.5 -top-0.5" />
141+
<CircleIcon className="absolute -bottom-0.5 -right-0.5" delay={0.4} />
142+
<CircleIcon className="absolute -left-0.5 -top-0.5" delay={0.8} />
143+
<CircleIcon className="absolute -bottom-0.5 -left-0.5" delay={1.6} />
144+
</div>
145+
);
146+
};
147+
148+
export const Beam = ({
149+
className,
150+
delay,
151+
duration,
152+
hovered,
153+
width = 600,
154+
...svgProps
155+
}: {
156+
className?: string;
157+
delay?: number;
158+
duration?: number;
159+
hovered?: boolean;
160+
width?: number;
161+
} & React.ComponentProps<typeof motion.svg>) => {
162+
const id = useId();
163+
164+
return (
165+
<motion.svg
166+
width={width ?? "600"}
167+
height="1"
168+
viewBox={`0 0 ${width ?? "600"} 1`}
169+
fill="none"
170+
xmlns="http://www.w3.org/2000/svg"
171+
className={cn("absolute inset-x-0 w-full", className)}
172+
{...svgProps}
173+
>
174+
<motion.path
175+
d={`M0 0.5H${width ?? "600"}`}
176+
stroke={`url(#svgGradient-${id})`}
177+
/>
178+
179+
<defs>
180+
<motion.linearGradient
181+
id={`svgGradient-${id}`}
182+
key={String(hovered)}
183+
gradientUnits="userSpaceOnUse"
184+
initial={{
185+
x1: "0%",
186+
x2: hovered ? "-10%" : "-5%",
187+
y1: 0,
188+
y2: 0,
189+
}}
190+
animate={{
191+
x1: "110%",
192+
x2: hovered ? "100%" : "105%",
193+
y1: 0,
194+
y2: 0,
195+
}}
196+
transition={{
197+
duration: hovered ? 0.5 : (duration ?? 2),
198+
ease: "linear",
199+
repeat: Infinity,
200+
delay: hovered ? Math.random() * (1 - 0.2) + 0.2 : 0,
201+
repeatDelay: hovered ? Math.random() * (2 - 1) + 1 : (delay ?? 1),
202+
}}
203+
>
204+
<stop stopColor="#2EB9DF" stopOpacity="0" />
205+
<stop stopColor="#3b82f6" />
206+
<stop offset="1" stopColor="#3b82f6" stopOpacity="0" />
207+
</motion.linearGradient>
208+
</defs>
209+
</motion.svg>
210+
);
211+
};
212+
213+
export const CircleIcon = ({
214+
className,
215+
delay,
216+
}: {
217+
className?: string;
218+
delay?: number;
219+
}) => {
220+
return (
221+
<div
222+
className={cn(
223+
`pointer-events-none animate-pulse group-hover/cover:hidden group-hover/cover:opacity-100 group h-2 w-2 rounded-full bg-neutral-600 dark:bg-black opacity-20 group-hover/cover:bg-black`,
224+
className,
225+
)}
226+
></div>
227+
);
228+
};

0 commit comments

Comments
 (0)