En la mayoría de los casos, son los mismos. Pero encontré este caso especial, es diferente cuando cambio el orden de los caracteres.
const ctx = document.createElement('canvas').getContext('2d'); const tw = text => ctx.measureText(text).width; tw('Tr') - tw('T') - tw('r') // -0.3662109375 tw('rT') - tw('T') - tw('r') // 0¿Alguien puede decirme las reglas de este comportamiento? ¡Gracias!
Esto se debe al kerning , que es como algunos personajes estarán más o menos cerca de sus vecinos. Esto dependerá de la fuente utilizada y de los caracteres mostrados.
Chrome agregó recientemente soporte para una propiedad .fontKerning que podemos usar para deshabilitar esto,
if ("fontKerning" in CanvasRenderingContext2D.prototype) { const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); ctx.textBaseline = "middle"; ctx.font = "30px sans-serif"; ctx.fillText("AV", 0, 30); console.log("with kerning", ctx.measureText("AV").width); ctx.fontKerning = "none"; console.log("without kerning", ctx.measureText("AV").width); ctx.fillText("AV", 0, 60); console.log("sum of chars", ctx.measureText("A").width + ctx.measureText("V").width); } else { console.log("your browser doesn't support setting fontKerning"); } <canvas></canvas>y podría usar fuentes de espacio único para evitarlo, pero eso aún no sería a prueba de balas porque incluso entonces algunos glifos simplemente no se pueden medir como lo hizo.
Entonces, lo mejor es medir el texto completo que desea medir.