74 lines
1.7 KiB
TypeScript
74 lines
1.7 KiB
TypeScript
"use client"
|
|
|
|
import type React from "react"
|
|
|
|
import { useEffect, useRef, useState } from "react"
|
|
|
|
interface VoidCanvasProps {
|
|
children: React.ReactNode
|
|
}
|
|
|
|
export default function VoidCanvas({ children }: VoidCanvasProps) {
|
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
const [mounted, setMounted] = useState(false)
|
|
|
|
useEffect(() => {
|
|
setMounted(true)
|
|
|
|
// Create starry background effect
|
|
const container = containerRef.current
|
|
if (!container) return
|
|
|
|
const createStar = () => {
|
|
const star = document.createElement("div")
|
|
star.className = "absolute rounded-full bg-white opacity-70"
|
|
|
|
// Random size between 1-3px
|
|
const size = Math.random() * 2 + 1
|
|
star.style.width = `${size}px`
|
|
star.style.height = `${size}px`
|
|
|
|
// Random position
|
|
star.style.left = `${Math.random() * 100}%`
|
|
star.style.top = `${Math.random() * 100}%`
|
|
|
|
// Random twinkle animation
|
|
star.style.animation = `twinkle ${Math.random() * 5 + 3}s infinite`
|
|
|
|
container.appendChild(star)
|
|
|
|
// Remove after some time to prevent too many stars
|
|
setTimeout(() => {
|
|
container.removeChild(star)
|
|
}, 8000)
|
|
}
|
|
|
|
// Create initial stars
|
|
for (let i = 0; i < 50; i++) {
|
|
createStar()
|
|
}
|
|
|
|
// Add new stars periodically
|
|
const interval = setInterval(() => {
|
|
createStar()
|
|
}, 300)
|
|
|
|
return () => {
|
|
clearInterval(interval)
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<div ref={containerRef} className="absolute inset-0 bg-black overflow-hidden">
|
|
<style jsx global>{`
|
|
@keyframes twinkle {
|
|
0%, 100% { opacity: 0.3; }
|
|
50% { opacity: 0.8; }
|
|
}
|
|
`}</style>
|
|
|
|
{mounted && children}
|
|
</div>
|
|
)
|
|
}
|