Loading component…
Components /Animated Rays
Hero with animated heading
"use client";
import { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
interface AnimatedRaysProps {
/** Additional CSS classes */
className?: string;
/** Optional children to render over the background */
children?: React.ReactNode;
}
export function AnimatedRays({
className = "",
children,
}: AnimatedRaysProps) {
const [isDark, setIsDark] = useState(false);
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
const checkDark = () => document.documentElement.classList.contains("dark");
setIsDark(checkDark());
const observer = new MutationObserver(() => setIsDark(checkDark()));
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["class"],
});
return () => observer.disconnect();
}, []);
if (!mounted) return null;
const stripes = `repeating-linear-gradient(
100deg,
var(--stripe-color) 0%,
var(--stripe-color) 7%,
transparent 10%,
transparent 12%,
var(--stripe-color) 16%
)`;
const rainbow = `repeating-linear-gradient(
100deg,
#60a5fa 10%,
#e879f9 15%,
#60a5fa 20%,
#5eead4 25%,
#60a5fa 30%
)`;
return (
<section className={cn("relative w-full h-full overflow-hidden", className)}>
{/* Aurora Background — matches original .hero */}
<div
className="absolute inset-0"
style={{
backgroundImage: `${stripes}, ${rainbow}`,
backgroundSize: "300%, 200%",
backgroundPosition: "50% 50%, 50% 50%",
filter: isDark
? "blur(10px) opacity(50%) saturate(200%)"
: "blur(10px) invert(100%)",
maskImage: "radial-gradient(ellipse at 100% 0%, black 40%, transparent 70%)",
WebkitMaskImage: "radial-gradient(ellipse at 100% 0%, black 40%, transparent 70%)",
}}
>
{/* Animated overlay — matches original .hero::after */}
<div
className="absolute inset-0 animate-aurora-bg"
style={{
backgroundImage: `${stripes}, ${rainbow}`,
backgroundSize: "200%, 100%",
backgroundAttachment: "fixed",
mixBlendMode: "difference",
}}
/>
</div>
{children && (
<div className="absolute inset-0 z-10 flex flex-col items-center justify-center">
{children}
</div>
)}
</section>
);
}
export default AnimatedRays;
Run the following command
npx shadcn@latest add https://vengeance-ui-v2.vercel.app/r/animated-rays.json1import AnimatedRays from "@/components/ui/animated-rays"23export function AnimatedRaysDemo() {4 return (5 <AnimatedRays6 headline="Build Beautiful Interfaces"7 subtext="Create stunning animations with ease"8 />9 )10}
| Prop Name | Type | Default | Description |
|---|---|---|---|
| headline | string | - | The main heading text for the hero section. |
| subtext | string | - | Secondary text displayed below the headline. |
| className | string | - | Additional CSS classes for the container. |