여름이 시작되기도 하고 별이 가득한 밤하늘을 웹으로 나마 보고 싶어 제작해보았습니다.
JavaScript로는 오로지 별을 랜덤 한 위치에 배치시키는 작업만 해주고, 스타일은 CSS 코드로 작성하였습니다.
코드
<div class="backSky">
<svg class="sky"></svg>
<!-- <div class="sky"></div> -->
</div>
HTML 태그 구성으로는 밤하늘 배경을 만들 부모 태그와 별들을 감쌀 태그를 만들어줍니다.
저는 Circle 태그를 사용하기 위해서 SVG를 사용하였습니다. (position 속성을 이용하여 div로도 가능)
/* 배경 */
.backSky {
width: 100vw;
height: 100vh;
position: relative;
background: linear-gradient(to right, #111, #0e0f19);
overflow: hidden;
}
/* 별을 감싼 부모 */
.sky {
width: 100vw;
height: 100vw;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: moveStar 240s linear infinite;
}
/* 별 */
.sky .star {
fill: #fff;
stroke: none;
stroke-width: 0;
}
/* 별 이동효과 */
@keyframes moveStar {
from {
transform: translate(-50%, -50%) rotate(0);
}
to {
transform: translate(-50%, -50%) rotate(360deg);
}
}
- backSky ㅣ 그러데이션을 이용하여 배경을 만들어줍니다.
- sky ㅣ 가로 세로 크기가 같은 별을 감싼 요소를 정 가운데에 위치시켜줍니다.
- star ㅣ Circle의 기본 속성만 지정해주고 크기는 JS로 정할 예정입니다.
- @keyframes moveStar ㅣ가운데에 위치시킨 sky 요소를 360도 돌려서 밤하늘이 움직이는 것처럼 보여줍니다.
// 별을 추가할 요소
const $sky = document.querySelector(".sky");
// 브라우저 창의 가로, 세로 중 가장 큰 크기
const maxSize = Math.max(window.innerWidth, window.innerHeight);
// 랜덤한 X 위치 값
const getRandomX = () => Math.random() * maxSize;
// 랜덤한 Y 위치 값
const getRandomY = () => Math.random() * maxSize;
// 랜덤한 크기 (circle는 반지름이 크기)
const randomRadius = () => Math.random() * 0.7 + 0.6;
먼저 별들을 랜덤 하게 생성하게 전에, 별을 만드는데 필요한 랜덤 한 위치, 랜덤 한 크기 값을 얻을 수 있는 함수를 만들어줍니다.
const makeStars = () => {
// 임의의 값
const _size = Math.floor(maxSize / 2);
const htmlDummy = new Array(_size).fill().map((_, i) => {
return `<circle class='star'
cx=${getRandomX()}
cy=${getRandomY()}
r=${randomRadius()}
className="star" />`
}).join('');
$sky.innerHTML = htmlDummy;
}
미리 선언한 함수를 이용하여 지정 개수만큼 별을 만들어 추가시켜줍니다.
브라우저 창에 따른 변화
브라우저 창의 크기가 바뀌게 되면, 이전에 배치된 별들은 이전 위치에 그대로 고정되게 됩니다. 이를 위해서 브라우저 창의 resize 이벤트를 감지하여 새로 별들을 배치시켜주겠습니다.
// 브라우저 창의 크기에 변화가 생길 때 새로운 별 생성
window.onresize = () => {
makeStars();
}
const makeStars = () => {
// 브라우저 가장 큰 크기
const maxSize = Math.max(window.innerWidth, window.innerHeight)
// 랜덤한 X 위치 값
const getRandomX = () => Math.random() * maxSize;
// 랜덤한 Y 위치 값
const getRandomY = () => Math.random() * maxSize;
// 랜덤한 크기 (circle는 반지름이 크기)
const randomRadius = () => Math.random() * 0.7 + 0.6;
....
}
랜덤 한 값을 얻을 수 있는 함수를 makeStars 함수 안에 넣어주고 resize 이벤트를 걸어줍니다. 이럴 시 창에 변화가 생길 때마다 makeStars 함수가 실행되고, 새로운 maxSize를 구할 수 있게 됩니다.