Canvas API/Canvas tutorial/Drawing text

김동현·2026년 3월 22일

안녕하세요! 캔버스 튜토리얼을 아주 순조롭게 따라오고 계시네요. 색상과 스타일을 다루는 법을 익혔으니, 이번에는 캔버스 위에 '텍스트(Text) 그리기'를 배워볼 차례입니다.

만들고 계신 독후감 사이트에서 연간 독서량 통계를 차트로 그리거나, 웹 프로필 사이트에서 역량 게이지를 캔버스로 표현할 때 그 위에 숫자나 글자를 직접 새겨 넣어야 하는 경우가 생길 텐데요. 그럴 때 이 텍스트 그리기 API가 아주 핵심적인 역할을 하게 됩니다.

강사의 실무 팁과 함께 상세히 번역해 드릴 테니 잘 따라와 주세요!


텍스트 그리기 (Drawing text)

이전 (Previous) | 다음 (Next)

이전 장에서 스타일과 색상을 적용하는 방법을 살펴본 데 이어, 이번에는 캔버스에 텍스트를 그리는 방법에 대해 알아보겠습니다.


이 문서에서는 (In this article)


텍스트 그리기 (Drawing text)

캔버스 렌더링 컨텍스트는 텍스트를 렌더링하기 위해 다음 두 가지 메서드를 제공합니다.

fillText(text, x, y [, maxWidth])

주어진 텍스트를 지정된 (x, y) 좌표에 색을 채워서(fill) 그립니다. 선택적으로 최대 너비(maxWidth)를 지정할 수 있습니다.

strokeText(text, x, y [, maxWidth])

주어진 텍스트를 지정된 (x, y) 좌표에 테두리 선만(stroke) 그립니다. 선택적으로 최대 너비(maxWidth)를 지정할 수 있습니다.

💡 강사의 실무 팁:
선택 사항인 maxWidth를 지정하면, 글자가 주어진 너비보다 길어질 경우 브라우저가 알아서 폰트 장평을 줄이거나 더 작게 압축해서 해당 너비 안에 욱여넣어 줍니다. 차트나 버튼 안의 텍스트가 컨테이너 밖으로 삐져나가는 것을 막고 싶을 때 아주 유용하게 쓰이는 방어 코드랍니다!

fillText 예제

이 메서드는 텍스트를 현재 설정된 fillStyle 속성을 사용하여 칠합니다.

function draw() {
  const ctx = document.getElementById("canvas").getContext("2d");
  ctx.font = "48px serif";
  ctx.fillText("Hello world", 10, 50);
}
<canvas id="canvas" width="300" height="100"></canvas>

strokeText 예제

이 메서드는 텍스트의 외곽선을 현재 설정된 strokeStyle 속성을 사용하여 그립니다. (마치 글씨 내부는 비어있고 테두리만 있는 형태가 됩니다.)

function draw() {
  const ctx = document.getElementById("canvas").getContext("2d");
  ctx.font = "48px serif";
  ctx.strokeText("Hello world", 10, 50);
}
<canvas id="canvas" width="300" height="100"></canvas>

텍스트 스타일링 (Styling text)

위의 예제들에서 우리는 이미 텍스트의 크기를 기본값보다 조금 더 크게 만들기 위해 font 속성을 사용해 보았습니다. 캔버스 위에 텍스트가 어떻게 그려질지를 세밀하게 조절할 수 있도록 해주는 추가적인 속성들이 몇 가지 더 있습니다.

font = value

텍스트를 그릴 때 사용될 폰트 스타일을 지정합니다. 이 문자열은 CSSfont 속성과 완벽하게 동일한 문법을 사용합니다. 기본 폰트는 10px sans-serif입니다.

textAlign = value

텍스트의 정렬 방식을 설정합니다. 사용 가능한 값: start, end, left, right, center. 기본값은 start입니다.

textBaseline = value

텍스트의 베이스라인(기준선) 정렬 방식을 설정합니다. 사용 가능한 값: top, hanging, middle, alphabetic, ideographic, bottom. 기본값은 alphabetic입니다.

direction = value

텍스트가 쓰이는 방향을 설정합니다. 사용 가능한 값: ltr(좌에서 우로), rtl(우에서 좌로), inherit(부모 요소 상속). 기본값은 inherit입니다.

이전에 CSS를 다뤄보신 적이 있다면 이 속성들이 꽤 친숙하게 느껴지실 겁니다.

HTML 명세서(HTML spec)에서 가져온 다음 다이어그램은 textBaseline 속성으로 지원되는 다양한 기준선(baselines)들을 보여줍니다.

다양한 textBaseline 기준선을 보여주는 다이어그램. em-over는 보통 글꼴 상단에, hanging은 आ 와 같은 글리프에 쓰이고, alphabetic은 영문자에 주로 쓰이며, ideographic-under는 한자/가나 등에, em-under는 글꼴 하단에 위치합니다.

textBaseline 예제

이 예제는 다양한 textBaseline 속성 값들이 텍스트를 어떻게 위치시키는지 시각적으로 보여줍니다.
더 자세한 정보와 예제는 CanvasRenderingContext2D.textBaseline 페이지에서 확인하실 수 있습니다.

