Canvas Day1
Canvas란
Canvas는 HTML5에서 새로 추가된 태그 중 하나로, 페이지에 그래픽 요소를 추가할 때 주로 사용된다. 기본적으로 width
, height
속성을 가지고 있는데 이는 레이아웃이 랜더링되어 있기 때문에 CSS로 임의로 크기를 지정할 경우 화면이 왜곡되어 보일 수 있어 비율을 맞춰주어야 한다.
아래 두개의 canvas는 겉으로 보기에는 같은 크기이나 실제 화면에 이미지를 그렸을 때 차이가 난다.
Canvas는 일반적인 이미지 속성과 같이 margin
, border
등을 줄 수 있지만 실제 캔버스에 그리는 그림에는 영향을 미치지 않는다.
<canvas id="board_canvas" width="500" height="500"></canvas>
기본적인 사각형 그리기
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(100, 100, 100, 100); //색 채워진 사각형
ctx.strokeRect(150, 150, 100, 100); // 테두리 가진 사각형
ctx.clearRect(30, 30, 100, 100); // 설정한 부분만큼 삭제
!
원그리기
원은 그냥 그릴 수 없고 arc()
라는 호 그리기 함수를 사용해서 사용해야 한다.
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.arc(100, 75, 50, 0, 2 * Math.PI); //(x, y, 반지름, 시작점, 끝점)
ctx.fill(); //ctx.stroke()
수학 그만둔지 너무 오래되서... 맨 마지막 끝점은 radian 단위로 들어가야 하는데(호로 원을 만든 것이기 때문이다!)360도가 2 * Math.PI
이고 만약 Math.PI
가 들어가면 반원이 된다.
함수로 만들어서 이해를 도운 버전
function radian(degree) {
return (degree * Math.PI) / 180;
}
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.arc(100, 75, 50, 0, radian(320)); //(x, y, 반지름, 시작점, 끝점)
ctx.stroke(); //ctx.stroke()
이제 무엇이든 그릴 수 있을 것 같지만 사실 이거 한 붓 그리기다. 만약 다음과 같은 코드를 짠다면 붓을 떼는 동작을 지정해 주지 않았기 때문에 다음과 같은 그림이 나온다.
function radian(degree) {
return (degree * Math.PI) / 180;
}
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.arc(100, 75, 50, 0, radian(320));
ctx.arc(200, 75, 50, 0, radian(320)); //(x, y, 반지름, 시작점, 끝점)
ctx.stroke(); //ctx.stroke()
그러므로 이것을 한 붓 그리기로 하지 않기 위해서는 시작 지점을 ctx.beginPath()
를 통해 매 번 다시 지정해 주어야 한다.
function radian(degree) {
return (degree * Math.PI) / 180;
}
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.beginPath(); //시작점 그려!
ctx.arc(100, 75, 50, 0, radian(320)); // 위치!
ctx.stroke();// 위에 쓴대로 그려!
ctx.beginPath(); // 여기서 다시 시작!
ctx.arc(200, 75, 50, 0, radian(320)); // 위치2222
ctx.stroke(); // 다시 그려!
이거 좀 성가시지 않나..? 좀... 너무.... 노가다 아닌가...?
애니메이션 만들기 : x축 따라 날라가는 공
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
let xPos = 10;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // 전체 지우기
ctx.beginPath(); //새로 그리기~
ctx.arc(xPos, 150, 20, 0, Math.PI * 2);
ctx.fill();
xPos += 3;
requestAnimationFrame(draw); //루프를 통해 매번 새로그림
}
draw(); // or setInterval(draw, 10) => 최적화 및 프레임 유실 xxx
함수로 더 느리게 가게 한 버전
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
let count = 0;
let xPos = 10;
function draw() {
if (count % 3 === 0) {
ctx.clearRect(0, 0, canvas.width, canvas.height); // 전체 지우기
ctx.beginPath(); //새로 그리기~
ctx.arc(xPos, 150, 20, 0, Math.PI * 2);
ctx.fill();
xPos += 3;
}
count++;
requestAnimationFrame(draw); //루프를 통해 매번 새로그림
}
draw();
날아가는 공 멈추게 하기
//방법 1
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
let xPos = 10;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // 전체 지우기
ctx.beginPath(); //새로 그리기~
ctx.arc(xPos, 150, 10, 0, Math.PI * 2);
ctx.fill();
xPos += 1;
if (xPos >= canvas.width - 10) {
return; // return 해줌으로서 밑의 request...가 실행 안됨
}
requestAnimationFrame(draw); //루프를 통해 매번 새로그림
}
draw();
//방법 2
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
let xPos = 10;
let time;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // 전체 지우기
ctx.beginPath(); //새로 그리기~
ctx.arc(xPos, 150, 10, 0, Math.PI * 2);
ctx.fill();
xPos += 1;
time = requestAnimationFrame(draw); //루프를 통해 매번 새로그림
if (xPos >= canvas.width - 10) {
cancelAnimationFrame(time);
}
}
draw();
클릭했을 때 멈추게 하기
var canvas = document.getElementById("board_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
let xPos = 10;
let time;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // 전체 지우기
ctx.beginPath(); //새로 그리기~
ctx.arc(xPos, 150, 10, 0, Math.PI * 2);
ctx.fill();
xPos += 1;
time = requestAnimationFrame(draw); //루프를 통해 매번 새로그림
}
draw();
canvas.addEventListener("click", () => {
cancelAnimationFrame(time);
});
'front-end > html&css' 카테고리의 다른 글
[CSS] position: absolute인 아이템 가운데 정렬하기 (0) | 2021.07.20 |
---|---|
[Canvas 공부 2일차] 이미지 업로드 (0) | 2020.12.07 |
[css] display:block과 visibility:none의 차이 (0) | 2020.08.01 |
[프론트엔드 개발자 면접 문제 02] 인라인 요소와 블록 요소 (0) | 2020.06.28 |
[css] 반응형 레이아웃을 위한 flexbox 알아보기 (브라우저별 flexbox 사용하기) (0) | 2020.04.23 |
댓글