Desenarea formelor
Pe lângă dreptunghiuri, canvas permite desenarea și formelor mai complexe. Pentru configurarea formelor complexe se utilizează conceptul de căi geometrice, care reprezintă un set de linii, cercuri, dreptunghiuri și alte detalii mai mici necesare pentru construirea unei forme complexe.
Pentru a crea o nouă cale, trebuie apelată metoda beginPath():
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath(); // începem desenarea formei
După metoda beginPath(), sunt apelate metodele care creează efectiv diferite segmente ale căii.
Metodele moveTo() și lineTo()
Pentru a începe desenarea unei căi, trebuie să stabilim punctul de început al acestei căi. Acest lucru se poate face cu ajutorul metodei moveTo(), care are următoarea definiție:
moveTo(x, y)
Metoda ne mută la punctul cu coordonatele x și y.
Metoda lineTo() desenează o linie. Are o definiție similară:
lineTo(x, y)
Metoda desenează o linie de la poziția curentă la punctul cu coordonatele x și y.
Acum să desenăm câteva linii:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
Aici stabilim începutul căii la punctul (20, 100), apoi desenăm o linie până la punctul (140, 10) (linie în sus) și continuăm cu încă o linie până la punctul (260, 100).
Afișarea căii
Deși am desenat câteva linii, încă nu le vom vedea pe ecran, deoarece trebuie să le afișăm. Pentru afișarea căii trebuie utilizată metoda stroke():
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>FDC.COM</title>
</head>
<body>
<canvas id="canvas" width="500" height="250"></canvas>
<script>
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
context.stroke(); // afișăm calea
</script>
</body>
</html>

Implicit, pentru desenare se utilizează culoarea neagră, dar cu proprietatea strokeStyle se poate schimba culoarea:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
context.strokeStyle = "red"; // culoare roșie
context.stroke(); // afișăm calea
Închiderea căii
Am desenat două linii și, presupunând că dorim să le conectăm pentru a închide forma - în acest caz, un triunghi. Deși am putea desena o altă linie pentru a forma un triunghi, pentru simplificare, API-ul Canvas oferă o metodă specială - context.closePath(), care permite închiderea automată a căii, conectând primul și ultimul punct al căii, formând astfel figura:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
context.closePath(); // închidem calea
context.stroke();

Obiecte Path2D
Lucrând cu multe căi poate deveni confuz. În acest caz, pentru a diferenția căile separate se pot folosi obiecte Path2D. Acest obiect oferă metode similare cu metodele obiectului context în ceea ce privește crearea unei căi. De exemplu:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
const path1 = new
Path2D(); // prima cale
path1.moveTo(20, 100);
path1.lineTo(140, 10);
path1.lineTo(260, 100);
path1.closePath(); // închidem calea
context.strokeStyle = "blue";
context.stroke(path1);
const path2 = new Path2D(); // a doua cale
path2.moveTo(20, 110);
path2.lineTo(140, 200);
path2.lineTo(260, 110);
path2.closePath(); // închidem calea
context.strokeStyle = "red";
context.stroke(path2);
Aici se creează două căi, fiecare reprezentând un triunghi. Pentru desenarea fiecărei căi se apelează metoda context.stroke(), în care se transmite calea respectivă.

Metoda rect
Metoda rect() creează un dreptunghi. Are următoarea definiție:
rect(x, y, width, height)
Unde x și y sunt coordonatele colțului superior stâng al dreptunghiului relativ la canvas, iar width și height sunt, respectiv, lățimea și înălțimea dreptunghiului. Să desenăm, de exemplu, următorul dreptunghi:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.rect(30, 20, 100, 90);
context.closePath();
context.stroke();

Este bine de menționat că un dreptunghi similar am fi putut crea folosind linii:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(30, 20);
context.lineTo(130, 20);
context.lineTo(130, 110);
context.lineTo(30, 110);
context.closePath();
context.stroke();
Metoda fill()
Metoda fill() umple cu culoare tot spațiul interior al căii desenate:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
context.closePath();
context.strokeStyle = "#2e86de";
context.fillStyle = "#4bcffa";
context.fill();
context.stroke();
Cu ajutorul proprietății fillStyle se poate seta culoarea de umplere a formei. În acest caz, culoarea este "#4bcffa".

Metoda clip()
Metoda clip() permite decuparea unei anumite zone din canvas, iar tot ceea ce se află în afara acestei zone va fi ignorat la desenarea ulterioară.
Pentru a înțelege această metodă, să desenăm mai întâi două dreptunghiuri:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
// desenăm primul dreptunghi roșu
context.beginPath();
context.moveTo(10, 20);
context.lineTo(130, 20);
context.lineTo(130, 110);
context.lineTo(10, 110);
context.closePath();
context.strokeStyle = "red";
context.stroke();
// desenăm al doilea dreptunghi verde
context.beginPath();
context.rect(30, 50, 180, 70);
context.closePath();
context.strokeStyle = "green";
context.stroke();

Acum să aplicăm metoda clip() pentru a limita zona de desenare doar la primul dreptunghi:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
// desenăm primul dreptunghi roșu
context.beginPath();
context.moveTo(10, 20);
context.lineTo(130, 20);
context.lineTo(130, 110);
context.lineTo(10, 110);
context.closePath();
context.strokeStyle = "red";
context.stroke();
context.clip(); // tăiem zona de desenare după primul traseu
// desenăm al doilea dreptunghi verde
context.beginPath();
context.rect(30, 50, 180, 70);
context.closePath();
context.strokeStyle = "green";
context.stroke();

