
Web Animation Api로 groupEffect를 사용하여 날라오는 3D로 날라오는 별들 star field를 구현해보자.

클릭하면 animation이 일시정지되고 다시 클릭하면 곧이어 animation이 다시 실행된다.
이번 animation을 구현하기위해 04.html과 Star.js 두파일이 사용되었다.
04.html<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Starfield</title>
<style>
body {
overflow: hidden;
background-color: black;
}
.star {
position: absolute;
width: 3px;
height: 3px;
font-size: 0;
border-radius: 50%;
background: white;
}
</style>
</head>
어두운 우주에 흰색 별이 날라오는 것처럼 구현하기위해 body전제는 background-color를 블랙으로 줬고 star는 흰색을 주었다. body부분의 코드는 아래와같다.
<body>
<!-- groupEffect를 사용하기위해 가져온 cdn-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/web-animations/2.3.2/web-animations-next.min.js"></script>
<script type="module">
import Star from "./Star.js";
// 날라가는 별이 200개
const numberOfStars = 200;
const effects = [];
// 3D효과로보이기위해 x,y,z값이 필요하다.
let x, y, z;
// Z좌표값이 비율로 적용되게끔하기위해
let scale;
let keyframes, options;
let star;
let pointFrom, pointTo;
let width = window.innerWidth;
let height = window.innerHeight;
const zModifier = height;
function set3DPoint(ax, y, z) {
const scale = zModifier / (zModifier + z);
const x2D = x * scale + width * 0.5;
const y2D = y * scale + height * 0.5;
return [x2D, y2D, scale];
}
for (let i = 0; i < numberOfStars; i++) {
x = Math.random() * width - width * 0.5;
y = Math.random() * height - height * 0.5;
z = Math.random() * zModifier;
scale = zModifier / (zModifier + z);
// 애니메이션에서 from에 해당되는 변수(시작점)
pointFrom = set3DPoint(x, y, z);
// 애니메이션에서 to에 해당되는 변수(도착점)
// zModifier을 빼준이유가 z값의 차를 만들기위함이다.
pointTo = set3DPoint(x, y, z - zModifier);
star = new Star(i);
keyframes = [
{
transform: `
translate(${pointFrom[0]}px, ${pointFrom[1]}px)
scale(${pointFrom[2]})
`,
},
{
transform: `
translate(${pointTo[0]}px, ${pointTo[1]}px)
scale(${pointTo[2]})
`,
},
];
options = {
// 속도조정 분자값이 클수록 별이 천천히 움직임
duration: 500 / scale,
iterations: Infinity,
fill: "both",
easing: "linear",
};
effects.push(new KeyframeEffect(star.element, keyframes, options));
}
const groupEffect = new GroupEffect(effects);
const animation = document.timeline.play(groupEffect);
console.log(animation);
// 창을 클릭하면 ani가 멈췄다가 다시클릭하면 그대로 다시 시작하도록하는 이벤트
window.addEventListener("click", () => {
if (animation.playState === "paused") {
animation.play();
} else {
animation.pause();
}
});
</script>
</body>
- Star파일을 따로 스크립트로 만들어서 임포트하기 위해
- 모듈타입으로 스크립트를 만들었을 때 변수를 선언하면 자체적으로 스코프가 되서 접근이 불가하다.
(원래 자바스크립트에서는 전역변수를 사용하지 않는 것이 좋다.)
Star.jsexport default class Star {
constructor(num) {
this.element = document.createElement("div");
this.element.classList.add("star");
this.element.innerHTML = num;
document.body.append(this.element);
}
}