<canvas id="canvas" width="400" height="100"></canvas>
function draw() {
  const ctx = document.getElementById("canvas").getContext("2d");
  ctx.font = "48px serif";

  // 위쪽 기준선
  ctx.textBaseline = "hanging";
  ctx.strokeText("hanging", 10, 50);

  // 중앙 기준선
  ctx.textBaseline = "middle";
  ctx.strokeText("middle", 250, 50);

  // 글씨가 어떻게 정렬되는지 확인하기 위한 기준선 그리기
  ctx.beginPath();
  ctx.moveTo(10, 50);
  ctx.lineTo(300, 50);
  ctx.stroke();
}

💡 강사의 핵심 팁:
화면에 버튼이나 차트 툴팁을 캔버스로 직접 그릴 때, 사각형(도형)의 정확한 한가운데에 텍스트를 배치하고 싶다면 어떻게 해야 할까요?
ctx.textAlign = 'center';ctx.textBaseline = 'middle'; 을 함께 설정한 뒤, 사각형 중심점의 x, y 좌표를 fillText()에 넘겨주면 글자가 완벽하게 수평/수직 중앙에 딱 맞춰서 렌더링 됩니다. 실무에서 아주 유용하게 쓰이는 공식입니다!


고급 텍스트 측정 (Advanced text measurements)

그려질 텍스트에 대한 더 상세한 치수 정보(너비 등)를 알아야 할 때가 있습니다. 이럴 때 다음 메서드를 사용하여 텍스트를 측정할 수 있습니다.

measureText()

지정된 텍스트가 현재의 텍스트 스타일로 그려질 때 차지하게 될 너비를 픽셀 단위로 담고 있는 TextMetrics 객체를 반환합니다.

다음 코드 조각은 텍스트를 측정하여 그 너비 값을 가져오는 방법을 보여줍니다.

function draw() {
  const ctx = document.getElementById("canvas").getContext("2d");
  const text = ctx.measureText("foo"); // TextMetrics 객체를 반환
  text.width; // 16 (설정된 폰트에 따라 픽셀 너비가 계산됨)
}

💡 강사의 실무 팁:
measureText()는 동적인 UI를 만들 때 필수입니다. 예를 들어 사용자의 이름이나 동적으로 변하는 데이터를 말풍선 안에 그려야 한다고 가정해 볼까요? 글자가 얼마나 길어질지 미리 알 수 없기 때문에, 먼저 measureText()로 글자의 width를 계산한 다음, 그 너비에 패딩(여백)을 조금 더해서 말풍선 사각형의 크기를 동적으로 그리는 로직에 사용합니다.


접근성 관련 주의사항 (Accessibility concerns)

<canvas> 요소는 본질적으로 그저 픽셀들의 묶음인 '비트맵(bitmap)'일 뿐이며, 그 안에 그려진 객체들에 대한 어떠한 의미론적(semantic) 정보도 제공하지 않습니다. 즉, 캔버스 위에 쓰인 텍스트는 시력 문제로 인해 화면 확대 프로그램(screen magnification)에 의존하는 사용자들에게 심각한 가독성 문제를 일으킬 수 있습니다.

캔버스 내의 픽셀들은 벡터(vector) 방식이 아니라 단순한 픽셀 조각의 모음이므로 화면 비율에 맞춰 깔끔하게 확장(scale)되지 못합니다. 따라서 화면을 확대하면 글자가 심하게 뭉개지거나 흐릿해집니다(blurry).

무엇보다 가장 큰 문제는 시맨틱 HTML과 달리 캔버스의 콘텐츠는 스크린 리더(Screen Readers)와 같은 접근성 도구(Accessibility tools)에 전혀 노출되지 않는다는 점입니다.

일반적으로, 웹 접근성이 중요한 웹사이트나 애플리케이션에서는 텍스트를 표현할 때 캔버스 사용을 피해야 합니다. 그 대신 캔버스 위에 투명한 일반 HTML 요소(예: <span>이나 <p>)를 절대 위치(absolute position)로 띄워서 배치하거나, SVG(Scalable Vector Graphics)를 사용하는 것이 훨씬 훌륭한 대안입니다.

이전 (Previous) | 다음 (Next)


MDN 개선에 참여하기 (Help improve MDN)

이 페이지가 도움이 되었나요? (Was this page helpful to you?)
[ 예 (Yes) ][ 아니오 (No) ]

링크


수고하셨습니다! 프론트엔드 개발자로서 캔버스에 텍스트를 입히는 방법뿐만 아니라 접근성(a11y) 측면의 한계점까지 완벽하게 파악하셨네요. 동적인 측정이나 중앙 정렬 등 예제에 없는 팁들도 실제 컴포넌트 개발 시에 꼭 활용해 보세요!

혹시 다음 파트나 React 컴포넌트에 이 캔버스를 어떻게 올릴지 궁금한 점이 있으시다면 편하게 질문 남겨주세요.

profile
프론트에_가까운_풀스택_개발자

0개의 댓글