이 페이지는 mdn 튜토리얼 을 참고했습니다. 해당 사이트의 예제는 훌륭하지만, 일부 코드들이 동작하지 않는 버그가 있습니다. 버그 수정 및 예제 추가를 하였습니다. 모든 실습파일은 다운로드 후에 실행, 분석할 수 있습니다.

강의노트

아래 github에 업로드된 예제코드를 다운받아 실습 할 수 있습니다(E_Canvas 참조).

https://github.com/iseohyun/html-tutorial.git

준비사항

이어지는 예제 코드는 아래의 기본 코드에서 TODO부분을 채우면 됩니다. (브라우저 버전별 지원 세부사항: https://developer.mozilla.org/...브라우저 지원)

<script>
  function draw() {
    var ctx = document.getElementById('canvas1').getContext('2d');
    <!-- TODO: intert 'Canvas API' -->
  }
</script>

<body onload="draw()">
  <canvas id="canvas1" width="200" , height="200"></canvas>
</body>

빈 캔버스canvas를 생성하고, 캔버스 위에 그림을 그립니다. 따라서 빈 캔버스가 완전히 로딩되고, script가 수행되어야 합니다. onload함수는 문서가 완전히 로딩이 된 후에 draw함수가 수행되도록 설계되어 있습니다. 위와 같이 호출된다면, 로딩 순서를 고민할 필요가 없습니다.

좌표계

좌표계는 캔버스의 가장 좌상단이 (0,0)이 되며, x축은 오른쪽으로 증가, y축은 하단으로 증가합니다.


도형 그리기

선 그리기 문법 Overview
분류 도형 문법
도형 그리기 시작 beginPath()
선으로 그리기 stroke()
채우기 fill()
이동 moveTo(좌표x, y)
lineTo(좌표x, y)
원호 arc(중심x, y, 반지름, 시작각, 끝각, 시계방향=true)
베지어곡선(2차) quadraticCurveTo(제어점x, y, 끝점x, y)
베지어곡선(3차) bezierCurveTo(제어점1x, y, 제어점2x, y, 끝점x, y)
채워진 사각형 fillRect(시작x, y, 크기x, y);
빈 사각형 StrokeRect(시작x, y, 크기x, y);
특성 선 색 ctx.strokeStyle = 색;
칠하기 색 ctx.fillStyle = 색;
선 굵기 ctx.lineWidth = 숫자;
끝선 처리 규칙 ctx.strokeStyle = 'butt' | 'round' | 'square';
선 이음부 처리 규칙 ctx.lineJoin = 'round' | 'bevel' | 'miter'
삐져나옴(bevel)처리 규칙 ctx.miterLimit = 임계각
점선 규칙 ctx.setLineDash([주기1, 주기2 ...]);
점선 밀기 ctx.lineDashOffset = 오프셋
그리기 도구 도구 생성
도구 복사
도구 생성(경로)
new Path2D();
new Path2D(path);
new Path2D(d);

직선

A_Start > a_line.html
lineTo(좌표x, y);   // 선을 그립니다.
moveTo(좌표x, y);   // 선을 그리지 않고 이동합니다.

사각형

A_Start > b_rect.html
fillRect(시작x, y, 크기x, y);   // 채워진 사각형
StrokeRect(시작x, y, 크기x, y);   // 빈 사각형
ctx.fillRect(25, 25, 100, 100); // 채워진 사각형을 그립니다.
ctx.strokeRect(150, 25, 100, 100); // 빈 사각형을 그립니다.
ctx.clearRect(350,50,100,50);   // 이미 그려진 것들을 지워버립니다.(사각투명)

원의 시작점이 3시 방향인 것에 주의합니다. 원호의 길이는 라디안radian값을 사용합니다.

arc(중심x, y, 반지름, 시작각, 끝각, 시계방향=true)
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // 바깥쪽 원
ctx.moveTo(110, 75);
ctx.arc(75, 75, 35, 0, Math.PI, false);  // 입(시계 방향)
ctx.moveTo(65, 65);
ctx.arc(60, 65, 5, 0, Math.PI * 2, true);  // 왼쪽 눈
//ctx.moveTo(95, 65); // 붓 떼기 주석처리
ctx.arc(90, 65, 5, 0, Math.PI * 2, true);  // 오른 쪽 눈
ctx.stroke();
  ※ 위 예제코드 구현파일입니다.
A_Start > c_arcs.html

곡선

곡선은 아래와 같이 시작-끝 외에 1개(2차함수) 또는 2개(베지어곡선, 3차함수)의 제어점을 갖습니다.

quadraticCurveTo(제어점x, y, 끝점x, y)
bezierCurveTo(제어점1x, y, 제어점2x, y, 끝점x, y)

  ※ 2차곡선의 드로잉 방식에 대한 설명을 위해 작성한 예제입니다.

2차 곡선

A_Start > d_speechBubble.html

3차 곡선

선 굵기와 출력방법 "canvas-grid.png", developer.mozilla.org, CC-BY-SA v2.5 or later

선분이 뿌옇게 보이는 이유는 0.5 단위로 그려지기 때문입니다. 따라서 정확하게 그리고 싶다면 위와 같이 시작점을 .5로 지정해야 합니다. 단, 소수점 랜더링은 CPU에 부하를 주는 방식이기 때문에 추천하지는 않습니다.

lineWidth

ctx.lineWidth = 숫자;
// .5로 그린 선분 : 확실히 선명하게 그려진다.
ctx.moveTo(5.5, 5);
ctx.lineTo(5.5, 140);
ctx.stroke();

// 대충 굵기만 다르게 그린 선분
for (var i = 0; i < 10; i++){
    ctx.lineWidth = 1 + i;
    ctx.beginPath();
    ctx.moveTo(5 + i * 14, 5);
    ctx.lineTo(5 + i * 14, 140);
    ctx.stroke();
}
A_Start > e_lineWidth.html

lineCap

ctx.strokeStyle = 'butt' | 'round' | 'square';
var lineCap = ['butt','round','square'];

// 안내선을 그린다
ctx.strokeStyle = '#09f';
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(140, 10);
ctx.moveTo(10, 140);
ctx.lineTo(140, 140);
ctx.stroke();

// 선을 그린다
ctx.strokeStyle = 'black';
for (var i=0;i<lineCap.length;i++){
    ctx.lineWidth = 15;
    ctx.lineCap = lineCap[i];
    ctx.beginPath();
    ctx.moveTo(25 + i * 50, 10);
    ctx.lineTo(25 + i * 50,140);
    ctx.stroke();
}
A_Start > e2_lineCap.html

lineJoin

ctx.lineJoin = 'round' | 'bevel' | 'miter'
ctx = document.getElementById('lineJoin').getContext('2d');
var lineJoin = ['round', 'bevel', 'miter'];
ctx.lineWidth = 10;
for (var i = 0; i & #x3C; lineJoin.length; i++) {
    ctx.lineJoin = lineJoin[i];
    ctx.beginPath();
    ctx.moveTo(-5, 5 + i * 40);
    ctx.lineTo(35, 45 + i * 40);
    ctx.lineTo(75, 5 + i * 40);
    ctx.lineTo(115, 45 + i * 40);
    ctx.lineTo(155, 5 + i * 40);
    ctx.stroke();
}
A_Start > e3_lineJoin.html

miterLimit

ctx.miterLimit = 임계각;   // 허용하는 최대 각

마이터(miter, 직각으로 물리는 톱니)의 구현에 있어서 어디까지 베블(bevel, 경사각)을 그려줄지 결정해야합니다.

A_Start > e4_miterLimit.html

아래의 그림을 클릭합니다. miterLimit과 각도에 따라서 bevel을 그릴지 말지 결정합니다.

lineDash

주기를 무한히 반복합니다.

setLineDash([주기1, 주기2 ...]);
lineDashOffset = 오프셋
A_Start > e5_linedash.html

애니메이션 기법은 Chapter 9에서 다시 다룹니다. 예제에서는 0.02초마다 march함수를 호출합니다. 부하가 걸리는 방식이기 때문에 추천하는 애니메이션은 아닙니다.

path2D

path2D객체로 경로를 가져와 그림을 그릴 수 있습니다.

new Path2D();     // empty path object
new Path2D(path); // copy from another Path2D object
new Path2D(d);    // path from SVG path data

예제

// Path2D 객체를 생성한 후 그리기 예제
var drawing = new Path2D();
drawing.rect(10, 10, 50, 50);
drawing.moveTo(125, 35);
drawing.arc(100, 35, 25, 0, 2 * Math.PI);

ctx.fill(drawing);

// SVG 경로를 생성한 후 그리기 예제
// Move(200,10) → horizontal(수평) 80 이동 → vertical(수직) 80이동 → 수평 -40이동 → 원점으로
var p = new Path2D('M200 10 h 80 v 80 h -40 Z');

ctx.stroke(p);
A_Start > e6_path2D.html

Path표기법에 대해서는 "Svg > 그리기(path)"를 참조합니다