JavaScript

애니메이션

9tun 2025. 5. 15. 21:22

객체를 사용한 도형 생성

객체로 여러 개의 원 생성

원을 생성할 수 있는 객체를 만들고 필요한 만큼 객체 인스턴스를 만들어서 화면에 그리기

 

객체 만들기

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

/* 캔버스 너비 설정 */
canvas.width = window.innerWidth;

/* 캔버스 높이 설정 */
canvas.height = window.innerHeight;

function Circle(x, y, radius, color) {
  this.x = x;
  this.y = y;
  this.radius = radius;
  this.color = color;

  /* 원을 그리는 메서드 */
  this.draw = function() {  
    ctx.beginPath(); /* 새로운 경로 시작 */

    ctx.fillStyle = this.color; /* 채우기 색상 설정 */

	/* 원(호) 그리기: 중심(this.x, this.y), 반지름(this.radius), 시작각도 0, 끝각도 2π, 시계방향 */
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);     

    ctx.fill(); /* 설정한 색상으로 내부 채우기 */
  }
}

const circleOne = new Circle(100, 100, 50, "red");   /* 인스턴스 생성 */
const circleTwo = new Circle(200, 200, 20, "blue");  /* 인스턴스 생성 */
circleOne.draw();
circleTwo.draw();

 

이제 객체를 사용해서 원을 한... 20개 그려봅시다!

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

function Circle (x, y, radius, color){
  this.x = x;
  this.y = y;
  this.radius = radius;
  this.color = color;

  this.draw = function(){
    ctx.beginPath();
    ctx.fillStyle = this.color;
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
    ctx.fill();    
  }
}

const objs = [];  /* 인스턴스 저장 변수 */
for (let i = 0; i < 20; i++){
  const radius = Math.floor(Math.random() * 50) + 10;    /* 반지름 */
  const x = Math.random() * (canvas.width - radius * 2) + radius;  /* 원점 x 좌표 */
  const y = Math.random() * (canvas.height - radius * 2) + radius; /* 원점 y 좌표 */
  const color = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;  /* 색상 */
  objs.push(new Circle(x, y, radius, color)); /* objs에 인스턴스 추가 */
}
/* console.log(objs); */

for (let i = 0; i < 20; i++){
  objs[i].draw();
}

애니메이션 효과 추가

그래픽 요소를 움직일 때는 캔버스에 그래픽 요소를 새로 그려줘야 한다.

 

그래픽 요소 옮기기

좌표 옮기기

좌표를 옮기려면 좌표가 변수여야 합니다.

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

canvas.width = window.innerWidth;    /* 캔버스 너비 */
canvas.height = window.innerHeight;  /* 캔버스 높이 */

const circle = {
  x: 100,
  y: 100,
  radius: 30,
  dx: 4,
  dy: 4,
  color: "#222"
}

function drawCircle() {
  ctx.beginPath();
  ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2, false);
  ctx.fillStyle = circle.color;
  ctx.fill();
}

/* 키 상태 저장 객체 */
let keys = {
  ArrowUp: false,
  ArrowDown: false,
  ArrowLeft: false,
  ArrowRight: false
};

/* 키 누르면 true */
window.addEventListener("keydown", (e) => {
  if (e.key in keys) keys[e.key] = true;
});

/* 키 떼면 false */
window.addEventListener("keyup", (e) => {
  if (e.key in keys) keys[e.key] = false;
});