După apelul metodei clip() după primul dreptunghi, doar partea a doua a dreptunghiului verde care se suprapune peste primul dreptunghi va fi desenată.
Metoda arc()
Metoda arc() adaugă la traseu un segment de cerc sau arc. Are următoarea definiție:
arc(x, y, radius, startAngle, endAngle, anticlockwise)
Parametrii utilizați sunt:
- x și y: coordonatele x și y unde începe arcul
- radius: raza cercului de-a lungul căruia se creează arcul
- startAngle și endAngle: unghiul de început și unghiul de sfârșit care taie cercul într-un arc. Unghiurile sunt măsurate în radiani. De exemplu, un cerc complet este 2π radiani. Dacă trebuie să desenăm un cerc complet, atunci pentru parametrul endAngle se poate specifica valoarea 2π. În JavaScript, această valoare se poate obține prin expresia Math.PI * 2
- anticlockwise: direcția de mișcare pe cerc atunci când se taie o porțiune a acestuia, delimitată de unghiurile de început și de sfârșit. Când valoarea este true, direcția este în sens invers acelor de ceasornic, iar când este false, direcția este în sensul acelor de ceasornic

Exemple de desenare a arcurilor și cercilor pe canvas în JavaScript sunt prezentate mai jos.
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(20, 90);
context.arc(20, 90, 50, 0, Math.PI/2, false);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(130, 90);
context.arc(130, 90, 50, 0, Math.PI, false);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(240, 90);
context.arc(240, 90, 50, 0, Math.PI * 3 / 2, false);
context.closePath();
context.stroke();
context.beginPath();
context.arc(350, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.stroke();

Ultimul parametru, anticlockwise, joacă un rol important, deoarece determină mișcarea pe cerc, iar în cazul schimbării din true în false și invers, putem obține figuri complet diferite:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(80, 90);
context.arc(80, 90, 50, 0, Math.PI/2, false);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(240, 90);
context.arc(240, 90, 50, 0, Math.PI/2, true);
context.closePath();
context.stroke();

Metoda arcTo()
Metoda arcTo() desenează, de asemenea, un arc. Are următoarea definiție:
arcTo(x1, y1, x2, y2, radius)
Unde x1 și y1 sunt coordonatele primului punct de control, x2 și y2 sunt coordonatele celui de-al doilea punct de control, iar radius este raza arcului.

Exemplu de desenare a arcurilor cu ajutorul arcTo():
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(0, 150);
context.arcTo(0, 0, 150, 0, 140)
context.closePath();
context.stroke();

Aici ne mutăm mai întâi la punctul (0, 150), și de la acest punct la primul punct de control (0, 0) va trece prima tangentă. Apoi, de la primul punct de control (0, 0) la al doilea (150, 0) va trece a doua tangentă. Aceste două tangente formează un arc, iar 140 servește drept raza cercului pe care este secționat arcul.
Metoda quadraticCurveTo()
Metoda quadraticCurveTo() creează o curbă pătratică. Are următoarea definiție:
quadraticCurveTo(x1, y1, x2, y2)
Unde x1 și y1 sunt coordonatele primului punct de sprijin, iar x2 și y2 sunt coordonatele celui de-al doilea punct de sprijin.

Exemplu de curbă pătratică Bézier:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(20, 90);
context.quadraticCurveTo(130, 0, 280, 90)
context.closePath();
context.stroke();

Metoda bezierCurveTo(). Curba Bézier
Metoda bezierCurveTo() desenează o curbă Bézier. Are următoarea definiție:
bezierCurveTo(x1, y1, x2, y2, x3, y3)
Unde x1 și y1 sunt coordonatele primului punct de sprijin, x2 și y2 sunt coordonatele celui de-al doilea punct de sprijin, iar x3 și y3 sunt coordonatele celui de-al treilea punct de sprijin.

Exemplu de curbă Bézier:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(30, 100);
context.bezierCurveTo(110, 0, 190, 200, 270, 100);
context.closePath();
context.stroke();

Figuri complexe
Vom combina mai multe figuri împreună și vom desena o scenă bidimensională mai complexă:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>FDC.COM</title>
</head>
<body>
<canvas id="canvas" width="400" height="250"></canvas>
<script>
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.fill();
context.fillStyle = "yellow";
context.beginPath();
context.arc(160, 130, 100, 0, 2 * Math.PI);
context.fill();
// gura
context.beginPath();
context.moveTo(100, 160);
context.quadraticCurveTo(160, 250, 220, 160);
context.closePath();
context.fillStyle = "red";
context.fill();
context.lineWidth = 2;
context.strokeStyle = "black";
context.stroke();
// dinții
context.fillStyle = "#FFFFFF";
context.fillRect(140, 160, 15, 15);
context.fillRect(170, 160, 15, 15);
// ochii
context.beginPath();
context.arc(130, 90, 20, 0, 2 * Math.PI);
context.fillStyle = "#333333";
context.fill();
context.closePath();
context.beginPath();
context.arc(190, 90, 20, 0, 2 * Math.PI);
context.fillStyle = "#333333";
context.fill();
context.closePath();
</script>
</body>
</html>
