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 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.
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 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 .
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.
let immagine = new Image();
immagine.src = 'https://source.unsplash.com/U5rMrSI7Pn4/1920x1280';
immagine.addEventListener('load', () => {
ctx.drawImage(immagine, 0, 0, 320, 240)
}, false);
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.
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.
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.
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.
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);
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 on Unsplash
Photo by Matthew Henry on Unsplash
Top comments (2)
nice work!, to bad that this is not in English
Thanks! I am planning for the translation, but time is short