본문 바로가기

Ecmascript/Canvas

캔버스 #01 그리기와 애니메이션 원리

캔버스

사이즈 설정

<style>
.canvas {width: 500px;height: 300px;background: #eee;}
</style>
<canvas class="canvas canvas2" width="1000" height="600"></canvas>
  • 캔버스 태그의 크기는 css가 아닌 속성으로 넣어줘야 정확하다.
  • 레티나 디스플레이에서 또렷하게 보이게 하기 위해 속성으로 크기 2배로 설정하고 CSS로 절반으로 줄여서 만드는 방법이 가능하다.
  • ex) 풀사이즈라면 윈도우 사이즈를 구해서 2배로 하고 CSS로 100%를 준다.

fillStyle = 'color'

  • 그릴 도형에 칠할 색을 선택
  • 색상명 규칙은 CSS와 동일(name, rgba, #16진수)
  • 도형을 그리기전에 먼저 붓에 물감은 바른다는 개념으로 이해 할 것

fillRect(x, y, width, height)

  • 색칠한 도형을 그린다.
  • 이전에 색을 고르지 않았다면 기본색은 black

clearRect(x, y, width, height)

  • 색칠한 도형에 색을 지움

strokeRect(x, y, width, height)

  • 선으로 그림
const canvas = document.querySelector(".canvas");
const context = canvas.getContext('2d');

context.fillRect(50,50,100,100);
context.fillStyle='red'; // 색 지정안하면 기본색은 까만색
// context.fillStyle='rgba(0,0,0,0.5)';
context.fillRect(0, 0, 100, 100);
context.clearRect(80, 80, 50, 50);

context.strokeRect(150,150,100,100);

직선

beginPath();

  • 그릴 준비 한다.

moveTo(x, y);

  • 붓을 옮긴다.

lineTo(x, y);

  • 선을 긋는다.

stroke();

  • 그른 선대로 그린다.
const canvas = document.querySelector(".canvas");
const context = canvas.getContext('2d');

context.beginPath();
context.moveTo(100, 100); // 붓을 100, 100으로 옮긴다.
context.lineTo(300, 200); // 선을 그린다.
context.stroke(); // 선을 보여준다.

곡선

arc(x, y, radius, Math.PI / 180 * startAngle, Math.PI / 180 * endAngle, anticlockwise);

  • x, y, 반지름, 시작각도, 끝각도(호도각 표기), 반시계방향
  • 호도법 설명 사이트 : https://mathbang.net/496
  • 그리는 방식은 직성이랑 같다(beginPath()로 시작 stroke();로 그리기)
function radian(angle) {
  return angle * Math.PI / 180 
}
const canvas = document.querySelector(".canvas");
const context = canvas.getContext('2d');

context.beginPath();
// x, y, 반지름, 시작각도, 끝각도(호도각 표기), 반시계방향 
context.arc(300, 200, 50, 0, radian(360), true);
context.stroke();
context.beginPath(); // 패스를 새로 시작하지 않으면 한붓그리기가 된다.
context.arc(500, 100, 20, 0, radian(360), true);
context.stroke();   

애니메이션

  • 싹 지우고 옮긴 위치로 그리고를 계속 반복하는 방식(즉 한 프레임을 계속 반복)
  • requestAnimationFrame(callback) : 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출 -> 리페인트 이전에 실행할 콜백을 인자로 받음
  • setInterval(callback, time) : 느려서 안씀
const canvas = document.querySelector(".canvas");
const context = canvas.getContext('2d');
let xPos = 10;
let count = 0;

function draw() {
  count++;

  if(count%30 === 0){
    // 기존 원 지우기 : 빼먹으면 잔상 다 그려짐
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.beginPath();
    // 새로 원 그리기
    context.arc(xPos, 150, 5, 0, Math.PI*2, false);
    context.fill();
    xPos += 5;
  }

  // 그릴 함수를 콜백으로 계속 호출한다.
  requestAnimationFrame(draw);
}

draw();

https://modernizr.com/

  • 지원하는 브라우저 판별 스크립트 소스 만들어주는 사이트
if (Modernizr.canvas) {
    console.log('Canvas를 지원하는 브라우저');
}