Created
November 20, 2023 06:10
-
-
Save zpuckeridge/577e84edec1e58c183b82c74df8830bb to your computer and use it in GitHub Desktop.
Framer Motion Starfield w/ Fade In and Twinkling Stars
This file contains hidden or 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
| "use client"; | |
| import { useEffect, useState } from "react"; | |
| import { motion, useAnimation } from "framer-motion"; | |
| interface StarProps { | |
| x: number; | |
| y: number; | |
| size: number; | |
| } | |
| const Star: React.FC<StarProps> = ({ x, y, size }) => { | |
| const controls = useAnimation(); | |
| useEffect(() => { | |
| const animateStar = async () => { | |
| while (true) { | |
| await controls.start({ opacity: 1, y: 0 }); | |
| await controls.start({ opacity: 0.8, scale: 1.2 }); | |
| await controls.start({ opacity: 1, scale: 1 }); | |
| await controls.start({ opacity: 1, y: 0 }); | |
| // Adjust duration and delay for desired twinkling speed and randomness | |
| await new Promise((resolve) => | |
| setTimeout(resolve, Math.random() * 2000 + 500) | |
| ); | |
| } | |
| }; | |
| animateStar(); | |
| }, [controls]); | |
| return ( | |
| <motion.div | |
| animate={controls} | |
| initial={{ opacity: 0, y: -50 }} | |
| style={{ | |
| position: "absolute", | |
| left: x, | |
| top: y, | |
| width: size, | |
| height: size, | |
| borderRadius: "50%", | |
| backgroundColor: "white", | |
| }} | |
| /> | |
| ); | |
| }; | |
| const Starfield: React.FC = () => { | |
| const [windowSize, setWindowSize] = useState({ width: 0, height: 0 }); | |
| useEffect(() => { | |
| const updateWindowSize = () => { | |
| setWindowSize({ width: window.innerWidth, height: window.innerHeight }); | |
| }; | |
| // Update window size on mount and on window resize | |
| updateWindowSize(); | |
| window.addEventListener("resize", updateWindowSize); | |
| return () => { | |
| // Clean up event listener on unmount | |
| window.removeEventListener("resize", updateWindowSize); | |
| }; | |
| }, []); | |
| const numberOfStars = 500; // Increase the number of stars | |
| const stars = []; | |
| for (let i = 0; i < numberOfStars; i++) { | |
| const size = Math.random() * 3; | |
| const x = Math.random() * windowSize.width; | |
| const y = Math.random() * windowSize.height; | |
| stars.push(<Star key={i} x={x} y={y} size={size} />); | |
| } | |
| return ( | |
| <div style={{ position: "relative", width: "100vw", height: "100vh" }}> | |
| {stars} | |
| </div> | |
| ); | |
| }; | |
| export default Starfield; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment