본문 바로가기
방송대_HTML5

HTML5_5강) 캔버스(1)

by dot_Connector 2021. 9. 18.

*여기에 있는 내용은 제가 복습차,  방송대 컴퓨터 과학과 HTML5 이관용 교수님의 PPT 수업 내용을 참조하여 정리함을 알립니다. 

 

1) 캔버스 개요

 

  • 캔버스? 웹페이지에서 자바스크립트 코드로 브라우저에 그림을 그리는 기능

- 별도의 프로그램 설치 없이 사용가능

- 단순히 그림을 표현하는 기능 이외에 그림의 합성, 변환, 애니메이션과 같은 다양한 효과의 표현도 가능

 

  • 그림을 그리기 위해서는 
  1. canvas 요소를 사용해서 그림이 그려질 영역 지정: canvas 요소 -> 단순히 그림을 담는 컨테이너
  2. 자바스크립트 코드를 사용해서 해당 영역에 실제 그림을 그린다. 

캔버스의 좌표시스템

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