1. <canvas></canvas>
캔버스 태그는 HTML에서 개발자가 지정한 모양의 그림을 그리거나 표현하는 태그이다.
해당 기능을 CSS로 소개하는 경우도 있으나 캔버스 태그를 다루는 방법이나 개념은 자바스크립트에 가깝다.
캔버스 태그는 해당 태그 자체에 다양한 문자 데이터를 가지고 있다. 이 문자 데이터에 입력된 값에 따라 화면에 ‘그림’이 표현된다.
이러한 개념을 컨텍스트라고 하는데, 이미지를 글로 표현하는 것이다.
이 컨텍스트는 본래 문자들의 집합인 프로그래밍 언어에서 그림을 표현하기 위한 기법이라는데 의의를 가진다.
파이썬이나 자바로 GUI(그래픽 유저 인터페이스)를 구현할 때도 적용되는 방식이다.
2. 사용방법: 컨텍스트 추출
우선 <body></body> 태그 안에 <canvas></canvas> 태그를 생성한다.
그 후 자바스크립트를 이용해 캔버스에 부여된 요소를 가져온다.
var canvas=document.getElementById("can");
해당 요소에서 컨텍스트 정보를 추출한다.
var ctx=canvas.getContext("2d");
컨텍스트 정보를 추출하는 것이 중요한 이유는 Element 에서 그림에 대한 값을 직접 컨트롤하기 어렵기 때문이다.
캔버스의 크기는 Element 에서 컨트롤 하는 것이 맞지만, 그 안에 그려지는 그림은 컨텍스트를 이용해야 한다.
(덧붙여 Canvas 태그의 Default 사이즈는 300*150px이다. Element 에서 조정이 가능하다. Style 을 이용해 사이즈를 변경하면 그림이 깨지기 때문에 주의하자.)
3. 컨텍스트를 조정하는 다양한 데이터
컨텍스트는 객체로 화면이나 데이터의 구성 성분이다.
설계도의 요약문으로 이해할 수 있다.
물론 실제 설계도는 개발자가 쓴 코드이지만 이 구성 성분을 조정하면 설계도를 통해 표현되는 객체를 조정할 수 있다.
태그 | 내용 |
ctx.fillStyle="color"; | 속을 채울 때 쓸 색상을 미리 color로 지정, color는 rgba 또한 사용이 가능하다. |
ctx.fillRect(x,y,width,height); | fillRect(기준 x, y, 너비, 높이); |
ctx.clearRect(x,y,width,height); | 사각형을 그려 그림을 지운다.(==배경색과 같음) |
ctx.beginPath(); | 선을 그리는 기능, 시작점 |
ctx.closePath(); | 선을 그리는 기능, 끝지점 |
ctx.moveTo(x,y); | (x,y) 위치를 이동, 해당 지점부터 선을 그린다. |
ctx.lineTo(x,y); | 현재 위치에서 (x,y)까지 직선을 표기 |
ctx.stroke(); | lineTo 로 그린 직선을 채운다. |
ctx.rect(x,y,width,height); | x, y를 기준으로 시작해서 너비와 높이를 가진 사각형을 그린다. |
ctx.arc(x,y,r,angle, Math.PI*2, false); | arc(중심 x, 중심 y, 반지름, 시작각도, 끝각도, 반시계 여부-외각 내각); 시계 방향이 원칙이다. Math.PI{1파이=180도이고, 회전 방향을 반대로 하고 싶다면 값을 true로 한다. ex) ctx.arc(350,200, 20, 0, Math.PI*2, false); |
ctx.quadraticCurveTo(제어점 x, 제어점y, 종료점 x, 종료점 y) | Quadratic 곡선: 2차함수 곡선을 그린다. |
ctx.bezierCurveTo(제어 1x, 제어 1y, 제어 2x, 제어 2y, 종료x, 종료 y) | Bezier 곡선: 베지어 곡선을 그린다. |
베지어 곡선과 2차함수 곡선은 모양을 직접 보고 이해하자.
4. 캔버스를 이용해서 공튀기기 만들기
1) 동작을 위한 인풋 데이터를 확정한다. (클릭 혹은 키보드)
클릭이라면 이벤트리스너로 클릭에 대한 동작을 정의하면 된다. 키보드라면 키보드의 값을 받아 해당 ‘키’에 대한 동작을 if문으로 하여 입력에 따라 화면이 변하게 한다.
2) 인풋 데이터에 대해 어떤 변화를 줄것인지 정의한다.
공이 움직이게 한다면 인풋 데이터에 따라 x와 y가 변하고 이 모양으로 다시 그림을 그린다. 쉽게 말해 기존에 그려진 그림을 ‘지우고’ 지운 뒤에 입력받은 데이터에 대응하여 ‘다시 그리는 것’이다.
3) 공의 움직임에 따라 캔버스에 대한 상한값을 정한다.
공튀기기라면 특정 값에 ‘도달’하면 반대로 돌아가야한다. 때문에 check를 위한 메소드를 정의해야한다.
4) 움직임을 위해 특정 주기로 함수가 수행되도록 한다.
동적인 움직임을 보여줘야하는 요소가 있다면 특정 주기로 그림을 다시 그려주며 이를 표현하면 된다.
이때는 setInterval(function, 시간); 을 이용한다.
위의 조건에 맞게 값을 설정하고 변수와 함수를 정의하면 공튀기기를 만들 수 있다.
1차 함수에 기준으로 하였으나 베지어 곡선을 함수로 이용하면 더욱 자연스럽게 구현이 가능하다.
5. 자동으로 튀겨지는 공 소스코드
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>공튀기기</title>
<style>
canvas{
border: 1px solid gray;
}
</style>
</head>
<body>
<canvas id="can">
</canvas>
<script>
var canvas=document.getElementById("can");
var ctx=canvas.getContext("2d");
canvas.width=600;
canvas.height=600;
var x = 20; // 공의 x좌표
var vx = 2; // 공의 x rkthreh
var y = 20; // 공의 y좌표
var vy = 5; // 공의 y 가속도
// 공의 가속도를 이용해서 각도와 속도를 조절할 수 있다.
var r = 20; // 공의 반지름
ctx.beginPath();
ctx.arc(x,y,20,0,Math.PI*2,false);
ctx.fillStyle="crimson";
ctx.fill();
ctx.beginPath();
//setInterval(function, 시간);
//시간/1000 초마다 해당 함수를 실행한다.
function box_check(){
if(y>(canvas.height-r)||y<r){
vy*=-1;
}
if(x>canvas.width-r||x<r){
vx*=-1;
}
} //공과 박스의 상호작용
function move(){
ctx.beginPath();
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.arc(x,y,r,0,Math.PI*2,false);
ctx.fillStyle="crimson";
ctx.fill();
ctx.closePath();
x += vx;
y += vy;
box_check();
}
setInterval(move, 20);
</script>
</body>
</html>
6. 키보드로 조작하는 공 소스코드
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>키이벤트</title>
<style>
canvas{
border: 1px solid gray;
}
</style>
</head>
<body>
<canvas id="can"></canvas>
<script>
var canvas=document.getElementById("can");
var ctx=canvas.getContext("2d");
canvas.width=600;
canvas.height=600;
ctx.beginPath();
ctx.arc(20,20,20,0,Math.PI*2, true);
ctx.fillStyle="skyblue";
ctx.fill();
ctx.closePath();
//addEventListener(String, function);
//특정 상황에서 특정 동작을 수행하도록 함
window.addEventListener("keydown",move);
var x = 20;
var vx = 5;
var y = 20;
var vy = 5;
function move(e){
var code = e.keyCode;//동작을 유발시킨 키의 번호
console.log(code);
if(code==39){
x+=vx;
}
if(code==37){
x-=vx;
}
if(code==38){
y-=vy;
}
if(code==40){
y+=vy;
}
ball();
}
function ball(){
ctx.beginPath();
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.arc(x,y,20,0,Math.PI*2,true);
ctx.fillStyle="skyblue";
ctx.fill();
ctx.closePath();
}
</script>
</body>
</html>
부록. 컨텍스트 arc의 원리 (발그림 주의)
'JavaScript > 기본 이론' 카테고리의 다른 글
Chapter 13. 객체의 이해 (0) | 2021.11.29 |
---|---|
Chapter 12. 변수와 호이스팅 (0) | 2021.11.28 |
Chapter 10. function (0) | 2021.11.26 |
Chapter 09. 동작에 따라 데이터를 변화시키는 방법 (0) | 2021.11.25 |
Chapter 08. 데이터를 추출하는 방법 (DOM 기초 2) (0) | 2021.11.24 |