Il metodo fillText()
ha un quarto argomento facoltativo, ovvero larghezza massima per il rendering della stringa.
documentazione del MDN dice ...
maxwidth
facoltativo; la larghezza massima da disegnare. Se specificato, e la stringa è calcolata per essere più ampia di questa larghezza, il carattere viene regolato per utilizzare un font a condensazione orizzontale più (se uno è disponibile o se uno sufficientemente leggibile può essere sintetizzato ridimensionando il font corrente orizzontalmente) o un font più piccolo.
Tuttavia, al momento della scrittura, questo argomento non è supportata navigatore ben croce, che porta alla seconda soluzione utilizzando measureText()
per determinare le dimensioni di una stringa senza renderlo.
var width = ctx.measureText(text).width;
Ecco come posso farlo ...
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
// Font sizes must be in descending order. You may need to use `sort()`
// if you can't guarantee this, e.g. user input.
var fontSizes = [72, 36, 28, 14, 12, 10, 5, 2],
text = 'Measure me!';
// Default styles.
ctx.textBaseline = 'top';
ctx.fillStyle = 'blue';
var textDimensions,
i = 0;
do {
ctx.font = fontSizes[i++] + 'px Arial';
textDimensions = ctx.measureText(text);
} while (textDimensions.width >= canvas.width);
ctx.fillText(text, (canvas.width - textDimensions.width)/2, 10);
jsFiddle.
Ho un elenco di dimensioni dei caratteri in ordine decrescente e scorre l'elenco, determinando se il testo renderizzato si adatta alle dimensioni dell'area di disegno.
Se lo fa, rendo il centro del testo allineato. Se è necessario eseguire il riempimento a sinistra ea destra del testo (che apparirà più gradevole), aggiungere il valore di riempimento allo textDimensions.width
durante il calcolo se il testo si adatta.
Se si dispone di un lungo elenco di dimensioni dei caratteri da provare, è preferibile utilizzare uno binary search algorithm. Ciò aumenterà tuttavia la complessità del tuo codice.
Ad esempio, se si dispone di 200 dimensioni di carattere, l'iterazione lineare attraverso gli elementi di matrice sarà O (n).
Il chop binario deve essere O (log n).
Qui c'è il budella della funzione.
var textWidth = (function me(fontSizes, min, max) {
var index = Math.floor((min + max)/2);
ctx.font = fontSizes[index] + 'px Arial';
var textWidth = ctx.measureText(text).width;
if (min > max) {
return textWidth;
}
if (textWidth > canvas.width) {
return me(fontSizes, min, index - 1);
} else {
return me(fontSizes, index + 1, max);
}
})(fontSizes, 0, fontSizes.length - 1);
jsFiddle.
link ai documenti e/o codice di esempio potrebbe essere bello. – Phrogz
@Phrogz Controlla la risposta aggiornata. :) – alex
Avrei dovuto sapere che non si ottiene 90k + ripetendo di non seguire. :) Molto bella. – Phrogz