๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
JavaScript/Vanilla JS

[๋ฐ”๋‹๋ผJS๋กœ ๊ทธ๋ฆผํŒ ๋งŒ๋“ค๊ธฐ] 2D Context

by ์ฝ”๋”ฉํ•˜๋Š” ๋ถ•์–ด 2021. 4. 25.
๋ฐ˜์‘ํ˜•

[์ถœ์ฒ˜-์œ ํŠœ๋ธŒ ๋…ธ๋งˆ๋“œ ์ฝ”๋” Nomad Coders]

https://youtu.be/IlANstQ1h3M

 

MDN์„ ํ†ตํ•ด์„œ canvas์— ๋Œ€ํ•ด ๋ฐฐ์›Œ๋ณด์ž!

 

ํ•„์š”ํ•œ๊ฑด ์ด ์‚ฌ์ดํŠธ์— ๋‹ค ์žˆ๋‹ค.

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D

 

CanvasRenderingContext2D - Web APIs | MDN

CanvasRenderingContext2D The CanvasRenderingContext2D interface, part of the Canvas API, provides the 2D rendering context for the drawing surface of a element. It is used for drawing shapes, text, images, and other objects. See the interface's properties

developer.mozilla.org

 

 

canvas๋Š” context๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” HTML์˜ ํ•œ ์š”์†Œ์ด๋‹ค.

์šฐ๋ฆฌ๋Š” ๊ทธ ์š”์†Œ ์•ˆ์—์„œ pixel๋“ค์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.๊ทธ๋ž˜์„œ canvas๋ฅผ ํฌ๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•จ

 

์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผํ• ๊ฑด context variable์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

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

 

 

๊ทธ ๋‹ค์Œ์—” context์˜ default๋ฅผ ์„ค์ •ํ•œ๋‹ค.

context๋Š” lineWidth๋„ ์žˆ๊ณ  fill๋„ ์žˆ๊ณ  strokeStyle๋„ ์žˆ๋‹ค.

๋จผ์ € strokeStyle์„ ์ถ”๊ฐ€ํ•˜์ž.

์ด๊ฑธ ์‚ฌ์šฉํ•˜๋ ค๋Š” ์‚ฌ๋žŒ์ด ์ฒซ ๋ฒˆ์งธ ์ƒ‰(๊ฒ€์ •์ƒ‰)์œผ๋กœ ์‹œ์ž‘ํ•˜๋„๋ก ์„ค์ •ํ•œ๋‹ค.

ctx.strokeStyle = "##2c2c2c";

 

 

lineWidth(๊ตต๊ธฐ ์กฐ์ •)์„ ์„ค์ •ํ•ด์ค€๋‹ค.

ctx.lineWidth = 2.5;

 

 

startPainting์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค.

function startPainting() {
    painting = true;
}

 

 

์ฝ”๋”ฉ์ค‘..

if(canvas) {
    canvas.addEventListener("mousemove", onMouseMove);
    canvas.addEventListener("mousedown", startPainting);
    canvas.addEventListener("mouseup", stopPainting);
    canvas.addEventListener("mouseleave", stopPainting);
}

 

 

 

onMouseMove๋ฅผ ์‹ ๊ฒฝ์จ์„œ ์ž˜ ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค.

์™œ๋ƒํ•˜๋ฉด ์—ฌ๊ธฐ์—์„œ ๋ชจ๋“  ์›€์ง์ž„์„ ๊ฐ์ง€ํ•˜๊ณ  ๋ผ์ธ์„ ๋งŒ๋“ค์–ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

context๋Š” ๋งŽ์€ ๊ฒƒ์„ ๊ฐ–๊ณ  ์žˆ๋Š”๋ฐ path๋„ ๊ฐ–๊ณ  ์žˆ๋‹ค.

path๋Š” ๊ธฐ๋ณธ์ ์ธ ์„ (line)์ด๋‹ค.

