Coordinate del Canvas
In questa pagina trovi informazioni utili sulle coordinate del canvas HTML, con esempi di codice per disegnare un cerchio e una linea.
Il canvas HTML è un elemento potente di HTML5 che consente di creare e manipolare grafica su una pagina web tramite JavaScript. L'elemento <canvas> fornisce una superficie di disegno bidimensionale che puoi immaginare come una griglia o un sistema di coordinate.
Questa pagina spiega come funziona il sistema di coordinate del canvas, come leggere e scrivere punti su di esso, e come spostare, scalare e ruotare quel sistema con le trasformazioni. Se sei nuovo all'elemento stesso, inizia prima con l'introduzione al Canvas.
Il sistema di coordinate
La griglia del canvas parte dall'angolo in alto a sinistra, che ha le coordinate (0, 0). Da lì:
- L'asse x aumenta verso destra.
- L'asse y aumenta verso il basso (questo è l'opposto di quanto si impara nelle lezioni di matematica, dove y aumenta verso l'alto).
Ogni punto sul canvas è una coppia (x, y) misurata in pixel a partire da quell'origine in alto a sinistra.
(0,0)──────── x increases → ────────►
│ ┌───────────────────────────────┐
│ │ (0,0) (300,0) │
y │ │
│ │ (150,75) │
▼ │ │
│ (0,150) (300,150)│
└───────────────────────────────┘Per un canvas 300 × 150, (0, 0) è l'angolo in alto a sinistra, (300, 0) è l'angolo in alto a destra, (0, 150) è l'angolo in basso a sinistra, e (150, 75) è il centro esatto.
Il contesto di rendering 2D
Non si disegna mai direttamente sull'elemento <canvas>. Si richiede invece un contesto di rendering — un oggetto che espone i metodi di disegno (moveTo, lineTo, arc, fillRect, e così via):
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");getContext("2d") restituisce il contesto 2D utilizzato in tutti gli esempi seguenti. (Esistono altri tipi di contesto, come "webgl" per il 3D, ma "2d" è quello usato per il disegno su canvas.) Ogni coordinata passata a un metodo del contesto viene interpretata nella griglia descritta sopra.
Disegnare una linea
I metodi seguenti vengono utilizzati per disegnare una linea retta su un canvas:
moveTo(x,y), che specifica il punto di partenza della linealineTo(x,y), che specifica il punto finale della linea
Usa uno dei metodi "inchiostro" per disegnare la linea, ad esempio stroke().
Esempio dell'elemento HTML <canvas> per disegnare una linea:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas width="300" height="150" style="border:1px solid #cccccc;" id="canvasExample">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
const c = document.getElementById("canvasExample");
const ctx = c.getContext("2d");
// Starting point (0,0) is the top-left corner
ctx.moveTo(0, 0);
// Ending point (300,150) matches the canvas width and height
ctx.lineTo(300, 150);
ctx.strokeStyle = '#359900';
ctx.stroke();
</script>
</body>
</html>Nell'esempio precedente, la linea viene tracciata in diagonale da (0, 0) (in alto a sinistra) a (300, 150) (in basso a destra). Nota che questa singola linea non ha avuto bisogno di beginPath(): quando non è stato ancora disegnato nulla, moveTo/lineTo avviano automaticamente un nuovo percorso. Il cerchio qui sotto usa beginPath() perché è una forma separata — vedi la spiegazione in quella sezione.
Per altre forme e riempimenti basati sullo stesso sistema di coordinate, consulta Canvas drawing.
Disegnare un cerchio
I metodi seguenti vengono utilizzati per disegnare un cerchio su un canvas:
beginPath(), che avvia un nuovo percorso in modo che il cerchio non sia connesso a nulla disegnato in precedenza.arc(x, y, r, startAngle, endAngle), che aggiunge un arco (una porzione di cerchio) al percorso corrente.
I parametri di arc()
| Parametro | Significato |
|---|---|
x, y | Le coordinate del centro del cerchio. |
r | Il raggio, in pixel. |
startAngle | Dove inizia l'arco, in radianti. |
endAngle | Dove termina l'arco, in radianti. |
Gli angoli si misurano in radianti, non in gradi, e 0 punta verso destra (l'asse x positivo), ruotando in senso orario. Un giro completo equivale a 2 * Math.PI radianti (360°), quindi un cerchio completo va da 0 a 2 * Math.PI.
Per convertire i gradi in radianti, moltiplica per Math.PI / 180:
const radians = degrees * (Math.PI / 180);Archi parziali
Non è necessario disegnare un cerchio completo. Usa un angolo finale più piccolo per disegnare solo una parte di esso. Ad esempio, un arco da 0 a Math.PI (mezzo giro completo) disegna la metà inferiore di un cerchio, poiché y aumenta verso il basso:
// A half-circle (bottom half) centered at (100, 75) with radius 50
ctx.beginPath();
ctx.arc(100, 75, 50, 0, Math.PI);
ctx.stroke();Esempio dell'elemento HTML <canvas> per disegnare un cerchio:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas id="exampleCanvas" width="250" height="200" style="border:1px solid #dddddd;">
The canvas tag is not supported by your browser.
</canvas>
<script>
const canvas = document.getElementById("exampleCanvas");
const ctx = canvas.getContext("2d");
ctx.beginPath();
// Center at (125, 95), radius 70. 125 is half of the 250 width.
ctx.arc(125, 95, 70, 0, 2 * Math.PI);
ctx.strokeStyle = '#1c87c9';
ctx.closePath();
ctx.stroke();
</script>
</body>
</html>Nell'esempio precedente, il cerchio è centrato in (125, 95) con un raggio di 70.
beginPath() e closePath()
Questi due metodi causano spesso confusione:
beginPath()scarta il percorso che stavi costruendo e ne avvia uno completamente nuovo. Chiamalo prima di ogni forma indipendente — altrimenti la nuova forma viene collegata alla precedente, e un singolostroke()/fill()le stilizza tutte insieme.closePath()traccia una linea retta dal punto corrente al punto in cui il percorso è iniziato, "chiudendo" il contorno. Per un cerchio completo il punto finale coincide già con quello iniziale, quindiclosePath()qui non ha effetti visibili — viene incluso per abitudine e fa la differenza quando si costruiscono forme aperte come un poligono.
L'esempio della linea precedente non aveva bisogno di nessuno dei due metodi perché era un percorso singolo e autonomo. Non appena si disegna una seconda forma, usa beginPath().
Trasformazioni delle coordinate
Invece di ricalcolare ogni coordinata manualmente, puoi spostare, ridimensionare o ruotare l'intero sistema di coordinate. Le trasformazioni hanno effetto su tutto ciò che disegni dopo averle applicate.
Un pattern comune è racchiudere il disegno trasformato in save() e restore() in modo che la griglia torni normale in seguito:
ctx.save(); // remember the current coordinate system
// ...transform and draw...
ctx.restore(); // put the coordinate system backtranslate(x, y)
Sposta l'origine (0, 0) in una nuova posizione. Dopo translate(50, 30), disegnare in (0, 0) apparirà effettivamente in (50, 30):
ctx.translate(50, 30);
ctx.fillRect(0, 0, 80, 40); // top-left corner now sits at (50, 30)scale(x, y)
Moltiplica la dimensione di ogni coordinata e dimensione. scale(2, 2) rende tutto il doppio più grande; scale(1, 0.5) mantiene la larghezza ma dimezza l'altezza:
ctx.scale(2, 2);
ctx.fillRect(10, 10, 30, 30); // drawn at (20, 20), 60×60 in real pixelsrotate(angle)
Ruota il sistema di coordinate in senso orario attorno all'origine corrente. L'angolo è in radianti, come per arc(). Poiché la rotazione avviene attorno a (0, 0), di solito si usa prima translate() per spostarsi al pivot desiderato:
ctx.translate(100, 75); // move origin to the pivot point
ctx.rotate(45 * Math.PI / 180); // rotate 45° clockwise
ctx.fillRect(-25, -25, 50, 50); // a square centered on the pivotLe trasformazioni mantengono le coordinate nella stessa griglia che hai utilizzato finora — si limitano a riposizionare o ridisegnare quella griglia. Per disegnare testo posizionato su questo sistema, consulta Canvas text.