캔버스란
- 웹 문서에 Canvas API를 이용해서 그림을 그릴 수 있는 기능
캔버스 생성
<canvas>
<canvas></canvas>
<canvas width = "너비" height = "높이"></canvas>
<div id="canvas-1">
<h2>크기를 지정하지 않을 때</h2>
<canvas></canvas>
</div>
<div>
<h2>크기를 지정했을 때 400*300</h2>
<canvas width="400" height="300"></canvas>
</div>
화면 전체를 캔버스로 사용하는 방법
화면 전체를 캔버스로 사용하기 위해서는 몇 가지 여백과 스크롤 막대를 없애야 한다.
<style>
body {
margin:0; /* 여백 기본값을 0으로 설정 */
overflow:hidden; /* 스크롤 막대 숨기기 */
}
canvas {
background-color:#ccc;
}
</style>
const canvas = document.querySelector('canvas'); /* canvas 태그 불러오기 */
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
getContext() 메서드로 렌더링 콘텍스트 생성하기
👨🏫 랜더링 콘텍스트란
렌더링 콘텍스트는 그래픽을 그리기 위한 상태와 환경을 담고 있는 객체입니다.
즉, "무엇을 그리고, 어떻게 그릴지"를 지정하는 작업 공간이라 할 수 있습니다.
쉽게 말해서
- 캔버스(Canvas) = 도화지
- 렌더링 콘텍스트 = 붓 + 색상 + 그리기 도구들 세트
canvas.getContext("2d")
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(10, 10, 50, 100);
캔버스의 좌표
캔버스의 원점은 왼쪽 상단이다.
오른쪽으로 갈수록 x 좌표가 커지고, 아래쪽으로 갈수록 y좌표가 커진다.
캔버스의 각도
각도는 라디안 값으로 표기합니다.
radians = (Math.PI / 180) * degree
수학 때 배운 것과는 다르게 시계방향이 정방향이다.
캔버스에 기본 도형 그리기
사각형
사각형 생성 메서드
메서드 | 기능 |
fillRect(x, y, width, height) | (x, y)에서 시작해 지정한 너비와 높이만큼 색이 채워진 사각형을 생성, 색상 디폴트 = 검은색 |
strokeRect(x, y, width, height) | (x, y)에서 시작해 지정한 너비와 높이만큼 테투리만 있는 사각형 생성, 선 색상 = 검은색 |
clearRect(x, y, width, height) | (x, y)에서 시작해 지정한 너비와 높이만큼 사각형 영역을 지움 |
채우기 색과 선 색 지정
메서드 | 기능 |
fillStyle = "색상" | 도형을 채우는 색상 지정 |
strokeStyle = "색상" | 도형의 선 색상을 지정 |
삼각형
캔버스는 사각형 그리기만 제공하므로, 다른 도형을 그리려면 경로 그리기로 그려야 합니다.
👨🏫 경로 그리기 순서
1. beginPath()
→ 새로운 경로 시작
2. 원하는 경로 그리기
1) moveTo(x, y)
→ 시작점 이동
2) lineTo(x, y)
→ 선 그리기 (필요하면 여러 번 사용 가능)
3) (필요 시) arc(), quadraticCurveTo(), bezierCurveTo() 등
→ 곡선, 원, 복잡한 도형 추가 가능
3. closePath()
→ 경로 닫기 (선택 사항, 보통 도형 마무리에 사용)
4. stroke() 또는 fill()
→ 외곽선 그리기 / 내부 색 채우기
경로 그리기의 시작과 끝
beginPath()
closePath()
// 경로 그리기 시작
// 경로 그리기 종료
직선 경로
lineTo(x, y)
// 시작점에서 (x, y)까지 직선 경로 생성, 경로는 생성하지만 화면에 나타나지는 않음
경로 그리기 및 색 채우기
stroke()
fill()
// 경로를 화면에 나타냄
// 닫힌 공간을 만들었으면 색을 채울 수 있음
위치 옮기기
moveTo(x,y)
// 시작점을 (x, y)로 옮김
// 캔버스를 처음 만들면 시작점은 원점 (0, 0) 입니다.
자, 그럼 시작점 (50, 50)부터 (200, 200)까지 직선을 그려보자!
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(200, 200);
ctx.stroke();
내친김에 삼각형도 그려보자!
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
/* 경로를 시작합니다. */
ctx.beginPath();
/* 시작점을 (50,50) 위치로 이동시킵니다. */
ctx.moveTo(50, 50);
/* 시작점에서 (150, 100)까지 경로를 만듭니다. */
ctx.lineTo(150, 100);
/* 앞서 그린 경로 끝점에서 (50,150)까지 경로를 만듭니다. */
ctx.lineTo(50, 150);
/* 경로를 닫습니다. (닫힌 도형) */
ctx.closePath();
/* 지금까지 만든 경로를 선으로 그립니다. */
ctx.stroke();
/* 경로를 시작합니다. */
ctx.beginPath();
/* 시작점을 (150, 100) 위치로 이동시킵니다. */
ctx.moveTo(150, 100);
/* 시작점에서 (250, 50)까지 직선을 만듭니다. */
ctx.lineTo(250, 50);
/* 시작점에서 (250, 150)까지 직선을 만듭니다. */
ctx.lineTo(250, 150);
/* 경로를 닫습니다. (닫힌 도형) */
ctx.closePath();
/* 채우기 색을 rgb(0,200,0)으로 지정합니다. */
ctx.fillStyle = "rgb(0, 200, 0)";
/* 만들어진 (닫힌) 도형에 색을 채웁니다. */
ctx.fill();
/* 도형 외곽선을 그립니다. */
ctx.stroke();
원이나 호 그리기
arc(x, y, r, startAngle, endAngle [, counterClockwise])
원 생성
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
ctx.fillStyle = "yellow";
ctx.strokeStyle = "red";
ctx.beginPath()
ctx.arc(200, 150, 100, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.stroke();
반원과 호 그리기
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
/* 붉은색 채우기 설정 */
ctx.fillStyle = "red";
/* 첫 번째 반원: 반시계 방향 */
ctx.beginPath();
ctx.arc(120, 100, 50, 0, (Math.PI / 180) * 180, true); /* 반시계 방향 */
ctx.arc(280, 100, 50, 0, (Math.PI / 180) * 180, false); /* 시계 방향 */
ctx.fill();
/* 두 번째 반원: 시계 방향으로 선만 그리기 */
ctx.beginPath();
ctx.arc(120, 200, 50, (Math.PI / 180) * 90, (Math.PI / 180) * 270, false);
ctx.closePath();
ctx.stroke();
/* 세 번째 호: 파란색 외곽선만 그리기 */
ctx.strokeStyle = "blue";
ctx.beginPath();
ctx.moveTo(200, 100);
ctx.arc(200, 200, 50, 0, (Math.PI / 180) * 60, false);
ctx.stroke();
타원 그리기
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle [, counterClockwise])
- radiusX: 가로 반지름
- radiusY: 세로 반지름
- rotation: 타원 회전 크기, 라디안 값
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
ctx.strokeStyle = "red";
ctx.beginPath();
ctx.ellipse(200, 70, 80, 50, 0, 0, Math.PI * 2);
ctx.stroke();
ctx.strokeStyle = "blue";
ctx.beginPath();
ctx.ellipse(150, 200, 80, 50, (Math.PI / 180) * -30, 0, Math.PI * 2);
ctx.stroke();
원을 변형해서 타원 그리기
scale(x, y)
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
/* 원의 세로 길이를 축소해서 타원으로 그리기 */
ctx.strokeStyle = "blue";
ctx.scale(1, 0.7); /* 가로 길이 유지, 세로 길이 축소 */
ctx.beginPath()
ctx.arc(200, 150, 80, 0, Math.PI * 2, true);
ctx.stroke();
ctx.beginPath()
ctx.arc(200, 150, 30, 0, Math.PI * 2, false);
ctx.stroke();
ctx.closePath();
곡선 그리기
2차 베지에 곡선 (Bezier Curve)
베지에 곡선은 시작점과 끝점 사이에 조절점을 통해 그린 곡선이다.
quadraticCurveTo(cpx, cpy, x, y)
- cpx, cpy: 조절점 좌표
조절점 갯수에 따라 베지에 곡선의 차수가 달라진다.
- 1차 베지에 곡선: 조절점 0개 (=직선)
- 2차 베지에 곡선: 조절점 1개
- 3차 베지에 곡선: 조절점 2개
조절점 1개로 곡선을 그려봅시다.
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(50, 200); /* 곡선 시작 위치 */
ctx.quadraticCurveTo(200, 50, 350, 200); /* 시작 위치부터 (350, 200)까지 곡선 그리기 */
ctx.stroke();
조절점 3개로 물결 곡선을 만들어 보자!
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(50, 100); /* 곡선 시작 위치 */
ctx.quadraticCurveTo(100, 50, 150, 100);
ctx.quadraticCurveTo(200, 150, 250, 100);
ctx.quadraticCurveTo(300, 50, 350, 100);
ctx.stroke();
3차 베지에 곡선
조절점 2개를 사용해서 곡선을 그려봅시다.
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
- cp1x, cp1y: 첫 번째 조절점 좌표
- cp2x, cp2y: 두 번째 조절점 좌표
- x, y: 곡선이 끝나는 점의 좌표
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(50, 100); /* 곡선 시작 위치 */
ctx.bezierCurveTo(90, 250, 310, 10, 350, 100);
ctx.strokeStyle = "green";
ctx.stroke();
Path2D
경로(도형의 윤곽)를 정의하고 재사용할 수 있게 해주는 객체
복잡한 도형을 미리 만들어 놓고, 캔버스에 그릴 때 간편하게 불러와 사용할 수 있습니다.
new Path2D()
new Path2D(경로)
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
let triangle = new Path2D(); /* 삼각형 경로 객체 */
triangle.moveTo(100, 100);
triangle.lineTo(300, 100);
triangle.lineTo(200, 260);
triangle.closePath();
let circle = new Path2D(); /* 원 경로 객체 */
circle.arc(200, 155, 50, 0, Math.PI * 2);
ctx.fillStyle = "green";
ctx.stroke(triangle); /* 삼각형 그리기 */
ctx.fill(circle); /* 원 그리기 */
캔버스에 텍스트 그리기
텍스트를 그리는 메서드
fillText(text, x, y [,maxWidth]) // 텍스트를 채움
strokeText(text, x, y [,maxWidth]) // 텍스트 선만 그림
- text: 캔버스에 그릴 텍스트
- x, y: 텍스트를 표시할 좌표
- maxWidth: 텍스트를 표시할 최대 너비
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
ctx.font = "60px Arial"; /* 글자 크기와 글꼴 설정은 쉼표, 공백 없이 */
ctx.fillText("HELLO", 50, 70); /* 텍스트 채움 */
ctx.strokeText("HELLO", 50, 150); /* 텍스트 선만 그림 */
캔버스의 이미지
이미지 표시
이미지 가져오기
let img = new Image(); /* 새로운 이미지 객체 생성 */
img.src = "spring.jpg"; /* 이미지 객체에 파일 경로 지정 */
이미지 그리기
drawImage(image, dx, dy)
- image: 캔버스에 표시할 이미지 객체 지정
- dx, dy: 캔버스 왼쪽 위 모서리로부터 얼마나 떨어져서 이미지를 표시할지 지정
👨🏫 drawImage는 context의 메서드입니다. onload 이벤트와 함께 함수를 실행
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
let img = new Image();
img.onload = function() { /* 이미지 객체의 load 이벤트 */
ctx.drawImage(img, 0, 0); /* Context 메서드 drawImage 사용 */
}
img.src = "images/cat.jpg";
이미지 크기 조절
drawImage(image, dx, dy, dw, dh)
- image: 캔버스에 표시할 이미지 객체 지정
- dx, dy: 캔버스 왼쪽 위 모서리로부터 얼마나 떨어져서 이미지를 표시할지 지정
- dw, dh: 캔버스에 표시할 이미지 크기 지정
ctx.drawImage(img, 0, 0, 300, 200);
캔버스 크기에 딱 맞게 하려면 아래와 같이 하면 된다.
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
이미지 일부만 표시
이미지 잘라내서 표시하기
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
- image: 캔버스에 표시할 이미지 객체 ㅈ지정
- sx, sy: 이미지 왼쪽 위 모서리로부터 얼마나 떨어진 곳부터 자를지 (자를 이미지 좌상단 좌표)
- sw, sh: 잘라낼 이미지의 너비와 높이
- dx, dy: 캔버스의 왼쪽 위 모서리로 부터 얼마나 떨어진 곳에 이미지를 붙일지
- dw, dh: 이미지의 너비와 높이
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
let img = new Image();
img.onload = function() {
ctx.drawImage(img, 100, 50, 280, 350, 160, 100, 140, 175);
}
img.src = "images/cat.jpg";
이미지 클리핑
👨🏫 클리핑이란?
경로를 그려 놓고 경로 밖은 감추는 것
clip()
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext("2d");
let img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 캔버스 크기에 맞게 지정
}
img.src = "images/bird.jpg";
ctx.beginPath();
ctx.arc(300, 200, 150, 0, Math.PI * 2, false); /* 원 경로 만듦 */
ctx.clip(); /* 클리핑 */

끝
'JavaScript' 카테고리의 다른 글
애니메이션 (0) | 2025.05.15 |
---|---|
캔버스의 그래픽 요소 (0) | 2025.05.07 |
비동기 프로그래밍 (0) | 2025.04.26 |
HTTP 통신과 JSON (0) | 2025.04.22 |
배열과 객체 (0) | 2025.04.10 |