*여기에 있는 내용은 제가 복습차, 방송대 컴퓨터 과학과 HTML5 이관용 교수님의 PPT 수업 내용을 참조하여 정리함을 알립니다.
1) 캔버스 개요
- 캔버스? 웹페이지에서 자바스크립트 코드로 브라우저에 그림을 그리는 기능
- 별도의 프로그램 설치 없이 사용가능
- 단순히 그림을 표현하는 기능 이외에 그림의 합성, 변환, 애니메이션과 같은 다양한 효과의 표현도 가능
- 그림을 그리기 위해서는
- canvas 요소를 사용해서 그림이 그려질 영역 지정: canvas 요소 -> 단순히 그림을 담는 컨테이너
- 자바스크립트 코드를 사용해서 해당 영역에 실제 그림을 그린다.

1-1) 그림 영역 지정
- canvas 요소를 사용해서 캔버스영역을 지정
- 캔버스 영역 -> 웹페이지에서 그림이 그려지는 투명한 사각형 영역
< canvas id="아이디" width="폭" height="높이">
이 요소를 지원하지 않는 브라우저에 출력할 내용
</canvas>
예)
<canvas id="myCanvas" width="500" height="300"
style="border: 1px solid red">
이 브라우저는 HTML5의 canvas 요소를 지원하지 않습니다.
</canvas>
- 캔버스 크기와 드로잉 표면의 크기
- canvas 요소의 height 속성 / width 속성을 지정하여 사용하는 경우 (권장)
-> 캔버스 크기 = 드로잉 표면의 크기
- CSS를 사용해서 캔버스 크기를 지정하는 경우 -> 캔버스의 크기 != 드로잉 표면의 크기
<canvas id="myCanvas"> 캔버스 미지원 (폭 , 높이 생략) </canvas> |
- (위) 드로잉 표면 크기: 300*150 (아래) 캔버스 크기(500*300)가 다르다
- 해석: 캔버스 크기를 스타일로 지정하면 캔버스의 크기는 500*300로 스타일에 지정된 크기로 되지만 드로잉 표면의 크기는 자동으로 작게 설정되어진다.
<style> canvas {width: 500px; height: 300px } </style> |
1-3) 캔버스와 캔버스 콘텍스트 생성
- 캔버스 객체 생성
- var 변수1 = document.getElementById('캔버스요소_아이디');
예) var canvas = document.getElementById('myCanvas');
-> 컨텍스트에서 사용하기 위한 캔버스 객체 생성
- 캔버스 콘텍스트 객체 생성
- var 변수2 = 변수1.getContext('2d');
예) var ctx = canvas.getContext('2d');
-> 실제 그림을 그릴수 있는 모든 그래픽 기능 생성
2 줄의 위의 문장을 1 줄의 var ctx = document.getElementById('myCanvas').getContext('2d'); 도 가능 |
1-4) 캔버스 작업의 기본 형태
<body>
<canvas id = "myCanvas" width="350" height="200" style="background-color:light-blue"> 이 브라우저는 HTML5의 canvas 요소를 지원하지 않습니다. </canvas> |
- (위) 그림 그릴 영역을 지정
<script> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); [ 실제 그림을 그리는 자바스크립트 코드를 위치 시킨다. ] </script> |
</body>
- (위) 자바스크립트 코드를 이용해 해당 영역에 그림을 그림
<실제 그림을 그리는 부분의 예> // 빨간색으로 텍스트 그리기 ctx.font = "20px 굴림체"; ctx.fillStyle = "red"; ctx.fillText("캔버스 맛보기", canvas.width/2 -70, canvas.height/2 -5); //파란색으로 사각형 그리기 ctx.strokeStyle="blue"; ctx.strokeRect(70,40,200,100); |

