본문으로 바로가기

HTML5 Canvas 생성 및 그리기

category 📈 js 그래픽/🎨 Canvas 2020. 7. 18. 01:40
 

캔버스 튜토리얼

이 튜토리얼은 canvas 요소를 사용하여 2D 그래픽을 어떻게 그리는지 기초부터 설명합니다. 예제들을 통하여 캔버스로 할 수 있는 것이 무엇인지 알려주며, 바로 사용할 수 있도록 코드도 제공합��

developer.mozilla.org

 

canvas는 주로 브라우저에서 2D 그래픽에 중점을 두고 있다. 3D 지원을 위한 webGL도 근본은 canvas이다.

canvas를 사용하면 조금 더 인터렉티브하고 화려한 웹을 구현할 수 있다.

 

사용도 그냥 canvas 태그를 쓰면 된다. 맨 처음 생성하면 투명하게 보이니 백그라운드 컬러를 주고 시작하자.

<canvas id="canvas"></canvas>

 

- modernizr 체크 (이 브라우저는 캔버스를 지원하는가?)

 

https://modernizr.com/

 

특정 기능을 브라우저에서 지원하는 지 체크할 수 있는 도구이다. 필요한 기능을 선택하고 build를 누르면 된다.

 

빌드된 내용을 파일에 넣고 html 상에서 불러와서 사용하시면 됩니다.

Modernizr.canvas 를 찍어서 지원하면 true, 지원하지 않으면 false를 반환합니다.

 

굳이 modernizr가 아니라 직접 사용해보는 방식으로 체크해 볼 수도 있습니다.

canvas Dom을 가져와서 getContext 메서드를 사용해보고, 사용이 되면 캔버스를 지원하는 것으로 간주하는 것입니다.

 

둘 중 편한 방법으로 하시면 됩니다. 저는 아무래도 모더나이저를 안 쓰는 게 좋아보입니다만, 많은 기능이 들어가는 환경에서는 모더나이저를 쓰는 것이 좋을 듯 싶습니다.

<!DOCTYPE html>
<html>
  <head>
    <script src="./modernizr.js"></script>
  </head>

  <body>
    <canvas>이 브라우저는 캔버스를 지원하지 않습니다.</canvas>

    <script>
      // Canvas 지원 여부 확인
      if (Modernizr.canvas) {
        // console.log('Canvas를 지원하는 브라우저');
      }

	  // canvas를 가져와서 사용해보는 방식으로 체크할 수 있습니다.
      const canvas = document.querySelector("canvas");
      if (canvas.getContext) {
        console.log("캔버스 지원");
      }
    </script>
  </body>
</html>

 

 

 

 - 캔버스 사이즈 설정과 해상도

 

html에 직접 줄 수도 있고, css에 줄 수도 있습니다. 둘 다 줄 경우도 많습니다.

css는 캔버스의 크기를 정의하고 html의 속성은 픽셀의 직접도를 결정합니다.

 

<style>
  body {
    margin: 0;
  }
  .canvas {
    width: 500px;
    height: 300px;
    background: #eee;
  }
</style>

<canvas class="canvas" width="500" height="300"></canvas>
<canvas class="canvas canvas2" width="1000" height="600"></canvas>
<script>
  const canvas = document.querySelector(".canvas");
  const canvas2 = document.querySelector(".canvas2");
  const context = canvas.getContext("2d");
  const context2 = canvas2.getContext("2d");
  
  context.arc(100, 100, 50, 0, Math.PI * 2, false);
  context2.arc(100, 100, 50, 0, Math.PI * 2, false);
  context.fill();
  context2.fill();
</script>

 

위 코드를 보시면 css로 같은 넓이, 높이를 주었기 때문에 크기는 똑같습니다만, 좌측 캔버스의 직접도가 더 높기 때문에 같은 크기의 원을 그려도 원이 작게 보입니다.

 

이런 식으로 구현하는 이유는 고해상도 화면에서도 선명하게 보기 위해서입니다.

일반적으로 선명도를 위해 캔버스 크기의 2배를 html상의 가로, 세로 길이에 줍니다. (JS를 사용해야 합니다)

 

