Canvas

Canvas

Canvas API๋Š” JavaScript ์™€ HTML <canvas> ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํ†ตํ•ด ๊ทธ๋ž˜ํ”ฝ์„ ๊ทธ๋ฆฌ๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์„ ์ œ๊ณตํ•œ๋‹ค.

์• ๋‹ˆ๋ฉ”์ด์…˜, ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”, ๊ทธ๋ž˜ํ”ฝ, ๊ฒŒ์ž„ ๋“ฑ ๋‹ค์–‘ํ•œ ์‹œ๊ฐ์  ์ธํ„ฐ๋ ‰์…˜์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ

Canvas Size

canvas์˜ size(width, height)๋Š” ์ธ๋ผ์ธ ์†์„ฑ์œผ๋กœ ์ง€์ •ํ•œ ๊ฐ’๊ณผ css ์Šคํƒ€์ผ๋กœ ์ง€์ •ํ•œ ๊ฐ’์€ ์„œ๋กœ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

์ธ๋ผ์ธ ์†์„ฑ

  • ์ธ๋ผ์ธ ์†์„ฑ์€ ์ปจ๋ฒ„์Šค์˜ ํ•ด์ƒ๋„(ํฌํ•จ๋œ ํ”ฝ์…€ ์ˆ˜)๋ฅผ ์ •์˜ํ•œ๋‹ค.

  • ์บ”๋ฒ„์Šค ๊ณ ์œ ์˜ ๋ฌผ๋ฆฌ์ ์ธ ํฌ๊ธฐ

  • ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์€ 300 x 150

css ์Šคํƒ€์ผ๋กœ ์‚ฌ์ด์ฆˆ๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚ด๋Š” ์‚ฌ์ด์ฆˆ ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค

์ฆ‰, ์บ”๋ฒ„์Šค ๊ณ ์œ ์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ•์ œ๋กœ ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๋Š” ์‚ฌ์ด์ฆˆ๋กœ ์กฐ์ ˆ(์••์ถ•)์‹œํ‚จ๋‹ค.

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d'); // canvas 2D ๋ Œ๋”๋ง ์ปจํ…์ŠคํŠธ

const canvasWidth = 300;
const canvasHeight = 300;

canvas.style.width = canvasWidth + 'px';
canvas.style.height = canvasHeight + 'px';

canvas.width = canvasWidth * 2;
canvas.height = canvasHeight * 2;

DPR (Device Pixel Ratio)

ํ•˜๋‚˜์˜ css ํ”ฝ์…€์„ ๊ทธ๋ฆด ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์žฅ์น˜์— ํ”ฝ์…€ ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. DPR์ด ๋†’์„์ˆ˜๋ก ์„ ๋ช…ํ•œ ํ™”๋ฉด์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

const DPR = window.devicePixelRatio; 
// ๊ณ ํ•ด์ƒ๋„ ๋””์Šคํ”Œ๋ ˆ์ด ํ™˜๊ฒฝ์—์„œ๋Š” ํ”ฝ์…€ ๋ฐ€๋„๊ฐ€ ๋†’๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์ •ํ•œ ์บ”๋ฒ„์Šค ํฌ๊ธฐ๋งŒ์œผ๋กœ๋Š” ํ๋ฆฟํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค.
// ์ง‘์ ๋„๋ฅผ ๋†’ํžˆ๊ธฐ ์œ„ํ•ด ์บ”๋ฒ„์Šค ์ž์ฒด์˜ ํฌ๊ธฐ๋ฅผ DPR๊ฐ’ ๋งŒํผ ๊ณฑํ•œ๋‹ค.
canvas.width = canvasWidth * DPR;
canvas.height = canvasHeight * DPR;

ctx.scale(DPR, DPR);// ์บ”๋ฒ„์Šค ์š”์†Œ ๋‚ด๋ถ€์˜ ๊ทธ๋ž˜ํ”ฝ๋“ค ์—ญ์‹œ ๋™์ผํ•˜๊ฒŒ ๋ณด์—ฌ์ง€๊ธฐ ์œ„ํ•ด DPR๊ฐ’ ๋งŒํผ ๊ณฑํ•œ๋‹ค.