<이벤트를 활용하는 경우> <head> <script> function 함수명(){ var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); --- 실제 그림 작업 --- } </script> </head> <body onload="함수명();"> -> onload 속성으로 문서가 시작될 때 자동으로 함수가 실행된다 <canvas id="myCanvas" ---> --- </canvas> </body> |
2) 선과 도형 그리기
2-1) 사각형 그리기
- 시작점(x,y), 폭 w, 높이 h (네가지 변수가 필요)
2-2) 사각형 그리기 관련 메서드
- strokeRect(x,y,w,h)
-테두리만 있는 사각형을 그림
(관련 속성 -> strokeStyle, lineWidth, lineJoin, lineCap)
- fillRect(x,y,w,h)
- 색이 채워진 사각형을 그림
(채우기 관련 스타일 속성 ->fillStyle, globalAlpha)
- clearRect(x,y,w,h)
- 지정한 사각형 영역을 지움
(영역 안의 모든 픽셀을 투명한 검은색 rgba(0,0,0,0)으로 채움)
2-3) 사각형 그리기 예
<body> <canvas id="myCanvas"></canvas> <script> var canvas= document.getElementById("myCanvas"); //캔버스 객체 생성 var ctx=canvas.getContext("2d"); // 컨텍스트 객체 생성하여 메소드 적용 canvas.width=300; // 캔버스 객체의 넓이 속성 추가 canvas.height=300; // 캔버스 객체의 높이 속성 추가 canvas.style.backgroundColor="lightyellow"'; // 캔버스 객체의 백그라운드 색깔을 JavaScript 코드 내에서 backgroundColor 로 표현 -> style 태그 내에서는 background-color로 표현 [ 사각형 그리는 부분 ] </script> </body> |
[사각형을 그리는 부분] ctx.lineWidth ="10"; // 그리는 라인의 면적이 10 ctx.strokeStyle = "blue"; // 그리는 라인의 색깔이 파란색 ctx.fillStyle = "green"; // 사각형을 채울 때 색상이 초록색 ctx.strokeRect(50,50,100,100); // 파란색으로 라인 그림(50,50이 x,y/ 100이 면적,100이 높이) ctx.fillRect(150,150,100,100); // x=150=, y=150초록색으로 사각형을 채움 ctx.clearRect(100,100,100,100); // 투명한 검은색으로 사각형을 채움 -> 결국엔 안보임 ![]() |
캔버스 영역전체를 지우려면
-> clearRect(0,0, canvas.width, canvas.height)
2-4) 그리기의 2가지 유형
- 즉시 그리는 방법
- 관련 함수를 호출하면 어떤 단계도 거치지 않고 바로 캔버스에 그림을 그리는 방법
-strokeRect(), fillRect(), clearRect(), strokeRect(), drawRect(), drawImage()
- 패스 path를 기반으로 그리는 방법
- 패스 -> 각 도형을 이루는 선("서브패스")들의 집합
2-5) 패스(path) 기반 그리기
- 패스 기반의 선/도형을 그리는 과정
1. 패스를 초기화 한다. -> beginPath() 메서드
2. 다양한 메서드를 사용해서 패스를 지정하고 선/도형을 그린다.
3. 지정한 패스를 닫는다. -> closePath() 에서드 (생략 가능)
4. 선이나 도형을 출력한다. -> stroke() 또는 fill() 메서드
beginPath() | 이전의 패스를 모두 지우고 새로운 패스를 그린다. |
closePath() | 현재 패스를 닫는다. (패스 그리는 것을 종료) |
moveTo(x,y) | 주어진 점을 시작으로 새로운 서브패스를 만든다. |
lineTo(x,y) | 바로 이전의 점(x1, y1)과 현재의 점(x2, y2,)을 연결하는 선을 그린다. |
rect(x,y,w,h) | 사각형을 그린다. |
arc(---) | 원/원호를 그린다. |
stroke() | 현재 패스에 있는 도형들을 선 스타일로 실제로 캔버스에 출력한다. (패스가 그려져도 현재는 안보이기에) |
fill() | 현재 패스에 있는 도형들을 채우기 스타일로 실제로 캔버스에 출력한다. |
2-6) 선 그리기

ctx. beginPath();
1) ctx.moveTo(x1,y1);
2) ctx.lineTo(x2,y2);
3) ctx. stroke();
예)
캔버스 영역: 250* 250, 선 두께:5px
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(200,200);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(200,50);
ctx.lineTo(200,200);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
ctx.stroke();
2-7) 다각형 그리기
- 방법1. 선들을 연결해서 연속적으로 그리는 방법
- 캔버스 영역: 200*200, 선 두께 : 3px, 선 색상: blue
ctx.beginPath(); //1
ctx. moveTo(100, 25); //2
ctx.lineTo(175,177);//3
ctx.lineTo(25, 175);//4
ctx.lineTo(100,25); //5
ctx.stroke(); // 삼각형 그림 //6
- 방법2. 선그리기 메서드 _ closePath()
- closePath() -> 셋 이상의 점을 가진 경우, 마지막 점과 첫번째 점을 연결하는 직선을 자동으로 추가하여 닫힌 모양의 도형을 만듬
ctx.beginPath();
ctx. moveTo(100, 25);
ctx.lineTo(175,177);
ctx.lineTo(25, 175);
ctx.closePath();// 위의 코드와 같으나 5번 라인이 사라지고 closePath()가 추가됨
ctx.stroke();
- 채우기 색상: green, 선 두께: 3px, 선 색상: blue
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(200,50);
ctx.lineTo(200,200);
ctx.lineTo(50,200);
ctx.closePath(); // 코드 하나 줄이고 처음의 꼭지점으로 가서 사각형 라인을 닫음
ctx.stroke();
ctx.fill();
2-8) 원/ 원호 그리기
- arc() 메서드
- arc( x, y , 반지름, 시작각도, 종료 각도, 그리는 방향);

- x, y 반지름 -> 원의 중심의 좌표와 반지름
- 시작각도, 종료각도 -> 라디안 단위 사용(360도 = 2π), 각도*Math.PI/180
- 그리는 방향
- false -> 기본값, 시계방향으로 그리는 경우
- true -> 시계반대방향으로 그리는 경우

- 중심 (100, 100), 반지름 75
ctx.beginPath();
ctx.arc(100,100,75, 0, 2*Math.PI, true) // '0'에서 '360'도 까지 한바퀴 돔, true 든 false 이든 어느 값 줘도 상관 없다.
ctx.stroke(); // ctx.fill(); 해주면 무슨 색상이 채워짐

