Canvas API

Canvas API

브라우저에서 그래픽을 그리고 애니메이션을 만들 때 Canvas API는 매우 강력한 도구다. 2D 그래픽을 자유롭게 다룰 수 있어서 게임이나 데이터 시각화에 유용하다. 이번에는 Canvas API의 기본부터 심화된 활용까지 코드와 함께 자세히 알아보려고 한다.


Canvas API를 잘 다루면 복잡한 그래픽 작업도 쉽게 구현할 수 있다. 하나씩 차근차근 살펴보자.


Canvas 기본 설정

<canvas> 요소와 2D 컨텍스트를 사용해서 시작할 수 있다:

const canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 300;
document.body.appendChild(canvas);

const ctx = canvas.getContext("2d");
ctx.fillStyle = "#ddd";
ctx.fillRect(0, 0, 400, 300);
// 400x300 크기의 회색 사각형 캔버스 생성

getContext("2d")로 2D 컨텍스트를 얻고, 기본 배경을 그렸다.


1. 기본 도형 그리기

사각형, 선, 원 같은 기본 도형을 그려보자:

const canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 300;
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

ctx.fillStyle = "red";
ctx.fillRect(50, 50, 100, 100);
// 빨간 사각형

ctx.strokeStyle = "blue";
ctx.lineWidth = 2;
ctx.strokeRect(200, 50, 100, 100);
// 파란 테두리 사각형

ctx.beginPath();
ctx.strokeStyle = "green";
ctx.moveTo(50, 200);
ctx.lineTo(150, 250);
ctx.stroke();
// 초록 선

ctx.beginPath();
ctx.fillStyle = "purple";
ctx.arc(250, 200, 40, 0, Math.PI * 2);
ctx.fill();
// 보라색 원

fillRect, strokeRect, lineTo, arc로 다양한 도형을 그렸다.


2. 경로와 스타일 조합

복잡한 경로를 그리고 스타일을 적용해보자:

const canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 300;
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.strokeStyle = "orange";
ctx.lineWidth = 3;
ctx.moveTo(50, 50);
ctx.lineTo(150, 100);
ctx.lineTo(100, 150);
ctx.closePath();
ctx.fillStyle = "yellow";
ctx.fill();
ctx.stroke();
// 노란색 채우기와 주황색 테두리의 삼각형

beginPathclosePath로 경로를 만들고 채우기와 테두리를 함께 적용했다.


3. 텍스트와 이미지 추가

텍스트와 이미지를 캔버스에 그려보자:

const canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 300;
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

ctx.font = "30px Arial";
ctx.fillStyle = "black";
ctx.fillText("안녕, Canvas!", 50, 50);
ctx.strokeStyle = "red";
ctx.strokeText("안녕, Canvas!", 50, 100);
// 검은 채우기 텍스트와 빨간 테두리 텍스트

const img = new Image();
img.src = "https://via.placeholder.com/100";
img.onload = () => {
    ctx.drawImage(img, 50, 150);
};
// 100x100 이미지 그리기

fillText, strokeText로 텍스트를 그리고, drawImage로 이미지를 추가했다.


4. 변환과 애니메이션

회전, 이동, 애니메이션을 적용해보자:

const canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 300;
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

ctx.translate(200, 150);
ctx.rotate(Math.PI / 4);
ctx.fillStyle = "blue";
ctx.fillRect(-50, -50, 100, 100);
// 중앙에서 45도 회전한 파란 사각형

let angle = 0;
function animate() {
    ctx.clearRect(-200, -150, 400, 300);
    ctx.rotate(Math.PI / 180);
    angle += Math.PI / 180;
    ctx.fillStyle = "green";
    ctx.fillRect(-25, -25, 50, 50);
    requestAnimationFrame(animate);
}
animate();
// 계속 회전하는 초록 사각형

translate, rotate로 변환을 적용하고, 애니메이션은 requestAnimationFrame으로 구현했다.


5. 이벤트와 상호작용

마우스 이벤트를 캔버스에 연결해보자:

const canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 300;
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

canvas.addEventListener("mousemove", (event) => {
    const x = event.offsetX;
    const y = event.offsetY;
    ctx.clearRect(0, 0, 400, 300);
    ctx.beginPath();
    ctx.fillStyle = "orange";
    ctx.arc(x, y, 20, 0, Math.PI * 2);
    ctx.fill();
});
// 마우스를 따라다니는 주황색 원

mousemove 이벤트로 마우스 위치를 추적해서 원을 그렸다.


6. 그림자와 그라디언트

그림자와 그라디언트로 시각적 효과를 더해보자:

const canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 300;
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

ctx.shadowColor = "gray";
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.fillStyle = "blue";
ctx.fillRect(50, 50, 100, 100);
// 그림자가 있는 파란 사각형

const gradient = ctx.createLinearGradient(200, 50, 300, 150);
gradient.addColorStop(0, "red");
gradient.addColorStop(1, "yellow");
ctx.fillStyle = gradient;
ctx.fillRect(200, 50, 100, 100);
// 빨강에서 노랑으로 변하는 그라디언트 사각형

shadow 속성과 createLinearGradient로 효과를 추가했다.


7. 클리핑과 합성

클리핑 영역과 합성 모드를 사용해보자:

const canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 300;
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.arc(200, 150, 50, 0, Math.PI * 2);
ctx.clip();
ctx.fillStyle = "pink";
ctx.fillRect(0, 0, 400, 300);
// 원형 클리핑 영역에 핑크색 채우기

ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(0, 0, 255, 0.5)";
ctx.fillRect(250, 200, 100, 100);
// 반투명 파란 사각형 합성

clip으로 그리기 영역을 제한하고, globalCompositeOperation으로 합성 방식을 조정했다.


8. 성능과 활용성 고려

Canvas API가 작업에 어떤 영향을 주는지 보자:

- 성능: 복잡한 그래픽은 자원을 많이 소모하지만, 애니메이션 최적화로 부담을 줄일 수 있다.

- 활용성: 도형, 텍스트, 이미지, 이벤트까지 다채롭게 조합 가능하다.

컨텍스트 설정requestAnimationFrame을 활용하면 동적인 그래픽을 효율적으로 다룰 수 있다.


마무리

Canvas API는 2D 그래픽을 그리기 위한 강력한 도구다. 기본 도형부터 애니메이션, 이벤트, 효과까지 다루며, 게임이나 시각화 작업에 큰 힘을 발휘한다.


+ Recent posts