Canvas Javascript: Come disegnare immagini 
Tags: javascript, canvas, drawimage
Published: 2021-01-22 07:52:01

---
title: Canvas Javascript: Come disegnare immagini 
published: true
description: Come caricare e disegnare un immagine sul canvas con la funzione drawImage
tags: #js #javascript #canvas #drawImage
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/954ippyderpl01qela27.jpg
---
Ci sono molteplici situazioni per il quale potremmo volere un'immagine sul canvas ad esempio se stiamo creando un videogioco e dobbiamo caricare sia gli sfondi che gli sprite o se volessiomo manipolare delle foto o applicare degli effetti grafici animati.
Per questo e per molte altre ragioni in questo articolo tratteremo **come caricare un immagine** e **impareremo ad usare il metodo che ci da a disposizione il context del canvas**.

Come ogni progetto bisogna inizializzarlo e richiamare i vari tool che ci da il contesto 2d, per questo vi rimando a questo [articolo](https://dev.to/camizzilla/canvas-javascript-un-potente-strumento-per-la-grafica-sul-web-4334) che spiega come farlo.

**La funzione che abbiamo a disposizione per 'disegnare' un immagine sul canvas è **

* `ctx.drawImage(immagine, x, y)`

**Questa è la forma base**, composta con gli argomenti obbligatori, più avanti spiegheremo anche gli altri, ma andiamo per gradi e inziamo a vedere quelli base.

* immagine: è **la variabile nella quale abbiamo salvato l'immagine** che abbiamo precendentemente caricato. Ho dedicato il prossimo paragrafo al giusto caricamento della foto.
* x, y : sono le cordinate che **posizionano l'immagine sul canvas**, partendo dal vertice superiore sinistro dell'immagine.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gr35ynupqolht5uxloe9.jpg)

## CARICARE UN IMMAGINE

Come abbiamo visto, dobbiamo passare una variabile con l'immagine alla funzione _drawImage_. Ma **come si carica un immagine in javascript**.

Il sistema più conosciuto è quella di creare nel DOM html, un elemento <img> e mettere nell'attributo _src_ il percorso del immagine  e poi catturarlo con _getDocumentById_, ma per il canvas non è il più funzionale. 

Il **mio consiglio è quello di creare un oggetto _Image_** direttamente nel codice javscript, così da essere più gestibile e tenere il DOM pulito con il solo elemento <canvas>.

``` javascript
let immagine = new Image();
immagine.src = 'laMiaImmagine.jpg';
```

**Abbiamo creato un nuovo oggetto Image()** e lo abbiamo salvato nella variabile immagine. Avremmo avuto lo stesso risultato se avessimo usato il metodo `document.createElement("img")` al posto di `new Image()`.
Nella seconda riga **abbiamo attribuito alla proprietà _src_ il percorso** di dove si trova l'immagine che vogliamo caricare.

Ma sorge un problema, essendo javascript un linguaggio _asincrono_, **se l'immagine ci mette tanto a caricare**, magari perchè è troppo grande, **la funzione _drawImage_ riceverà come argomento una variabile non funzionante** perchè l'immagine non ha fatto in tempo a caricare e sul canvas non si vedrebbe nulla.

**Una soluzione** efficente **è usare il metodo _addEventListener_ che aggiunge**, nel nostro caso, **l'evento _load_**. Quest'ultimo, **manda in eseguzione** la funzione che gli passiamo **solo quando l'immagine ha finito di essere caricata**.

