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

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