"use client"; import { cn } from "@/lib/utils"; import React, { useEffect, useState, useRef } from "react"; interface ShootingStar { id: number; x: number; y: number; angle: number; scale: number; speed: number; distance: number; } interface ShootingStarsProps { minSpeed?: number; maxSpeed?: number; minDelay?: number; maxDelay?: number; starColor?: string; trailColor?: string; starWidth?: number; starHeight?: number; className?: string; } const getRandomStartPoint = () => { const side = Math.floor(Math.random() * 4); const offset = Math.random() * window.innerWidth; switch (side) { case 0: return { x: offset, y: 0, angle: 45 }; case 1: return { x: window.innerWidth, y: offset, angle: 135 }; case 2: return { x: offset, y: window.innerHeight, angle: 225 }; case 3: return { x: 0, y: offset, angle: 315 }; default: return { x: 0, y: 0, angle: 45 }; } }; export const ShootingStars: React.FC = ({ minSpeed = 10, maxSpeed = 30, minDelay = 1200, maxDelay = 4200, starColor = "#9E00FF", trailColor = "#2EB9DF", starWidth = 10, starHeight = 1, className, }) => { const [star, setStar] = useState(null); const svgRef = useRef(null); useEffect(() => { const createStar = () => { const { x, y, angle } = getRandomStartPoint(); const newStar: ShootingStar = { id: Date.now(), x, y, angle, scale: 1, speed: Math.random() * (maxSpeed - minSpeed) + minSpeed, distance: 0, }; setStar(newStar); const randomDelay = Math.random() * (maxDelay - minDelay) + minDelay; setTimeout(createStar, randomDelay); }; createStar(); return () => {}; }, [minSpeed, maxSpeed, minDelay, maxDelay]); useEffect(() => { const moveStar = () => { if (star) { setStar((prevStar) => { if (!prevStar) return null; const newX = prevStar.x + prevStar.speed * Math.cos((prevStar.angle * Math.PI) / 180); const newY = prevStar.y + prevStar.speed * Math.sin((prevStar.angle * Math.PI) / 180); const newDistance = prevStar.distance + prevStar.speed; const newScale = 1 + newDistance / 100; if ( newX < -20 || newX > window.innerWidth + 20 || newY < -20 || newY > window.innerHeight + 20 ) { return null; } return { ...prevStar, x: newX, y: newY, distance: newDistance, scale: newScale, }; }); } }; const animationFrame = requestAnimationFrame(moveStar); return () => cancelAnimationFrame(animationFrame); }, [star]); return ( {star && ( )} ); };