중심(100,100), 반지름 75, 시작각도 135, 종료각도 315,
ctx.beginPath();
ctx.arc(100,100,75,135.Math.PI/180, 315*Math.PI/180, false);
ctx.stroke();
ctx.beginPath();
ctx.arc(100,100,75, 135*Math.PI/180, 315*Math.PI/180, false);

중심(100,100), 반지름 75, 각도(225,45), 그리는 방향 false 고정
ctx.beginPath();
ctx.arc(100, 100, 75, 225*Math.PI/180, 45*Math.PI/180, false);
ctx.stroke();
ctx.beginPath();
ctx.arc(100,100,75, 45*Math.PI/180, 225*Math.PI/180, false);
ctx.stroke();

ctx.beginPath();
ctx.arc(100, 100, 75, 0*Math.PI/180, 180*Math.PI/180, false);
ctx.fill();
ctx.beginPath();
ctx.arc(100,100,75, 90*Math.PI/180, 180*Math.PI/180, false);
ct.xfill();
ctx.beginPath();
ctx.arc(100,100,75, 180*Math.PI/180, 360*Math.PI/180, fasle);
ctx.fill();
2-9) 부채꼴 그리기
- moveTo() -> arc() -> closePath()

ctx.beginPath();
ctx.moveTo(100,100);
ctx.arc(100, 100, 75, 0, 90*Math.PI/180, true);
ctx.closePath(); // 중심좌표와 원호의 양끝점 연결함
ctx. stroke();
ctx.beginPath();
ctx.moveTo(110,110);
ctx.arc(110, 110,75, 0, 90*Math.PI/180, false);
ctx.closePath();
ctx.fill();
2-10) 직선과 접하는 원호 그리기
- moveTo(x,y) +arcTo(x1,y1,x2,y2, 반지름)

- moveTo(x, y) // 시작점
- 보조점 x1, y1
- 종료점 x2, y2
- 2개의 점과 원호에 해당하는 반지름 줌

ctx.beginPath();
ctx.moveTo(30,30);
ctx.arcTo(100,170, 180, 80, 50);
ctx.stroke();
ctx.fill(); // 하늘색으로 채워짐
2-11) 베지에 곡선 그리기 (2 가지 메서드)
- 베지에 곡선 Bezier Curve
- // 아무방향으로 가는 것을 제어한다. 제어점으로 가라, 지나지는 않고 진행방향 정보 제공
- n개의 점으로부터 얻어지는 (n-1)차 곡선 // 3개의 점이면 2차 곡선
- 2차 베지에 곡선: quadraticCurveTo(제어점x, 제어점y, 종료점x, 종료점 y)
- 3차 베지에 곡선: bezierCurveTo(제어점x, 제어점y, 제어점x2, 제어점y2, 종료점x, 종료점 y)
2차베지에곡선(A,B,C){ //시작점 A,제어점 B, 종료점 C D <- 선분 AB의 중점; E <- 선분 BC의 중점; F <- 선분 DE의 중점; F를 베지에 곡선 상의 한 점으로 저장; 2차베지에곡선(A,D,F); 2차베지에곡선(F,E,C); |

- D와 E의 중점 F
- ADF중점, CFE 중점 등 재귀적으로 계속 구함
- 점들 구할 수 도 있고 점들 쭉 연결하다 보면 곡선이 연결된다.

(2차 베지에 곡선)
ctx.beginPath();
ctx.moveTo(50,150);
ctx.quadraticCurveTo(130,50,180,180)
ctx.stroke();
- 점선은 이해를 위해 그려줌

(3차 베지에 곡선)
- 시작점에서 종료점까지 가는 곡선 그림
-이 제어점은 이 곡선이 지나가는 방향 정보 제공
- 순환적으로 중점 구함 -> 빨간 3차 베지에 곡선 구하는 게(아래)

ctx.beginPath();
ctx.moveTo(30,50);
ctx.bezierCurveTo(50,180,130,180,180,50);
ctx.stroke();
ctx.fill();
<정리하기>
- 캔버스개요
- 그림영역 지정+캔버스객체와 컨텍스트 객체생성
- 캔버스 작업의 기본 형태
- 선과 도형 그리기
- 사각형-> strokeRect(), fillRect(), clearRect()
- 선-> moveTo(), lineTo(), ----stroke();
- 다각형-> 선그리기 +closePath()
- 부채꼴 -> moveTo() -arc() -closePath();
- 직선과 접하는 원호 -> moveTo() +arcTo()
- 베지에 곡선 -> moveTo() + quadraticCurveTo(), moveTo() + bezierCurveTo()
'방송대_HTML5' 카테고리의 다른 글
HTML5_8강 SVG(Scalable Vector Graphic) (0) | 2021.10.06 |
---|---|
HTML5_7강) 캔버스(3) (0) | 2021.09.27 |
HTML5_6강) 캔버스(2) (0) | 2021.09.22 |