밝을희 클태

[ 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);
};
}, []);