``` javascript
let immagine = new Image();
immagine.src = 'https://source.unsplash.com/U5rMrSI7Pn4/1920x1280';
immagine.addEventListener('load', () => {
  ctx.drawImage(immagine, 0, 0, 320, 240)
}, false);
```
{% codepen https://codepen.io/camizzilla/pen/xxEmVXJ %}

Creiamo l'oggetto _Image_ e gli carichiamo l'immagine. 
Il metodo _addEventListener_ applicato alla variabile _immagine_ farà partire la funzione contente _ctx.drawImage_ solo quando l'evento _'load'_, quindi solo quando l'immagine verrà caricata.
Così i problemi di asincronia saranno risolti.

# ALTEZZA e LUNGHEZZA
Sicurmante vi sarete accorti che nell'ultimo codice _drawImage_ aveva cinque argomenti e non tre.

* `ctx.drawImage(immagine, x, y, larghezza, altezza)`

**Abbiamo aggiunto l'altezza e la larghezza** perchè l'immagine che abbiamo caricato era un 2400x1600 e se non avessimo adattato l'immagine al canvas, avremmo visto solo una porzione della foto.

Se il nostro scopo è adattare la foto con il canvas possiamo passargli direttamente le proprietà del canvas: width e height, come larghezza e altezza e la x e la y con valore 0.

``` javascript
ctx.drawImage(immagine, 0, 0, canvas.width, canvas.height)
```

## RITAGLIARE (CROP)

Se volessimo **ritagliare una porzione rettangolare dell'immagine** caricata e disegnarla sul canvas, dovremmo usare anche gli ultimi argomenti che ci permettono di creare una maschera di ritaglio.

* `ctx.drawImage(immagine ,rX, rY, rLarghezza, rAltezza, x, y, larghezza, altezza)`

* _immagine_: l'oggetto Image()
* _rX, rY_: le coordinata dell'immagine da dove partirà il ritaglio
* _rLarghezza, rAltezza_: le dimensioni rettangolari del ritaglio
* _x, y_: le coordinata di dove verrà posizionati il ritaglio sul canvas
* _larghezza, altezza_: altezza e larghezza del ritaglio riferito al canvas

Facciamo un esempio pratico. 
Dal immagine sottostante, voglio disegnare a video solo il funghetto di Super Mario.

![Alt Photo by Geeky Shots on Unsplash](https://dev-to-uploads.s3.amazonaws.com/i/pm5ufn3wosafbgoyg8fa.jpg)

**Il punto di partenza del ritaglio sarà una coordinata relativa all'immagine** (non al canvas) con la _rX: 220px_ e la _rY: 140px_ e per comprendere il funghetto **dobbiamo creare un rettangolo lungo _140px_ e alto _110px_**.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zv3knnb0rkbphv7waq14.jpg)

Adesso che abbiamo la porzione ritagliata la **posizioniamo sul canvas alle coordinate** _x: 50_ e _y:20_.

**Gli ultimi due valori sono le dimensioni con il quale vuoi fare vedere il tuo ritaglio**. Se vuoi che le dimensioni rimangano invariate, _rLarghezza_ deve essere uguale a _larghezza_ e _rAltezza_ devono essere uguali a _altezza_. Mentre se vogliamo che il ritaglio si raddoppi sul canvas i valori _larghezza_ e _Altezza_ devono essere il doppio dei valori di _rLarghezza_ e _rAltezza_.
Nel nostro caso rimpiccioliamo il ritaglio dandogli una larghezza di 100 e un'altezza di 80 px.

``` javascript
let immagine = new Image();
immagine.src = 'https://source.unsplash.com/hQ4BQ3wdHsQ/600x400';
immagine.addEventListener('load', () => {
//ctx.drawImage(immagine ,rX, rY, rL, rA, x, y, l, a)
  ctx.drawImage(immagine, 220, 140, 140, 110, 50, 20, 100, 80 )
}, false);
```
{% codepen https://codepen.io/camizzilla/pen/qBawQqY %}
##CONCLUSIONE
In questo articolo abbiamo visto come caricare in maniera funzionale un immagine nel canvas e come possiamo creare una maschera di ritaglio con una sola funzione.
Quest'ultima è molto utile qualora volessimo fare degli slideshow o se volessimo dividere vari elementi caricando una solo immagine o (la mia preferita) creare degli sprites per i videogiochi.

Spero che l'articolo ti sia piaciuto Se hai dei consigli, suggerimenti o critiche costruttive lasciami un commento qui sotto oppure contattami trammite i miei social. 

Photo by [Geeky Shots](https://unsplash.com/@geekyshots?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/animal-fun?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText)
Photo by [Matthew Henry](https://unsplash.com/@matthewhenry?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/animal-fun?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText)