*particle: 입자

const ctxW = ctx.canvas.width;
const ctxH = ctx.canvas.height;
const bgImage = new Image();
bgImage.src = '/winternight.jpg';
function animate() {
ctx.clearRect(0, 0, ctxW, ctxH);
ctx.drawImage(bgImage, 0, 0);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

let y = 0;
// 눈송이를 그린다.
function snow() {
ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
ctx.beginPath();
ctx.arc(100, y++, 5, 0, Math.PI * 2);
ctx.fill();
}
// 매 시간 화면을 갱신한다.
function animate() {
ctx.clearRect(0, 0, ctxW, ctxH);
ctx.drawImage(bgImage, 0, 0);
snow();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

// x 좌표를 랜덤으로 변경한다.
let x = Math.floor(Math.random() * ctxW) + 1;
let y = 0;
// 눈송이의 크기를 랜덤으로 변경한다.
const size = Math.floor(Math.random() * 3) + 1;
// 눈송이를 그린다.
function snow() {
ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
ctx.beginPath();
ctx.arc(x, y++, size, 0, Math.PI * 2);
ctx.fill();
}

const snowflakes = [];
const totalCount = 10;
/// 눈송이를 추가한다.
function addSnowflake() {
if (snowflakes.length >= totalCount) return;
// x 좌표를 랜덤으로 변경한다.
let x = Math.floor(Math.random() * ctxW) + 1;
let y = 0;
// 눈송이의 크기를 랜덤으로 변경한다.
const size = Math.floor(Math.random() * 3) + 1;
snowflakes.push({ x, y, size });
}
// 눈송이를 그린다.
function snow() {
addSnowflake();
ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
for (const [i] of snowflakes.entries()) {
ctx.beginPath();
ctx.arc(snowflakes[i].x, snowflakes[i].y++, snowflakes[i].size, 0, Math.PI * 2);
ctx.fill();
// 화면을 넘어가면 삭제한다.
if (snowflakes[i].y > ctxH) {
snowflakes.splice(i, 1);
}
}
}
// 매 시간 화면을 갱신한다.
function animate() {
ctx.clearRect(0, 0, ctxW, ctxH);
ctx.drawImage(bgImage, 0, 0);
snow();
requestAnimationFrame(animate);
}

const snowflakes = [];
/// 눈송이를 추가한다.
function addSnowflake() {
// x 좌표를 랜덤으로 변경한다.
let x = Math.floor(Math.random() * ctxW) + 1;
let y = 0;
// 눈송이의 크기를 랜덤으로 변경한다.
const size = Math.floor(Math.random() * 3) + 1;
snowflakes.push({ x, y, size });
}
// 눈송이를 그린다.
function snow() {
addSnowflake();
ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
for (const [i] of snowflakes.entries()) {
ctx.beginPath();
// 눈송이가 떨어지는 속도를 눈송이의 크기 값에 비례해서 계산
const ty = snowflakes[i].y += snowflakes[i].size * 0.5;
ctx.arc(snowflakes[i].x, ty, snowflakes[i].size * 0.5, 0, Math.PI * 2);
ctx.fill();
// 화면을 넘어가면 삭제한다.
if (snowflakes[i].y > ctxH) {
snowflakes.splice(i, 1);
}
}
}
// 눈송이의 개수를 화면에 표시한다.
function displayCount() {
ctx.fillStyle = 'white';
ctx.font = 'bold 14px Arial, sans-serif';
ctx.fillText(snowflakes.length, 10, 20);
}
// 매 시간 화면을 갱신한다.
function animate() {
ctx.clearRect(0, 0, ctxW, ctxH);
ctx.drawImage(bgImage, 0, 0);
snow();
displayCount();
requestAnimationFrame(animate);
}

const ctxW = canvas.width + 100;
const ctxH = canvas.height + 100;
const bgImage = new Image();
bgImage.src = '/winternight.jpg';
const snowflakes = [];
/// 눈송이를 추가한다.
function addSnowflake() {
// x 좌표를 랜덤으로 변경한다.
let x = Math.floor(Math.random() * ctxW) - 100;
let y = 0;
// 눈송이의 크기를 랜덤으로 변경한다.
const size = Math.floor(Math.random() * 3) + 1;
snowflakes.push({ x, y, size });
}
// 눈송이를 그린다.
function snow() {
addSnowflake();
ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
for (const [i] of snowflakes.entries()) {
ctx.beginPath();
const ty = snowflakes[i].y += snowflakes[i].size * 0.5;
ctx.arc(snowflakes[i].x, ty, snowflakes[i].size * 0.5, 0, Math.PI * 2);
ctx.fill();
// 화면을 넘어가면 삭제한다.
if (snowflakes[i].y > ctxH) {
snowflakes.splice(i, 1);
}
}
}
// 눈송이의 개수를 화면에 표시한다.
function displayCount() {
ctx.fillStyle = 'white';
ctx.font = 'bold 14px Arial, sans-serif';
ctx.fillText(snowflakes.length, 10, 20);
}
// 매 시간 화면을 갱신한다.
function animate() {
ctx.save();
ctx.clearRect(0, 0, ctxW, ctxH);
ctx.drawImage(bgImage, 0, 0);
displayCount();
// 배경을 그린 다음에 rotate()를 이용해서 눈송이만 회전한다.
ctx.rotate(-0.2);
snow();
ctx.restore();
requestAnimationFrame(animate);
}