-
Notifications
You must be signed in to change notification settings - Fork 185
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
97 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { CSSProperties, ReactElement, useEffect, useState } from 'react' | ||
Check warning on line 1 in src/components/stateless/SparklesText/index.jsx GitHub Actions / Qodana for JSUnused import
Check warning on line 1 in src/components/stateless/SparklesText/index.jsx GitHub Actions / Qodana for JSUnused import
|
||
import { motion } from 'motion/react' | ||
import clsx from 'clsx' | ||
|
||
const SparklesText = ({ | ||
text, | ||
colors = { first: '#9E7AFF', second: '#FE8BBB' }, | ||
className, | ||
sparklesCount = 10, | ||
...props | ||
}) => { | ||
const [sparkles, setSparkles] = useState([]) | ||
|
||
useEffect(() => { | ||
const generateStar = () => { | ||
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 ( | ||
<div | ||
className={clsx('text', className)} | ||
{...props} | ||
style={{ | ||
'--sparkles-first-color': `${colors.first}`, | ||
'--sparkles-second-color': `${colors.second}`, | ||
}} | ||
> | ||
<span className="relative inline-block"> | ||
{sparkles.map((sparkle) => ( | ||
<Sparkle key={sparkle.id} {...sparkle} /> | ||
))} | ||
<i>{text}</i> | ||
</span> | ||
</div> | ||
) | ||
} | ||
|
||
const Sparkle = ({ id, x, y, color, delay, scale }) => { | ||
return ( | ||
<motion.svg | ||
key={id} | ||
className="absolute z-20 pointer-events-none" | ||
initial={{ opacity: 0, left: x, top: y }} | ||
animate={{ | ||
opacity: [0, 1, 0], | ||
scale: [0, scale, 0], | ||
rotate: [75, 120, 150], | ||
}} | ||
transition={{ duration: 0.8, repeat: Infinity, delay }} | ||
width="21" | ||
height="21" | ||
viewBox="0 0 21 21" | ||
> | ||
<path | ||
d="M9.82531 0.843845C10.0553 0.215178 10.9446 0.215178 11.1746 0.843845L11.8618 2.72026C12.4006 4.19229 12.3916 6.39157 13.5 7.5C14.6084 8.60843 16.8077 8.59935 18.2797 9.13822L20.1561 9.82534C20.7858 10.0553 20.7858 10.9447 20.1561 11.1747L18.2797 11.8618C16.8077 12.4007 14.6084 12.3916 13.5 13.5C12.3916 14.6084 12.4006 16.8077 11.8618 18.2798L11.1746 20.1562C10.9446 20.7858 10.0553 20.7858 9.82531 20.1562L9.13819 18.2798C8.59932 16.8077 8.60843 14.6084 7.5 13.5C6.39157 12.3916 4.19225 12.4007 2.72023 11.8618L0.843814 11.1747C0.215148 10.9447 0.215148 10.0553 0.843814 9.82534L2.72023 9.13822C4.19225 8.59935 6.39157 8.60843 7.5 7.5C8.60843 6.39157 8.59932 4.19229 9.13819 2.72026L9.82531 0.843845Z" | ||
fill={color} | ||
/> | ||
</motion.svg> | ||
) | ||
} | ||
|
||
export default SparklesText |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters