๐ HTML Canvas๋ก GROK ์๊ฐ์ ๋ฐ์ Starfield์ Shooting Stars๋ฅผ ๋ง๋ ๋ฐฉ๋ฒ โจ
Source: Dev.to
HTML Canvas ๋ก GROK ์คํํ๋ & ์ ์ฑ ํจ๊ณผ ์ฌํํ๊ธฐ
GROKโ์คํ์ผ ์คํํ๋ ์ ๋๋ฉ์ด์ ์ ๋ณธ ์ ์ด ์๋ค๋ฉด ๊ทธ ๋ถ์๊ธฐ๋ฅผ ์ ๊ฒ๋๋ค: ๋๋ฆฌ๊ณ ์ํ ๊ฐ์ ํ์ , ์์ํ ๊น๋นก์, ๊ทธ๋ฆฌ๊ณ ๊ฐ๋์ฉ ์ง๋๊ฐ๋ ์ ์ฑ. ์ด ๊ธ์์๋ ์์ HTMLโฏ+โฏCSSโฏ+โฏJavaScript ๋ก ๊ทธ ํจ๊ณผ๋ฅผ ์ฌํํ๋ ๋ฐฉ๋ฒ์ ๋จ๊ณ๋ณ๋ก ์ดํด๋ด ๋๋ค โ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋, ํ๋ ์์ํฌ๋ ์์ด Canvas API๋ง ์ฌ์ฉํฉ๋๋ค.
๐ ์ด ํจ๊ณผ์ ํฌํจ๋ ๋ด์ฉ
- ์ ์ฒด ํ๋ฉด HTML5
<canvas> - ํ๋ฉด ๋ฐ์ ๋๋ ์๋ฐฑ ๊ฐ์ ํ์ ๋ณ
- ์์ฐ์ค๋ฌ์ด ๊น๋นก์ / ๋ฐ๊ด ์๋ฎฌ๋ ์ด์
- ๋๋ฌผ๊ฒ ๋ํ๋๋ ์ฐ์ํ ์ ์ฑ
- ๋ฐ์ํ ๋ฆฌ์ฌ์ด์ฆ ์ฒ๋ฆฌ
๋ชจ๋requestAnimationFrame์ผ๋ก ๋ถ๋๋ฝ๊ฒ ์คํ๋ฉ๋๋ค.
๐ ํ๋ก์ ํธ ๊ตฌ์กฐ
index.html โ Canvas ์ปจํ
์ด๋
style.css โ ์ ์ฒด ํ๋ฉด ๊ฒ์ ๋ฐฐ๊ฒฝ
script.js โ ์ ๋๋ฉ์ด์
๋ก์ง & ์ปค์คํฐ๋ง์ด์ง
๋น๋ ๋จ๊ณ ์์ด index.html ์ ๋ธ๋ผ์ฐ์ ์์ ์ด๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
๐งฑ HTML: ์ต์ ์บ๋ฒ์ค ์ค์
์บ๋ฒ์ค๋ ๋ทฐํฌํธ ์ ์ฒด๋ฅผ ์ฑ์ฐ๋ฉฐ, ์ฐ๋ฆฌ๊ฐ ๊ทธ๋ฆฌ๋ ๋ชจ๋ ์์์ ๋ ๋๋ง ํ๋ฉด ์ญํ ์ ํฉ๋๋ค. JavaScript ํ์ผ์ DOM์ด ์ค๋น๋ ๋ค์ ๋ก๋๋๋๋ก ํ๋จ์ ๋ฐฐ์นํ์ต๋๋ค.
๐จ CSS: ์ ์ฒด ํ๋ฉด, ๋ฐฉํด ์์ ์์
html, body {
margin: 0;
padding: 0;
background: black;
overflow: hidden;
width: 100%;
height: 100%;
}
#starfield {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
overflow: hidden์ ์คํฌ๋กค๋ฐ๊ฐ ๋ํ๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.position: fixed๋ก ์บ๋ฒ์ค๋ฅผ ํ๋ฉด์ ๊ณ ์ ํฉ๋๋ค.pointer-events: none์ UI ์์๊ฐ ์บ๋ฒ์ค ์์ ๋์ผ ์ ์๊ฒ ํฉ๋๋ค.
๐ง JavaScript: ํต์ฌ ๊ฐ๋
Canvas & Context
const canvas = document.getElementById("starfield");
const ctx = canvas.getContext("2d");
๋ชจ๋ ๊ทธ๋ฆฌ๊ธฐ๋ 2D ๋ ๋๋ง ์ปจํ ์คํธ๋ฅผ ์ฌ์ฉํด ์๋์ผ๋ก ์ํ๋ฉ๋๋ค.
โญ ๋ณ ๋ฐ์ดํฐ ๋ชจ๋ธ
๊ฐ ๋ณ์ ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ฒด๋ก ์ ์ฅ๋ฉ๋๋ค:
{
angle: Number,
radius: Number,
speed: Number,
size: Number
}
๋ณ์ ๊ทน์ขํ ๋ก ์ ์๋ฉ๋๋ค:
angleโ ํ์ ์์นradiusโ ์ค์ฌ์ผ๋ก๋ถํฐ์ ๊ฑฐ๋ฆฌ
์ด๋ ๊ฒ ํ๋ฉด ์ํ ์์ง์์ ๊ฐ๋จํ ๊ตฌํํ ์ ์์ต๋๋ค.
๐ ์บ๋ฒ์ค ๋ฆฌ์ฌ์ด์ฆ ์ฒ๋ฆฌ
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
initStars();
}
์๋์ฐ ํฌ๊ธฐ๊ฐ ๋ฐ๋ ๋๋ง๋ค:
- ์บ๋ฒ์ค ํฌ๊ธฐ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
- ์ ํฌ๊ธฐ์ ๋ง๊ฒ ๋ณ์ ๋ค์ ์์ฑํด ์ ๋ช ํ๊ณ ๋ฐ์ํ์ผ๋ก ์ ์งํฉ๋๋ค.
โจ ์คํํ๋ ์ด๊ธฐํ
const numStars = 360;
๋ณ์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ๋ฉ๋๋ค:
stars = Array.from({ length: numStars }, () => ({
angle: Math.random() * Math.PI * 2,
radius: Math.random() * Math.sqrt(canvas.width ** 2 + canvas.height ** 2),
speed: Math.random() * 0.0003 + 0.00015,
size: Math.random() * 1.2 + 0.5,
}));
- ๋ฌด์์ ๊ฐ๋๋ก ๋ณ์ ๊ณ ๋ฅด๊ฒ ๋ฐฐ์นํฉ๋๋ค.
- ํฐ ๋ฐ๊ฒฝ์ ์ฌ์ฉํด ๋ณ์ด ๋ทฐํฌํธ ๋ฐ๊น์ง ๋๊ฒ ํฉ๋๋ค.
- ์์ ๊ฐ์๋๋ก ๋๋ฆฌ๊ณ ์ํ ๊ฐ์ ์์ง์์ ๊ตฌํํฉ๋๋ค.
๐ ์ ๋๋ฉ์ด์ ๋ฃจํ
function animate() {
requestAnimationFrame(animate);
// clear, update, draw, spawn shooting stars, etc.
}
requestAnimationFrame(animate);
๊ฐ ํ๋ ์๋ง๋ค:
- ์บ๋ฒ์ค๋ฅผ ์ง์๋๋ค.
- ๋ณ ์์น๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
- ๋ณ์ ๊ทธ๋ฆฝ๋๋ค.
- ์ ์ฑ์ ์์ฑํ ์ง ํ๋จํฉ๋๋ค.
- ๊ธฐ์กด ์ ์ฑ์ ์ ๋ฐ์ดํธํฉ๋๋ค.
๐ ํ์ ๋ณ ๊ทธ๋ฆฌ๊ธฐ
star.angle += star.speed;
const x = centerX + star.radius * Math.cos(star.angle);
const y = centerY + star.radius * Math.sin(star.angle);
์ ํ์ ์ธ ์์ด๋ ์์์ ๋๋ค.
๊น๋นก์ / ๋ฐ๊ด ํจ๊ณผ
const flicker = 0.4 + Math.abs(Math.sin(Date.now() * 0.0015 + i)) * 0.5;
๋ฐ๊ธฐ๋ ๋ค์์ ํตํด ํ๋ด๋ ๋๋ค:
- ์ง๋ํ๋ ํฌ๋ช ๋.
- ๋ณ๋ง๋ค ์ฝ๊ฐ์ฉ ๋ค๋ฅธ ์์ ์คํ์ .
๋จ์ํ๋ฉด์๋ ๋น ๋ฅด๊ณ ํจ๊ณผ์ ์ ๋๋ค.
โ๏ธ ์ ์ฑ
์ ์ฑ์ ์๋์ ์ผ๋ก ๋๋ฌผ๊ฒ ๋ฑ์ฅํฉ๋๋ค:
if (shootingStars.length === 0 && Math.random() < 0.01) {
// create a new shooting star
}
ํ ๋ฒ์ ํ๋๋ง ์กด์ฌํ๋๋ก ํ์ฌ ์๊ฐ์ ํน๋ณํ๊ฒ ๋ง๋ญ๋๋ค. ๊ฐ ์ ์ฑ์ ์์น, ์๋, ์๋ช ์ ๊ฐ์ง๋๋ค.
๐ฏ ์ ์ฑ ๊ผฌ๋ฆฌ
๊ผฌ๋ฆฌ๋ ์ ํ ๊ทธ๋ผ๋์ธํธ ๋ก ๊ตฌํํฉ๋๋ค:
const grad = ctx.createLinearGradient(
s.x,
s.y,
s.x - s.vx * 35,
s.y - s.vy * 35
);
ํฌ๋ช ๋๊ฐ ๊ผฌ๋ฆฌ ์ชฝ์ผ๋ก ์ ์ ๋ฎ์์ ธ ํํฐํด ์์ด๋ ์์ฐ์ค๋ฌ์ด ์คํธ๋ฆญ ํจ๊ณผ๋ฅผ ์ค๋๋ค.
โ๏ธ ๊ฐํธํ ์ปค์คํฐ๋ง์ด์ง
๋ชจ๋ ํ๋ ์ต์
์ script.js ์ ์์ต๋๋ค.
๋ฐ๋
const numStars = 360;
๊น๋นก์ ๊ฐ๋
// base brightness
0.4
// flicker amplitude
0.5
์ ์ฑ ๋ฐ์ ๋น๋
Math.random() < 0.01
์ ์ฑ ์๋
vx: 3 + Math.random() * 2,
vy: 1 + Math.random() * 1.5
๐ก ํ์ฅ ์์ด๋์ด
- ๋ง์ฐ์ค ๊ธฐ๋ฐ ์์ฐจ ํจ๊ณผ.
- ์์์ด ๋ณํ๋ ๋ณ๋ค.
- ์๋๊ฐ ๋ค๋ฅธ ๊น์ด ๋ ์ด์ด.
- ๊ทธ๋ผ๋์ธํธ ์ฐ์ฃผ ๋ฐฐ๊ฒฝ.
- ์ฑ์ด ๋ ธ์ด์ฆ ์ค๋ฒ๋ ์ด.
๐งช ์ ์ด ์ ๊ทผ๋ฒ์ด ํจ๊ณผ์ ์ธ๊ฐ
- ์์กด์ฑ ์ ๋ก โ ์์ JavaScript์ Canvas๋ง ์ฌ์ฉ.
- ๊ทนํ ๋น ๋ฆ โ ๊ฐ๋จํ ์ํ ์ฐ์ฐ + ์บ๋ฒ์ค ๋ ๋๋ง.
- ์ด๋๋ ์ฝ๊ฒ ์ฝ์ ๊ฐ๋ฅ (๋๋ฉ ํ์ด์ง, ๋ฐฐ๊ฒฝ, ๋ฐ๋ชจ ๋ฑ).
- UI ๋ฐฐ๊ฒฝ์ฉ์ผ๋ก ์ต์ โ ์์ JS + Canvas๋ง์ผ๋ก๋ ์ผ๋ง๋ ๋ฉ์ง ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค ์ ์๋์ง ๋ณด์ฌ์ค๋๋ค.