path๋ฅผ ์›€์ง์ผ ์ˆ˜๋„ ์žˆ๊ณ  path๋ฅผ ์ƒ‰์œผ๋กœ ์ฑ„์šธ ์ˆ˜๋„ ์žˆ๊ณ  path๋ฅผ ๋‹ซ์„ ์ˆ˜๋„ ์žˆ๋‹ค.

 

์ผ๋‹จ ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ (line)์„ ์‹œ์ž‘ํ•  ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ painting์„ ํ•  ๋• path๋Š” ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค. painting์„ ํ•˜์ง€ ์•Š์„ ๋•Œ๋งŒ ํ•„์š”ํ•จ!

path๋ฅผ ๋งŒ๋“œ๋Š” ๊ฑด ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ (line), ์„ ์˜ ์‹œ์ž‘์ ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

์‹œ์ž‘์ ์€ ๋งˆ์šฐ์Šค๊ฐ€ ์›€์ง์ด๋Š” ๊ณณ์ด๋ผ๋ฉด ์–ด๋””๋“ ์ง€ ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ํด๋ฆญํ•˜๊ณ ๋‚˜๋ฉด ์‹œ์ž‘์ ๋ถ€ํ„ฐ ํด๋ฆญํ•œ ๊ณณ๊นŒ์ง€ ์„ ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

(์„ค๋ช…์ด ์–ด๋ ค์šฐ๋‹ˆ ๊ฐ•์˜๋ฅผ ๋ณด๊ณ  ๋จธ๋ฆฌ์†์œผ๋กœ ์ดํ•ดํ•ด๋ณผ๊ฒƒ..-๋‹ˆ๊ผฌ์Œค-)

 

function onMouseMove(event) {
    const x = event.offsetX;
    const y = event.offsetY;
    if(!painting) {
        ctx.beginPath();
        ctx.moveTo(x, y);
    }
}

 

 

๊ทธ๋Ÿฌ๋‚˜ ์œ„์˜ ์ฝ”๋“œ๋Š” canvas ์œ„์—์„œ ํด๋ฆญํ•˜๊ณ  ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์ด๋ฉด ๋”์ด์ƒ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์šฐ๋ฆฌ๋Š” lineTo()๋ผ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค.

lineTo()๋Š” ํ˜„์žฌ sub-path์˜ ๋งˆ์ง€๋ง‰ ์ ์„ ํŠน์ • ์ขŒํ‘œ์™€ ์ง์„ ์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

path๋ฅผ ๋งŒ๋“ค๊ณ  lineTo()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ ๊ณผ ์ ์ด ์—ฐ๊ฒฐ์ด ๋œ๋‹ค.

function onMouseMove(event) {
    const x = event.offsetX;
    const y = event.offsetY;
    if(!painting) {
        ctx.beginPath();
        ctx.moveTo(x, y);
    } else {
        ctx.lineTo(x, y);
    }
}

์•„์ง path๊ฐ€ ์—†์–ด์„œ ์•ˆ๊ทธ๋ ค์ง...

 

 

 

 

stroke()๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

stroke()๋Š” ํ˜„์žฌ์˜ stroke style๋กœ ํ˜„์žฌ์˜ sub-path์— ํš์„ ๊ธ‹๋Š” ๊ฒƒ์ด๋‹ค.

function onMouseMove(event) {
    const x = event.offsetX;
    const y = event.offsetY;
    if(!painting){
        ctx.beginPath();
        ctx.moveTo(x, y);
    } else {
        ctx.lineTo(x, y);
        ctx.stroke();
    }
}

์•ˆ๊ทธ๋ ค์ง. ๋‹ˆ๊ผฌ์Œค๋„ ์•ˆ๊ทธ๋ ค์ ธ์„œ ๋‹ค์Œ ๊ฐ•์˜์—์„œ ๋ณด์žํ•˜๊ณ  ๋Ÿฐํ•˜์‹ฌ. ์˜์ฟจ

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€