Skip to content

canvas를 이용한 눈 애니메이션 만들기

Jin edited this page Dec 15, 2020 · 2 revisions

canvas를 이용해서 눈 애니메이션 만드는 과정을 공유하겠습니다.

처음에는 눈 객체를 만들어야 합니다.

 // initSnow() 함수는 눈을 그려주는 함수
 for (let i = 0; i < SNOW_NUM; i++) {
    initSnow();
  }
 
 // x: 눈의 x좌표
 // y: 눈의 y좌표
 // distance: 매 프레임마다 눈의 이동거리
 // randomRadius : 눈의 반지름
 // g : 눈의 그라데이션을 표현하기 위해서 설정  
 // t : 눈의 이동 방향을 눈 내리는 것처럼 표현하기 위해 설정한 매개변수 

  const x = Math.floor(Math.random() * width);
  const y = Math.floor(Math.random() * height);
  const distance = Math.floor(Math.random() * 3 + 1);
  const randomRadius = Math.floor(Math.random() * 10 + 5);
  const g = context.createRadialGradient(x, y, 0, x, y, randomRadius);
  const t = Math.random() * (Math.PI * 2);

 // g : 눈의 그라데이션 설정 
  g.addColorStop(0, 'rgba(255,255,255,1)');
  g.addColorStop(1, 'rgba(255,255,255,0)');

 // 도화지에 그릴 준비
  context.beginPath();
 // 도화지에 눈을 찍는다(도화지에 표현은 x) 
  context.moveTo(x, y);
 // 눈의 속성에 그라데이션을 적용해준다
  context.fillStyle = g;
 
 // 눈의 크기를 정해준다.
  context.arc(x, y, randomRadius, 0, Math.PI * 2, false);
 // 눈을 도화지에 칠해준다.
  context.fill();
 // snowArr는 눈 100개에 해당되는 속성을 대입(이 부분은 애니메이션 적용할 때 필요하다.)
  snowArr.push({ x, y, randomRadius, g, distance, t });
 // 객체를 생성했으면 눈을 그려준다.
 fallingSnow();
 // 눈이 그려졌을 때, 시작한다. 
 // 매 프레임마다 배경이미지와 눈 100개를 그려준다. 
 // animationId을 얻은 이유는 배경화면 드롭다운을 닫을 떄나 다른 배경화면으로 넘어갈 때, 애니메이션을 삭제하기 위함이다.
 // 삭제는 cancelAnimationFrame이라는 함수를 이용해서 제거해준다. 

animationId = requestAnimationFrame(fallingSnow);

  context.clearRect(0, 0, width, height);
  const snowImage = makeImage();
  context.drawImage(snowImage, 0, 0, width, height);
  context.fillRect(0, 0, width, height);
  context.fill();
  for (let i = 0; i < SNOW_NUM; i++) {
    const snow = snowArr[i];
    const [x, y] = calculateSnow(snow);
    moveSnow(x, y, snow.randomRadius);
  }
  // t는 각도인데 360도보다 크거나 같으면 0도 아니면 t로 설정해준다.
  // x는 Math.sin* snow.distance * 0.8만큼 이동한다.
  // y는 snow의 거리만큼 이동한다.
  snow.t = snow.t >= Math.PI * 2 ? 0 : snow.t;
  snow.x += Math.sin(snow.t) * snow.distance * 0.8;
  snow.y += snow.distance;
  // x가 도화지의 가로 길이보다 클 경우 0으로 초기화
  if (snow.x > width) {
    snow.x = 0;
    snow.distance = Math.floor(Math.random() * 3 + 1);
  }
  // 
  if (snow.y > height) {
    snow.y = 0;
    snow.distance = Math.floor(Math.random() * 3 + 1);
  }
  return [snow.x, snow.y];

개선할 부분이 너무도 많은데 남은 기간동안 개선해나갈 예정이다.

🤝 Rules

🤖 개발 진행 공유

🧑‍🏫 학습 정리

📖 Document

😄데일리 스크럼
😄일일 회의록
😄주간 회고록

🗣 피어세션

🔥 트러블 슈팅

Clone this wiki locally