function move() {
  /* ctx.clearRect(0, 0, canvas.width, canvas.height); */

  /* 원을 지울 때 완전히 흰색으로 지우지 않고, 약간 불투명도가 있는 색으로 지우면 끌리는 자국처럼 보일 것입니다. */
  ctx.fillStyle = `rgba(255, 255, 255, 0.3)`;     /* 캔버스를 채울 색, 흰색에 불투명도가 0.3 */
  ctx.fillRect (0, 0, canvas.width, canvas.height); /* 캔버스를 다 덮는다, 그러면 덧칠을 하면 할수록 제일 처음 그린 애는 완전히 흰색에 가깝게 되고, 최근에 그린 것일수록 투명도가 점점 옅어질 것이다. */
  drawCircle();

  /* 방향키에 따라 이동 */
  if (keys.ArrowRight) circle.x += circle.dx;
  if (keys.ArrowLeft)  circle.x -= circle.dx;
  if (keys.ArrowDown)  circle.y += circle.dy;
  if (keys.ArrowUp)    circle.y -= circle.dy;

  if (circle.x + circle.radius > canvas.width || circle.x - circle.radius < 0) {
    circle.dx = -circle.dx;
    circle.color = `rgb(${Math.floor(Math.random() * 256)}, 
                      ${Math.floor(Math.random() * 256)}, 
                      ${Math.floor(Math.random() * 256)})`;
  }

  if (circle.y + circle.radius > canvas.height || circle.y - circle.radius < 0) {
    circle.dy = -circle.dy;
    circle.color = `rgb(${Math.floor(Math.random() * 256)}, 
                      ${Math.floor(Math.random() * 256)}, 
                      ${Math.floor(Math.random() * 256)})`;
  }
  
  requestAnimationFrame(move);
}

move();

 

아래는 방향키로 원을 움직이는 코드입니다.

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

canvas.width = window.innerWidth;    /* 캔버스 너비 */
canvas.height = window.innerHeight;  /* 캔버스 높이 */

const circle = {
  x: 100,
  y: 100,
  radius: 30,
  dx: 4,
  dy: 4,
  color: "#222"
}

function drawCircle() {
  ctx.beginPath();
  ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2, false);
  ctx.fillStyle = circle.color;
  ctx.fill();
}

/* 키 상태 저장 객체 */
let keys = {
  ArrowUp: false,
  ArrowDown: false,
  ArrowLeft: false,
  ArrowRight: false
};

/* 키 누르면 true */
window.addEventListener("keydown", (e) => {
  if (e.key in keys) keys[e.key] = true;
});

/* 키 떼면 false */
window.addEventListener("keyup", (e) => {
  if (e.key in keys) keys[e.key] = false;
});

function move() {
  /* ctx.clearRect(0, 0, canvas.width, canvas.height); */

  /* 원을 지울 때 완전히 흰색으로 지우지 않고, 약간 불투명도가 있는 색으로 지우면 끌리는 자국처럼 보일 것입니다. */
  ctx.fillStyle = `rgba(255, 255, 255, 0.3)`;     /* 캔버스를 채울 색, 흰색에 불투명도가 0.3 */
  ctx.fillRect(0, 0, canvas.width, canvas.height); /* 캔버스를 다 덮는다, 그러면 덧칠을 하면 할수록 제일 처음 그린 애는 완전히 흰색에 가깝게 되고, 최근에 그린 것일수록 투명도가 점점 옅어질 것이다. */
  drawCircle();

  /* circle.x += circle.dx; */   /* circle.x = circle.x + circle.dx */
  /* circle.y += circle.dy; */

  /* 방향키에 따라 이동 */
  if (keys.ArrowRight) circle.x += circle.dx;
  if (keys.ArrowLeft)  circle.x -= circle.dx;
  if (keys.ArrowDown)  circle.y += circle.dy;
  if (keys.ArrowUp)    circle.y -= circle.dy;

  if (circle.x + circle.radius > canvas.width || circle.x - circle.radius < 0) {
    circle.dx = -circle.dx;
    circle.color = `rgb(${Math.floor(Math.random() * 256)}, 
                        ${Math.floor(Math.random() * 256)}, 
                        ${Math.floor(Math.random() * 256)})`;
  }

  if (circle.y + circle.radius > canvas.height || circle.y - circle.radius < 0) {
    circle.dy = -circle.dy;
    circle.color = `rgb(${Math.floor(Math.random() * 256)}, 
                        ${Math.floor(Math.random() * 256)}, 
                        ${Math.floor(Math.random() * 256)})`;
  }

  requestAnimationFrame(move);
}

move();

 

'JavaScript' 카테고리의 다른 글

공개 API  (1) 2025.05.20
웹 API 활용  (0) 2025.05.18
캔버스의 그래픽 요소  (0) 2025.05.07
캔버스  (0) 2025.05.05
비동기 프로그래밍  (0) 2025.04.26