Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Font su Canvas: allineamento e spaziatura caratteri (Kerning)

Sfruttare le API 2D del canvas per gestire la spaziatura dei caratteri, dimensioni e opzioni di allineamento
Sfruttare le API 2D del canvas per gestire la spaziatura dei caratteri, dimensioni e opzioni di allineamento
Link copiato negli appunti

Osservando la locandina del film, scelta nelle lezioni precedenti, notiamo come ci siano alcune peculiarità nella disposizione del testo, in particolare la spaziatura tra i caratteri (kerning) non è quella di default del font. Inoltre le due parole sono centrate rispetto al canvas e la dimensione dei caratteri varia non solo tra parola e parola ma anche all'interno della stessa.

Le API 2D del canvas mettono a disposizione una serie di metodi per la scrittura, per gestire le tematiche sollevate ci avvaliamo di due di queste funzioni:

Metodo Descrizione
measureText(testo) restituisce un oggetto contenente una singola proprietà 'width' valorizzata con la larghezza del testo passato come argomento tenendo conto di tutte le impostazioni di stato del canvas, come il tipo e la dimesione del font
fillText(testo, posizione_x, posizione_y) scrive il testo passato come argomento sul canvas allineando l'angolo in basso a sinistra con le coordinate ricevute. Anche in questo caso l'operazione è eseguita rispettando tutte le impostazioni di stato del canvas

Ora progettiamo un algoritmo che, facendo leva su queste due funzioni, sappia costruire il testo secondo i vincoli imposti: l'idea alla base è calcolare la dimensione del riquadro contenente il testo, tenendo conto anche della spaziatura e di eventuali caratteri dalle dimensioni diverse, dopodiché procedere alla stampa di ogni singola lettera aggiungendo di volta in volta il kerning necessario e utilizzando le dimensioni del riquadro calcolato per centrare il tutto.

Aggiungiamo in coda alla funzione effettoLaMummia:

function kerningAndSize(contesto, testo, pos_y, kerning, dimensione, eccezioni) {
  contesto.save();
  contesto.font = "" + dimensione + "px Esteban, Arial, serif";
  eccezioni = eccezioni || {};
  var dim_lettere = 0;
  // calcolo la dimensione del box contenente il testo, comprensivo di kerning e
  // di eventuali dimensioni difformi da quella standard
  var box = (contesto.measureText(testo).width + kerning * (testo.length - 1));
  // incremento o decremento la lunghezza del testo della differenza tra il font
  // standard ed ogni font specificato nelle eccezioni
  box = _.reduce(_.values(eccezioni), function(memo, num) {
                 return box + (num - dimensione); }, box);
  // stampo ogni lettera singolarmente tenendo conto del kerning impostato, ritorno
  // la posizione e la dimensione delle singole lettere
  var lettere = _.map(testo.split(""),function(lettera, indice) {
    contesto.font = "" + (eccezioni[indice] || dimensione) + "px Esteban, Arial, serif";
    var pos_x = (contesto.canvas.width - box) / 2 + dim_lettere + kerning * indice;
    contesto.fillText(lettera, pos_x , pos_y);
    dim_lettere = dim_lettere + contesto.measureText(lettera).width;
    return { x:pos_x, y:pos_y, w:contesto.measureText(lettera).width };
  });
  contesto.restore();
  return lettere;
}

la funzione accetta in ingresso il contesto del canvas, la parola da stampare, la distanza tra una lettera e la successiva, la dimensione del font da utilizzare ed un array associativo { posizione: dimensione_font } per gestire eventuali lettere di dimensioni diverse.

Con queste informazioni e utilizzando il metodo measureText viene elaborata la dimensione della scritta; tale valore viene poi impiegato nel ciclo di stampa.

Le istruzioni contesto.save() e contesto.restore() garantiscono che all'uscita della funzione lo stato interno del canvas sia lo stesso di quello all'ingresso. Validiamo subito questa implementazione modificando il codice all'interno della funzione effettoLaMummia:

function effettoLaMummia(canvas, prima_parola, seconda_parola) {
  var contesto = canvas.getContext('2d');
  contesto.fillStyle = 'rgba(242,211,83,0.8)';
  var prima_parola_pos = kerningAndSize(contesto, prima_parola, 200, 60, 43);
  var eccezioni = [],
  posizione = Math.floor(seconda_parola.length/2);
  eccezioni[posizione] = 120;
  var seconda_parola_pos = kerningAndSize(contesto, seconda_parola, 330, 60, 73, eccezioni);
}

Aggiorniamo il progetto nel browser e ammiriamo il risultato ottenuto:

Figura 3. La spaziatura caratteri applicata
(clic per ingrandire)


La spaziatura caratteri applicata

Ti consigliamo anche