Wesbos - Fun with Canvas


캔버스 활용하기

🙂 사실 그렇게 자주 사용할것 같지는 않지만, 배워두면 좋을 것 같은 ..?
Javascript를 이용한 그리기 도구 기능 구현 챕터다

로직

  1. canvas태그를 통해 그림판을 브라우저에 깔아준다
  2. canvas의 개념적 정의를 ‘2d’로 설정한다 : canvas.getContext(‘2d’)
  3. canvas에 이벤트리스너를 부여한다.
  4. 캔버스 내에서 마우스 움직임에 따라 그림이 그려질 수 있도록 ctx설정을 한다 (그리기 속성과 위치값 설정)

그림판 깔기

canvas 태그

💡 <canvas></canvas>와 같은 형태로 쓰이며, id값을 부여해 사용해주는 것이 바람직하다.

canvas태그에 id값을 #draw로 부여해뒀다. 이를 활용!

1
2
3
4
5
const canvas = document.querySelector('#draw');

//그림판 캔버스가 브라우저 전체 크기를 차지할 수 있도록 설정
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

canvas태그 불러오기 및 기본설정 (렌더링 컨텍스트)

💡 canvas만 브라우저에 펼쳐져 있다고 그림을 그릴 수 있는게 아니다.

**getContext()**를 통해 렌더링 컨텍스트까지 canvas에 노출시켜줘야
그리기 함수나 렌더링 컨텍스트 등을 활용할 수 있다.

그리기 도구를 지정해준다고 생각하면 이해하기 편할 것이다.

1
const ctx = canvas.getContext('2d');

이벤트리스너 적용 및 함수 생성

💡 canvas가 이벤트를 감지할 수 있도록 addEventListener와 그에 따른 함수를 생성해줘야 한다.

1
2
//마우스의 움직임을 감지
canvas.addEventListener('mousemove', draw);

💡 이제 draw함수를 생성해보자 !

1
2
//일단 만들어만 놓자
function draw() {}

ctx를 통한 그리기 속성 세팅

💡 그림을 그려야하기 때문에, 먼저 그리기 도구들을 세팅해주자

ctx세팅을 위한 함수 및 기능들은 아래 표에 정리해두었다.

1
2
3
4
ctx.strokeStyle = '#BADA55';
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.lineWidth = 50;

ctx

ctx를 통한 위치값 설정 및 그리기 기능 구현

💡 거의 다 왔다…..

이제 그림을 그릴 수 있도록 xy 좌표값과 그에 해당하는 기본 변수값들을 지정해줘야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//마우스를 클릭한 상태로 움직였을 때만 그리기가 가능하도록 isDrawing을 설정해줬다.
let isDrawing = false;
let lastX = 0;
let lastY = 0;

function draw(e) {
//마우스를 뗀 상태라면 그려지지 않는다
if (!isDrawing) return;
ctx.beginPath(); //새로운 경로가 생성된다.
ctx.moveTo(lastX, lastY); //마우스가 눌린 시점의 x,y의 좌표가 입력될 것이다.
ctx.lineTo(e.offsetX, e.offsetY); //마우스가 이동한 위치의 좌표가 입력될 것이다.
ctx.stroke(); //도형(선 포함)이 그려진다.
//마우스 움직임에 따라 lastX와 lastY값 지속적으로 변동
[lastX, lastY] = [e.offsetX, e.offsetY];
}
1
2
3
4
5
6
7
8
9
//마우스를 눌렀을 때 x와 y값이 입력되도록 설정!
canvas.addEventListener('mousedown', (e) => {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
});

//마우스가 눌려있지 않은 경우에 그리기를 실행하지 않기 위한 설정
canvas.addEventListener('mouseup', () => (isDrawing = false));
canvas.addEventListener('mouseout', () => (isDrawing = false));

offsetX & offsetY

💡 offsetX : 이벤트의 대상이 되는 객체 내에서의 상대적 마우스 “x좌표” 위치를 나타냄

offsetY : 이벤트의 대상이 되는 객체 내에서의 상대적 마우스 “y좌표” 위치를 나타냄


최종 완성 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const canvas = document.querySelector('#draw');

const ctx = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

ctx.strokeStyle = '#BADA55';
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.lineWidth = 50;

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

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

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

Author

Hoonjoo

Posted on

2022-01-04

Updated on

2022-02-07

Licensed under

Comments