본문 바로가기

개발/JavaScript 30

8. Fun with HTML5 Canvas

반응형

코드 분석

<!DOCTYPE html>

<html lang="en"> <head> <meta charset="UTF-8"> <title>HTML5 Canvas</title> </head> <body> <canvas id="draw" width="800" height="800"></canvas> <script> </script> <style> html, body { margin:0; } </style> </body> </html>

목표

클릭 후 드래그할 때 색이 변하고 두께가 커졌다 작아졌다를 반복하는 선을 만들어보자.

분석

이번에는 개요를 나누다가는 조금 더 번잡해질 수 있기 때문에 강의에 나온 순서대로 풀어가면서 해보겠다.

const canvas = document.querySelector('#draw');
const ctx = canvas.getContext('2d');

가장 먼저 해야하는 일은 이 두가지이다.
우리의 목표가 화면 내에서 클릭을 통해 선을 그려내는 것이기 때문에 그에 대한 기본적인 틀을 만들어 주어야 한다.

위의 코드처럼 적어주면, 이것은 2D코드를 사용하여 캔버스의 컨텍스트를 가져오고 이렇게 되면 캔버스에 대한 2D 렌더링 컨텍스트가 생겨서 그 안에 그릴 수가 있게 되는 것이다.
(자세한 내용은 여기를 참고)

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.strokeStyle = '#BADA55';
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.lineWidth = 100;


let isDrawing = false;
let lastX = 0;
let lastY = 0;
let hue = 0;
let direction = 0;

먼저, canvas.width와 canvas.height를 window 에 연결해줌으로써 창의 크기가 변화하더라도 그 전체 화면내에서 그릴 수 있도록 한다.
나머지 내용은 뒤에서 나올 내용들의 초석이라고 볼 수 있다.

function draw(e) {
  if (!isDrawing) return; 
  console.log(e);
  ctx.strokeStyle = `hsl(${hue}, 100%, 50%)`;
  ctx.beginPath();
  ctx.moveTo(lastX, lastY);
  ctx.lineTo(e.offsetX, e.offsetY);
  ctx.stroke();
  [lastX, lastY] = [e.offsetX, e.offsetY];

  hue++;
  if (hue >= 360) {
    hue = 0;
  }
  if (ctx.lineWidth >= 100 || ctx.lineWidth <= 1) {
    direction = !direction;
  }

  if(direction) {
    ctx.lineWidth++;
  } else {
    ctx.lineWidth--;
  }

}

여기서 if문으로 시작한 것은 위에서 정의했던 isDrawing과 연결 해놓음으로써 클릭을 하지 않을 때는 함수를 실행하지 않는다는 것을 먼저 선언해 두는 것이다.
아래 .beginPath는 ‘선을 만들겠다’ 라 하고
.moveTo(a, b)로 가로, 세로 시작점, .lineTo(a', b')로 가로, 세로 끝점을 잡고
.stroke()로 선을 시각화 시키는 과정이다.
(참고자료)

그 다음 코드를 보면, hue++;에 따라 드래그를 할때마다 hue의 값이 커지고
그 값이 .strokeStyle의 hsl의 첫번째 값에 들어감에 따라 색상이 무지개색을 따라 보라색으로 향한다. 

그리고 보라색의 hsl첫번째 값이 360 이므로 보라색이 되면 다시 빨간색부터 시작하도록 if 문을 걸어준 것이다.

먼저 맨 아래의 if문과 그 위의 if문은 보다시피 direction이 참일 경우 lineWidth를 계속 증가시키고, 아닐 경우 감소시키는 아래의 if문에 의해 lineWidth를 늘렸다가 줄였다가 할 수 있도록 해준다.

canvas.addEventListener('mousedown', (e) => {
  isDrawing = true;
  [lastX, lastY] = [e.offsetX, e.offsetY];
});


canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);

이후, 마우스 움직임에 관련된 이벤트리스너를 지정하고
'mousedown'에 대한 이벤트를 지정하여 시작점을 자유롭게 만들어준다.
그리고 그 외 'mouseup'이나 'mouseout'에 대해서는 선이 나타나지 않도록 정의해 준 내용이다.

정리

내가 공부한 내용을 강의 흐름에 따라 정리하고는 있지만 뭔가 비효율적인 것 같다.
계속해서 테마나 정리 방향에 대해서 고민하고 고쳐봐야겠다.
끝.

반응형

'개발 > JavaScript 30' 카테고리의 다른 글

11. Custom Video Player  (0) 2017.04.18
10. Hold Shift and Checkboxes  (0) 2017.04.14
9. Dev Tools Domination  (0) 2017.04.13
7. Array Cardio Day 2  (2) 2017.04.11
5. Flex Panel Gallery  (0) 2017.04.07