'use client'
import { motion } from 'framer-motion'
import type { CSSProperties, ReactElement } from 'react'
import { useEffect, useState } from 'react'
import { ny } from '@/lib/utils'
interface Sparkle {
id: string
x: string
y: string
color: string
delay: number
scale: number
lifespan: number
}
interface SparklesTextProps {
/**
* @default
* @type ReactElement
* @description
* The component to be rendered as the text
*/
as?: ReactElement
/**
* @default ""
* @type string
* @description
* The className of the text
*/
className?: string
/**
* @required
* @type string
* @description
* The text to be displayed
*/
text: string
/**
* @default 10
* @type number
* @description
* The count of sparkles
*/
sparklesCount?: number
/**
* @default "{first: '#A07CFE', second: '#FE8FB5'}"
* @type string
* @description
* The colors of the sparkles
*/
colors?: {
first: string
second: string
}
}
const SparklesText: React.FC = ({
text,
colors = { first: '#A07CFE', second: '#FE8FB5' },
className,
sparklesCount = 10,
...props
}) => {
const [sparkles, setSparkles] = useState([])
useEffect(() => {
const generateStar = (): Sparkle => {
const starX = `${Math.random() * 100}%`
const starY = `${Math.random() * 100}%`
const color = Math.random() > 0.5 ? colors.first : colors.second
const delay = Math.random() * 2
const scale = Math.random() * 1 + 0.3
const lifespan = Math.random() * 10 + 5
const id = `${starX}-${starY}-${Date.now()}`
return { id, x: starX, y: starY, color, delay, scale, lifespan }
}
const initializeStars = () => {
const newSparkles = Array.from({ length: sparklesCount }, generateStar)
setSparkles(newSparkles)
}
const updateStars = () => {
setSparkles(currentSparkles =>
currentSparkles.map((star) => {
if (star.lifespan <= 0)
return generateStar()
else return { ...star, lifespan: star.lifespan - 0.1 }
}),
)
}
initializeStars()
const interval = setInterval(updateStars, 100)
return () => clearInterval(interval)
}, [colors.first, colors.second])
return (
{sparkles.map(sparkle => (
))}
{text}
)
}
const Sparkle: React.FC = ({ id, x, y, color, delay, scale }) => {
return (
)
}
export default SparklesText