

const STAR_COUNT = 2500;
let stars = [];
class Star {
constructor(initialAngle) {
// ๊ฐ ๋ณ๋ง๋ค ๋ค๋ฅธ ๊ธฐ๋ณธ ๊ถค๋ ๋ฐ๊ฒฝ
this.baseR = random(130, 800);
this.r = this.baseR;
// ๊ฐ ๋ณ๋ง๋ค ๋ค๋ฅธ ์ด๊ธฐ ๊ฐ์๋
this.baseOmega = random(0.002, 0.006);
this.omega = this.baseOmega;
// ํ์ ์ํ
this.angle = initialAngle;
// ์๊ฐ์ ํฌ๊ธฐ (์ง๋๊ณผ ๋ถ๋ฆฌ)
this.size = random(2, 5);
// ๊ฐ์ด๋๋ ์์ (m ์ ๊ฑฐ๋ ํํ)
this.angularMomentum = this.r * this.r * this.omega;
// ์ต์ ์ ๊ทผ ๋ฐ์ง๋ฆ (์ฌ๊ฑด์ ์งํ์ ๋๋)
this.minR = 10;
}
update() {
// ๋ง์ฐ์ค ์
๋ ฅ์ ๋ฐ๋ฅธ ๋ฐ์ง๋ฆ ๋ณํ
if (mouseIsPressed) {
this.r -= random(1.5, 2.5);
this.r = max(this.r, this.minR);
} else {
this.r += random(1.5, 5.5);
this.r = min(this.r, this.baseR);
}
// ๊ฐ์ด๋๋ ๋ณด์กด
this.omega = this.angularMomentum / (this.r * this.r);
// ๊ฐ๋ ์
๋ฐ์ดํธ
this.angle += this.omega;
}
draw() {
let x = cos(this.angle) * this.r;
let y = sin(this.angle) * this.r;
noStroke();
fill(0);
ellipse(x, y, this.size, this.size);
}
}
function setup() {
createCanvas(windowWidth, windowHeight);
// ์คํ๋ง๋ค ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ํ ๊ฒฝ์ฐ seed ๊ณ ์ ํ์ง ์์
for (let i = 0; i < STAR_COUNT; i++) {
let angle = random(TWO_PI);
stars.push(new Star(angle));
}
}
function draw() {
background(230);
translate(width / 2, height / 2);
// ์ค์ฌ ๋ธ๋ํ
noStroke();
fill(0);
ellipse(0, 0, 24, 24);
// ๋ณ ์
๋ฐ์ดํธ ๋ฐ ๋ ๋๋ง
for (let star of stars) {
star.update();
star.draw();
}
}
const STAR_COUNT = 2500;
let stars = [];
let spacePressed = false;
class Star {
constructor(initialAngle) {
this.baseR = Math.random() * 670 + 130;
this.r = this.baseR;
this.baseOmega = Math.random() * 0.004 + 0.002;
this.omega = this.baseOmega;
// ํ์ ์ ์ํ ๋ฒกํฐ
this.cosAngle = Math.cos(initialAngle);
this.sinAngle = Math.sin(initialAngle);
this.size = Math.random() * 3 + 2;
this.angularMomentum = this.r * this.r * this.omega;
this.minR = 10;
// ์ ๋๋ฉ์ด์
์งํ๋ (0.0 ~ 1.0)
this.progress = 0.0;
// ์ ๋๋ฉ์ด์
์๋
this.animSpeed = Math.random() * 0.003 + 0.002;
}
// ease-in-out ํจ์ (smoothstep)
easeInOut(t) {
return t * t * (3.0 - 2.0 * t);
}
update() {
// progress ์
๋ฐ์ดํธ
if (spacePressed) {
this.progress += this.animSpeed;
if (this.progress > 1.0) this.progress = 1.0;
} else {
this.progress -= this.animSpeed;
if (this.progress < 0.0) this.progress = 0.0;
}
// ease-in-out ์ ์ฉ
const easedProgress = this.easeInOut(this.progress);
// ๋ฐ์ง๋ฆ ๋ณด๊ฐ
this.r = this.baseR - (this.baseR - this.minR) * easedProgress;
// ๊ฐ์ด๋๋ ๋ณด์กด
const rSquared = this.r * this.r;
this.omega = this.angularMomentum / rSquared;
// ์ฆ๋ถ ํ์
const cosOmega = Math.cos(this.omega);
const sinOmega = Math.sin(this.omega);
const newCos = this.cosAngle * cosOmega - this.sinAngle * sinOmega;
const newSin = this.sinAngle * cosOmega + this.cosAngle * sinOmega;
this.cosAngle = newCos;
this.sinAngle = newSin;
}
draw() {
const x = this.cosAngle * this.r;
const y = this.sinAngle * this.r;
noStroke();
fill(0);
ellipse(x, y, this.size, this.size);
}
}
function setup() {
createCanvas(windowWidth, windowHeight);
const twoPI = 6.28;
for (let i = 0; i < STAR_COUNT; i++) {
const angle = Math.random() * twoPI;
stars.push(new Star(angle));
}
}
function draw() {
background(230);
translate(width / 2, height / 2);
noStroke();
fill(0);
ellipse(0, 0, 24, 24);
for (let i = 0; i < STAR_COUNT; i++) {
stars[i].update();
stars[i].draw();
}
}
function keyPressed() {
if (key === " ") {
spacePressed = true;
}
}
function keyReleased() {
if (key === " ") {
spacePressed = false;
}
}
์ผ๊ฐํจ์ ๊ณ์ฐ ๊ฐ์ํ
cos()/sin() ๋์ ์ฆ๋ถ ํ์ ๋ฐฉ์ ์ฌ์ฉ์ํ ์์ ๋ฏธ๋ฆฌ ๊ณ์ฐ
TWO_PI ์์๋ฅผ ์ด๊ธฐํ ์ ํ ๋ฒ๋ง ์ฌ์ฉ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ต์ ํ
๋ถํ์ํ ํจ์ ํธ์ถ ์ ๊ฑฐ
random() ํธ์ถ์ ๊ณ ์ ๊ฐ์ผ๋ก ๋์ฒด ๊ฐ๋ฅํ ๋ถ๋ถ ๊ฐ์ max()/min() ๋์ ์กฐ๊ฑด๋ฌธ ์ฌ์ฉrandom() ํธ์ถ์ ์์ฑ์์์๋ง ์ฌ์ฉ