dpr๊ฐ’์ด 3 ์ด์ƒ์ด๋ผ๋ฉด ์บ”๋ฒ„์Šค ํฌ๊ธฐ๋ฅผ ๊ทธ๋งŒํผ ๋Š˜๋ฆฌ๋ฉด์„œ ์„ฑ๋Šฅ ์ด์Šˆ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๊ณ , dpr์ด 2์ธ ๊ธฐ๊ธฐ์˜ ์„ ๋ช…ํ•จ ์ •๋„๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ๋Œ€ dpr ๊ฐ’์„ 2๋กœ ์„ ์–ธํ•œ๋‹ค.

์› ๊ทธ๋ฆฌ๊ธฐ

ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI / 180 * 360);
ctx.fill(); // ctx.stroke();
ctx.closePath();

beginPath()

path๋ฅผ ๊ทธ๋ฆฌ๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค๊ณ  ์•Œ๋ฆฌ๋Š” ๋ฉ”์„œ๋“œ, ์ƒˆ๋กœ์šด path๋ฅผ ๊ทธ๋ฆฌ๊ธฐ ์‹œ์ž‘ํ•˜๋ฉฐ, ์ด์ „ path๋Š” ์ดˆ๊ธฐํ™”์‹œํ‚จ๋‹ค.

closePath()

path์˜ ์‹œ์ž‘ ์ง€์ ๊ณผ ํ˜„์žฌ ์œ„์น˜๋ฅผ ์ง์„ ์œผ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ path๋ฅผ ๋‹ซ๋Š”๋‹ค.

fill()

ํ˜„์žฌ ์„ค์ •๋œ path์— ์ƒ‰์„ ์ฑ„์šด๋‹ค.

  • fillStyle โ†’ ์ฑ„์šธ ์ƒ‰์ƒ์„ ์„ค์ • ctx.fillStyle = 'red'

stroke()

ํ˜„์žฌ ์„ค์ •๋œ path์— ์œค๊ณฝ์„ ์„ ๊ทธ๋ฆฐ๋‹ค.

arc()

์›์„ ๊ทธ๋ฆฌ๋Š” ๋ฉ”์†Œ๋“œ, ์ธ์ž์˜ ์ •๋ณด๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • x: numberโ†’ ์‹œ์ž‘ํ•˜๋Š” x ์œ„์น˜

  • y: numberโ†’ ์‹œ์ž‘ํ•˜๋Š” y ์œ„์น˜

  • radius: numberโ†’ ๋ฐ˜์ง€๋ฆ„์˜ ๊ธธ์ด

  • startAngle: number โ†’ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ๋„

  • endAngle: number โ†’ ๋๋‚˜๋Š” ๊ฐ๋„

  • counterclockwise: boolean | undefinedโ†’ ์‹œ๊ณ„๋ฐฉํ–ฅ(false, default) or ๋ฐ˜์‹œ๊ณ„๋ฐฉํ–ฅ(true)

๊ฐ๋„๋Š” degree ๊ฐ’์ด ์•„๋‹Œ radian ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Math.PI / 180 * [degree]๋กœ ๊ธฐ์ž…ํ•ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ๊ฐ๋„ 1๋„์˜ ๊ฐ’์€. PI(3.14)๋ฅผ 180์œผ๋กœ ๋‚˜๋ˆˆ๊ฐ’๊ณผ ๊ฐ™๋‹ค.

  • 180 degree = ฯ€ radian

  • 1 degree = ฯ€ / 180 radian

  • x degree = x * ฯ€ / 180 radian

clearRect(x, y, width, height)

์ง€์ •ํ•œ ์˜์—ญ์„ ์ง€์šฐ๋Š” ๋ฉ”์„œ๋“œ

ctx.clearRect(0, 0, canvasWidth, canvasHeight); // ์บ”๋ฒ„์Šค ์ „์ฒด ์˜์—ญ ์ง€์šฐ๊ธฐ

Last updated