{"id":164047,"date":"2025-03-30T09:00:00","date_gmt":"2025-03-30T07:00:00","guid":{"rendered":"https:\/\/gtechgroup.it\/blog\/html-canvas-grafica-animazioni-browser\/"},"modified":"2025-03-30T09:00:00","modified_gmt":"2025-03-30T07:00:00","slug":"html-canvas-grafica-animazioni-browser","status":"publish","type":"post","link":"https:\/\/gtechgroup.it\/blog\/html-canvas-grafica-animazioni-browser\/","title":{"rendered":"HTML Canvas: Creare Grafica e Animazioni nel Browser"},"content":{"rendered":"<p style=\"text-align: justify;\">L&#8217;elemento <code>&lt;canvas&gt;<\/code> di HTML5 ha aperto possibilit\u00e0 straordinarie per la creazione di grafica, animazioni e visualizzazioni interattive direttamente nel browser, senza la necessit\u00e0 di plugin esterni. Utilizzato in combinazione con JavaScript, Canvas permette di disegnare forme, renderizzare testo, manipolare immagini e creare animazioni fluide. In questa guida esploreremo le fondamenta del disegno su Canvas e le tecniche per creare contenuti grafici coinvolgenti.<\/p>\n<h2>L&#8217;Elemento Canvas e il Contesto di Rendering<\/h2>\n<p style=\"text-align: justify;\">L&#8217;elemento <code>&lt;canvas&gt;<\/code> \u00e8 essenzialmente un&#8217;area rettangolare nel documento HTML che funge da superficie di disegno. Di per s\u00e9, il tag canvas non mostra nulla: tutto il disegno avviene tramite <strong>JavaScript<\/strong>, utilizzando un oggetto chiamato &#8220;contesto di rendering&#8221; che fornisce i metodi e le propriet\u00e0 necessarie per disegnare.<\/p>\n<p style=\"text-align: justify;\">Le dimensioni del canvas si definiscono tramite gli attributi <strong>width<\/strong> e <strong>height<\/strong> direttamente sull&#8217;elemento HTML, non tramite CSS. Questa distinzione \u00e8 importante: gli attributi HTML definiscono la risoluzione reale della superficie di disegno, mentre il CSS controlla solo le dimensioni di visualizzazione. Se le due non corrispondono, il contenuto apparir\u00e0 sfocato o distorto. La dimensione predefinita \u00e8 300&#215;150 pixel.<\/p>\n<p style=\"text-align: justify;\">Per ottenere il contesto di rendering 2D, si utilizza il metodo <strong>getContext(&#8216;2d&#8217;)<\/strong> sull&#8217;elemento canvas. Questo oggetto contesto \u00e8 il punto di accesso a tutte le operazioni di disegno. Esiste anche un contesto WebGL per la grafica 3D, ma per la maggior parte delle applicazioni il contesto 2D \u00e8 pi\u00f9 che sufficiente.<\/p>\n<p style=\"text-align: justify;\">\u00c8 buona pratica includere un contenuto testuale di fallback tra i tag di apertura e chiusura di <code>&lt;canvas&gt;<\/code>, che verr\u00e0 visualizzato dai browser che non supportano l&#8217;elemento. Sebbene oggi il supporto sia universale, il fallback migliora l&#8217;accessibilit\u00e0 per le tecnologie assistive che non possono interpretare il contenuto grafico.<\/p>\n<h2>Disegnare Forme: Rettangoli, Cerchi e Linee<\/h2>\n<p style=\"text-align: justify;\">Il contesto 2D di Canvas offre metodi diretti per disegnare <strong>rettangoli<\/strong> e un sistema basato su percorsi (paths) per tutte le altre forme. Per i rettangoli, i metodi principali sono: fillRect(x, y, width, height) per un rettangolo pieno, strokeRect(x, y, width, height) per un rettangolo con solo bordo, e clearRect(x, y, width, height) per cancellare un&#8217;area rettangolare.<\/p>\n<p style=\"text-align: justify;\">Per disegnare <strong>cerchi, archi e forme complesse<\/strong>, si utilizza il sistema dei percorsi. Un percorso si inizia con beginPath(), si definisce con una serie di comandi di disegno, e si finalizza con fill() per riempirlo o stroke() per tracciarne il contorno. Il metodo arc(x, y, raggio, angoloInizio, angoloFine) disegna un arco di cerchio, dove gli angoli sono espressi in radianti. Un cerchio completo va da 0 a 2*Math.PI.<\/p>\n<p style=\"text-align: justify;\">Per le <strong>linee<\/strong>, si usa moveTo(x, y) per posizionare il cursore e lineTo(x, y) per tracciare una linea dal punto corrente al nuovo punto. La propriet\u00e0 lineWidth controlla lo spessore della linea, lineCap definisce la forma delle estremit\u00e0 (&#8220;butt&#8221;, &#8220;round&#8221;, &#8220;square&#8221;) e lineJoin controlla la giunzione tra segmenti (&#8220;round&#8221;, &#8220;bevel&#8221;, &#8220;miter&#8221;). Queste propriet\u00e0 permettono un controllo fine sull&#8217;aspetto delle linee.<\/p>\n<p style=\"text-align: justify;\">Le <strong>curve di B\u00e9zier<\/strong> permettono di creare forme organiche e fluide. Il metodo quadraticCurveTo(cpx, cpy, x, y) disegna una curva con un punto di controllo, mentre bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) utilizza due punti di controllo per curve pi\u00f9 complesse. Con queste primitive \u00e8 possibile creare qualsiasi forma geometrica.<\/p>\n<h2>Colori, Gradienti e Pattern<\/h2>\n<p style=\"text-align: justify;\">Il canvas supporta una vasta gamma di opzioni per colorare le forme. Le propriet\u00e0 <strong>fillStyle<\/strong> e <strong>strokeStyle<\/strong> accettano stringhe di colore CSS (nomi, hex, rgb, rgba, hsl, hsla), permettendo anche la trasparenza tramite il canale alfa. La propriet\u00e0 <strong>globalAlpha<\/strong> imposta la trasparenza globale per tutte le operazioni di disegno successive.<\/p>\n<p style=\"text-align: justify;\">I <strong>gradienti lineari<\/strong> si creano con createLinearGradient(x0, y0, x1, y1), che definisce la direzione del gradiente attraverso due punti. Si aggiungono poi i colori con addColorStop(posizione, colore), dove la posizione \u00e8 un valore tra 0 e 1. I <strong>gradienti radiali<\/strong> si creano con createRadialGradient(x0, y0, r0, x1, y1, r1), che definisce due cerchi tra cui si sviluppa il gradiente.<\/p>\n<p style=\"text-align: justify;\">I <strong>pattern<\/strong> permettono di riempire aree con immagini ripetute. Si creano con createPattern(immagine, ripetizione), dove la ripetizione pu\u00f2 essere &#8220;repeat&#8221;, &#8220;repeat-x&#8221;, &#8220;repeat-y&#8221; o &#8220;no-repeat&#8221;. L&#8217;immagine sorgente pu\u00f2 essere un elemento Image, un altro canvas o un elemento video, offrendo grande flessibilit\u00e0 creativa.<\/p>\n<p style=\"text-align: justify;\">Le <strong>ombre<\/strong> si controllano tramite quattro propriet\u00e0: shadowColor per il colore, shadowBlur per la sfocatura, shadowOffsetX e shadowOffsetY per lo spostamento. Le ombre vengono applicate a tutte le operazioni di disegno successive, inclusi rettangoli, percorsi e testo, aggiungendo profondit\u00e0 alle composizioni grafiche.<\/p>\n<h2>Testo e Immagini su Canvas<\/h2>\n<p style=\"text-align: justify;\">Il canvas permette di renderizzare <strong>testo<\/strong> utilizzando i metodi fillText(testo, x, y) e strokeText(testo, x, y). La propriet\u00e0 font accetta la stessa sintassi della propriet\u00e0 CSS font (ad esempio &#8220;bold 24px Arial&#8221;). Le propriet\u00e0 textAlign (&#8220;left&#8221;, &#8220;center&#8221;, &#8220;right&#8221;, &#8220;start&#8221;, &#8220;end&#8221;) e textBaseline (&#8220;top&#8221;, &#8220;middle&#8221;, &#8220;bottom&#8221;, &#8220;alphabetic&#8221;) controllano l&#8217;allineamento del testo rispetto alle coordinate specificate.<\/p>\n<p style=\"text-align: justify;\">Per misurare le dimensioni del testo prima di disegnarlo, il metodo measureText(testo) restituisce un oggetto TextMetrics con la larghezza del testo, utile per centrare il testo o creare layout testuali complessi.<\/p>\n<p style=\"text-align: justify;\">Il disegno di <strong>immagini<\/strong> su canvas avviene tramite il metodo drawImage(), che accetta tre varianti: la versione base drawImage(img, x, y) disegna l&#8217;immagine alle coordinate specificate; drawImage(img, x, y, width, height) la ridimensiona; e drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh) permette di ritagliare una porzione dell&#8217;immagine sorgente e disegnarla ridimensionata. Quest&#8217;ultima versione \u00e8 particolarmente utile per gli sprite sheet nelle animazioni e nei giochi.<\/p>\n<h2>Animazioni con requestAnimationFrame<\/h2>\n<p style=\"text-align: justify;\">Le animazioni su canvas seguono un pattern fondamentale: cancellare il canvas, aggiornare lo stato degli oggetti e ridisegnare tutto in un ciclo continuo. La funzione <strong>requestAnimationFrame(callback)<\/strong> \u00e8 il metodo standard per creare questo ciclo di animazione, sincronizzato con il refresh rate del monitor (tipicamente 60fps).<\/p>\n<p style=\"text-align: justify;\">A differenza di setInterval o setTimeout, requestAnimationFrame viene automaticamente sospeso quando la scheda del browser non \u00e8 visibile, risparmiando risorse di CPU e batteria. Inoltre, il browser ottimizza internamente il timing per garantire animazioni fluide senza tearing o stuttering.<\/p>\n<p style=\"text-align: justify;\">Il pattern tipico di un&#8217;animazione prevede una funzione che viene chiamata ricorsivamente: all&#8217;interno della funzione si cancella il canvas con clearRect(), si aggiornano le posizioni e gli stati degli oggetti animati, si ridisegnano tutti gli elementi e infine si richiama requestAnimationFrame con la stessa funzione come callback. Per animazioni time-based (indipendenti dal frame rate), si utilizza il parametro timestamp fornito automaticamente dalla callback.<\/p>\n<p style=\"text-align: justify;\">Le ottimizzazioni comuni per le animazioni includono: ridisegnare solo le aree modificate anzich\u00e9 l&#8217;intero canvas, utilizzare un canvas fuori schermo (offscreen canvas) per operazioni di pre-rendering, e sfruttare le trasformazioni del canvas (translate, rotate, scale) per evitare calcoli matematici complessi nelle coordinate.<\/p>\n<h2>Canvas vs SVG: Quando Usare Cosa<\/h2>\n<p style=\"text-align: justify;\">La scelta tra Canvas e SVG dipende dal tipo di applicazione. Il <strong>Canvas<\/strong> \u00e8 basato su pixel (raster) ed \u00e8 pi\u00f9 adatto per: animazioni complesse con molti elementi in movimento, giochi, elaborazione di immagini in tempo reale, visualizzazioni di dati con migliaia di punti, e qualsiasi scenario in cui le performance sono critiche.<\/p>\n<p style=\"text-align: justify;\"><strong>SVG<\/strong> \u00e8 basato su vettori ed \u00e8 preferibile per: grafici e diagrammi interattivi, icone e illustrazioni scalabili, interfacce utente con elementi cliccabili, animazioni semplici con pochi elementi, e contenuti che devono mantenere la qualit\u00e0 a qualsiasi dimensione. Per una guida dettagliata sulla grafica SVG, consulta il nostro articolo su <a href=\"https:\/\/gtechgroup.it\/blog\/svg-html-grafica-vettoriale-scalabile\/\">SVG in HTML<\/a>.<\/p>\n<p style=\"text-align: justify;\">In pratica, Canvas eccelle quando il numero di elementi \u00e8 elevato e le interazioni dirette con singoli elementi non sono necessarie, mentre SVG \u00e8 superiore quando ogni elemento grafico deve essere indipendentemente manipolabile e accessibile. In alcuni casi, combinare entrambe le tecnologie nella stessa pagina \u00e8 la soluzione ottimale.<\/p>\n<p style=\"text-align: justify;\">Hai bisogno di aiuto con la creazione di grafica e animazioni per il tuo sito web? <strong>G Tech Group<\/strong> offre servizi di sviluppo web professionale e consulenza tecnica. Contattaci a <strong>support@gtechgroup.it<\/strong> o via WhatsApp al <strong>0465 84 62 45<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&#8217;elemento &lt;canvas&gt; di HTML5 ha aperto possibilit\u00e0 straordinarie per la creazione di grafica, animazioni e visualizzazioni interattive direttamente nel browser, senza la necessit\u00e0 di plugin&hellip;<\/p>\n","protected":false},"author":2,"featured_media":164227,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"1246","_seopress_titles_title":"HTML Canvas: Creare Grafica e Animazioni nel Browser %%sep%% %%sitename%%","_seopress_titles_desc":"Guida completa a HTML Canvas: disegno 2D, forme, colori, gradienti, testo, immagini, animazioni con requestAnimationFrame e confronto con SVG.","_seopress_robots_index":"","footnotes":""},"categories":[1246],"tags":[787,1108],"class_list":["post-164047","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-html","tag-sviluppo-web","tag-web-design"],"_links":{"self":[{"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts\/164047","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/comments?post=164047"}],"version-history":[{"count":0,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts\/164047\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/media\/164227"}],"wp:attachment":[{"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/media?parent=164047"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/categories?post=164047"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/tags?post=164047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}