밝을희 클태

[ JavaScript / NextJS / React ] 랜덤으로 움직이는 별들을 만들어보자 본문

JavaScript

[ JavaScript / NextJS / React ] 랜덤으로 움직이는 별들을 만들어보자

huipark 2024. 4. 23. 15:20

별들을 담을 컨테이너를 우선 만들어줘야 한다

<>
      	...
                
		<div className="background-stars" ref={starRef}></div>
                
        ...
</>

 

그러고 나서 해당 컨테이너에 원하는 만큼 별을 찍고

useEffect(() => {
	const makeStars = () => {
		const starContainer = starRef.current;
		if (starContainer) {
			starContainer.innerHTML = "";
			for (let i = 0; i < 50; i++) {
				const x: any = Math.random() * window.innerWidth;
				const y: any = Math.random() * window.innerHeight;
				const size: any = Math.random() * 13;
				const star = document.createElement("div");
				star.className = "star";
				star.style.display = "flex";
				star.style.position = "fixed";
				star.style.left = `${x}px`;
				star.style.top = `${y}px`;
				star.style.width = `${size}px`;
				star.style.height = `${size}px`;
				star.style.borderRadius = "50%";
				star.style.filter = "blur(1px)";
				starContainer.appendChild(star);
			}
		}
	};
	makeStars();
	};
}, []);

 

여기서 만약 브라우저의 크기가 변경될 때마다 새로 별들을 찍으려면

useEffect Hook 맨 밑에 아래의 코드를 넣으면 브라우저의 크기가 줄거나 늘어나면 새로 별들의 위치를 계산해서 찍을 수 있다.

		window.addEventListener("resize", makeStars);
		return () => {
			removeEventListener("resize", makeStars);
		};

 

그리고 별들을 랜덤 하게 움직이고 싶다면 아래의 코드를 반복문 안에 넣어주면 된다.

time : 3 ~ 10

moveX, moveY = -100 ~ 100

의 범위를 가진다.

const time: any = Math.random() * 11 + 3;
const moveX = Math.random() * 201 - 100;
const moveY = Math.random() * 201 - 100;
const keyframes = `
@keyframes star-move${i} {
0%, 100% { transform: translate(0px, 0px); }
50% { transform: translate(${moveX}px, ${moveY}px); }
}
`;

const styleSheet = document.styleSheets[0];
styleSheet.insertRule(keyframes, styleSheet.cssRules.length);

star.style.animation = `star-move${i} ${time}s ease infinite`;

 

위와 같은 방법으로 랜덤으로 색상을 지정해 줄 수 도 있다.

const randomColor = () => {
	return `rgb(${Math.floor(Math.random() * 256)}, ${Math.floor(
		Math.random() * 256
	)}, ${Math.floor(Math.random() * 256)})`;
};

 

전체 코드 :

useEffect(() => {
	const makeStars = () => {
		const starContainer = starRef.current;
		if (starContainer) {
			starContainer.innerHTML = "";
			for (let i = 0; i < 50; i++) {
				const x: any = Math.random() * window.innerWidth;
				const y: any = Math.random() * window.innerHeight;
				const size: any = Math.random() * 13;
				const time: any = Math.random() * 7 + 3;
				console.log(time);
				const moveX = Math.random() * 200 - 100;
				const moveY = Math.random() * 200 - 100;
				const keyframes = `
				@keyframes star-move${i} {
				  0%, 100% { transform: translate(0px, 0px); }
				  50% { transform: translate(${moveX}px, ${moveY}px); }
				}
			  `;
				const styleSheet = document.styleSheets[0];
				styleSheet.insertRule(keyframes, styleSheet.cssRules.length);
				const star = document.createElement("div");
				star.className = "star";
				star.style.display = "flex";
				star.style.position = "fixed";
				star.style.left = `${x}px`;
				star.style.top = `${y}px`;
				star.style.width = `${size}px`;
				star.style.height = `${size}px`;
				star.style.backgroundColor = randomColor();
				star.style.borderRadius = "50%";
				star.style.filter = "blur(1px)";
				star.style.animation = `star-move${i} ${time}s ease infinite`;
				star.style.zIndex = "1";
				starContainer.appendChild(star);
			}
		}
	};
	makeStars();
		window.addEventListener("resize", makeStars);
	return () => {
		removeEventListener("resize", makeStars);
	};
}, []);