(카메라 잡던 시절을 떠올려보면, 4K로 촬영해도 fhd로 압축해서 내보내면, 더 선명해보이는 그런 효과입니다.)

 

- 캔버스에 그리기

보통 일러스트레이터를 이용해서 이미지를 가져다 쓰는 것이 일반적입니다.

 

 

문서가 잘 되어 있으므로 언급하지 않은 내용들은 해당 문서를 참고해보면 된다.

(https://developer.mozilla.org/ko/docs/Web/HTML/Canvas/Tutorial/Drawing_shapes)

 

 

캔버스를 사용하기 위해서는 캔버스 객체를 먼저 가져온 후, context를 등록해줘야 합니다.

context를 콘솔에 찍어보면 CanvasRenderingContext2D로, 이 객체 안에 우리가 사용할 메서드나 속성들이 존재합니다.

// canvas 가져오기
const canvas = document.querySelector(".canvas");

// context 등록!
const context = canvas.getContext("2d");

 

 

사각형

 

fillRect, clearRect, stokeRect

 

* x, y 좌표는 한 가운데가 아니라 항상 왼쪽 상단 끝을 의미함.

// 사각형 그리기
context.fillRect(25, 25, 50, 50);

// 스타일 적용
context.fillStyle = "#ff9999";
context.fillRect(0, 0, 50, 50);

// 투명한 사각형 그리기 (구멍 뚫기)
context.clearRect(10, 10, 25, 25);

// 외곽선 사각형 그리기
context.strokeRect(5, 5, 100, 100);

 

path 그리기

 

조금 복잡합니다. path를 그릴 것이다, 여기서 시작할 것이다, 여기까지 그릴 것이다. 무엇으로 그릴 것이다를 지정해줘야 합니다.

 // path를 그릴겁니다.
 context.beginPath();
 
 // 여기에서 시작할 것입니다.
 context.moveTo(100, 100);
 
 // moveTo에서 시작해서 lineTo까지 그릴 겁니다.
 context.lineTo(300, 200);
 
 // stoke로 그릴겁니다
 context.stroke();
 
 // path 그리기를 끝냄
 context.closePath();

 

 

 

arc를 이용한 원 그리기

 

arc. 즉, 호를 정의함으로써 원을 그릴 수 있습니다.

 

* x, y 좌표는 원 중앙을 의미함.

anticlockwise 변수는 true일 때 호를 반시계 방향으로 그리게 되며, 그렇지 않을 경우에는 시계 방향으로 그리게 됩니다.

또, arc도 path이기 때문에 fill을 하더라도 꼭 beginPath와 closePath를 적용해줍니다.

 

// x 좌표, y 좌표, 반지름, 시작 라디안, 끝 라디안, 방향
arc(x, y, radius, startAngle, endAngle, anticlockwise)

 

중요한게, 각도가 아니라 라디안 값을 줘야 한다.

const canvas = document.querySelector(".canvas");
const context = canvas.getContext("2d");

function radian(angle) {
  return (angle * Math.PI) / 180;
}

// 360도가 아니라 라디안 값을 넣어줘야 함
context.beginPath();
context.arc(300, 200, 50, 0, radian(360));
context.stroke();
context.closePath();

// path가 아니라 fill을 줄수도 있음
context.arc(300, 200, 50, radian(120), radian(360), false);
context.fill();

// anticlockwise 변수는 true일 때 호를 반시계 방향으로 그리게 되며, 그렇지 않을 경우에는 시계 방향으로 그리게 됩니다.
context.arc(300, 200, 50, radian(120), radian(360), true);
context.fill();

 

호를 그린 후 fill 해주었더니 피자 조각 모양이 아니라 호의 처음과 끝을 연결하고 색칠한 모양이 나와버렸습니다.

그러니까 부채꼴이 아니라 활꼴이 나와버린 거죠.

 

부채꼴을 그리고 싶다면 arc만으로는 안됩니다. 호의 끝좌표와 처음 좌표를 알아내서 path를 따로 그려줘야 합니다...

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체