raphaël - Obtener el tamaño del texto sin usar la función boundingBox en la biblioteca Raphael javascript
raphaël js (2)
Estoy intentando crear algunos botones con texto en javascript usando la biblioteca Rahpael. Me gustaría saber el tamaño del texto con estilo, antes de dibujar para evitar eso, así puedo crear el fondo adecuado (el botón). También me gustaría evitar dibujar el texto fuera del lienzo / papel (la posición del texto es la posición de su centro).
Puedo usar el método Raphaels getBox (), pero tengo que crear (dibujar) el texto en primer lugar para hacer esto. Así que dibujo texto para obtener el tamaño para poder dibujarlo en la posición correcta. Esto es feo Así que estoy buscando algún método general para estimar las métricas del texto con estilo para una fuente determinada, tamaño de letra, familia ...
Existe la posibilidad de hacer esto utilizando el lienzo HTML5 http://www.html5canvastutorials.com/tutorials/html5-canvas-text-metrics/ pero Raphael no usa lienzo. ¿Hay alguna posibilidad de obtener las métricas de texto usando Raphael o Javascript simple?
Hay un par de formas de cortar este gato. Dos obvios vienen a la mente fácilmente.
Técnica de regla fuera de vista
Este es el más fácil. Simplemente cree un elemento de texto fuera del cuadro de visualización del lienzo, rellene con la información y el texto de su fuente, y mídalo.
// set it up -- put the variable somewhere globally or contextually accessible, as necessary
var textRuler = paper.text( -10000, -10000, '''' ).attr( { fill: ''none'', stroke: ''none'' } );
function getTextWidth( text, fontFamily, fontSize )
{
textResult.attr( { text: text, ''font-family'': fontFamily, ''font-size'': fontSize } );
var bbox = textResult.getBBox();
return bbox.width;
}
No es elegante en ningún momento de la imaginación. Pero lo hará con relativamente poca carga y sin complejidad.
Cufonized Fuente
Si estaba dispuesto a considerar el uso de una fuente cufonizada , podría calcular el tamaño de una cadena de texto dada sin necesidad de meterse con el DOM en absoluto. De hecho, esto es probablemente aproximadamente lo que los elementos del lienzo measureText
método measureText
detrás de las escenas. Dada una fuente importada, simplemente harías algo como esto (¡ten en cuenta este protocode!)
// font should be the result of a call to paper.[getFont][2] for a cufonized font
function getCufonWidth( text, font, fontSize )
{
var textLength = text.length, cufonWidth = 0;
for ( var i = 0; i < textLength; i++ )
{
var thisChar = text[i];
if ( ! font.glyphs[thisChar] || ! font.glyphs[thisChar].w )
continue; // skip missing glyphs and/or 0-width entities
cufonWidth += font.glyphs[thisChar].w / font.face[''units-per-em''] * fontSize;
}
return cufonWidth;
}
Realmente me gusta trabajar con fuentes cufonizadas: en términos de su capacidad para ser animadas de maneras interesantes, son mucho más útiles que el texto. Pero este segundo enfoque puede ser una complejidad adicional más de la que necesita o desea.
Sé que parece descuidado, pero no debería tener problemas dibujando el texto, midiéndolo, luego dibujando el botón y moviendo la etiqueta. Para estar seguro, simplemente sácalo de la pantalla:
var paper = Raphael(0, 0, 500, 500);
var text = paper.text(-100, -100, "My name is Chris");
//outputs 80 12
console.log(text.getBBox().width, text.getBBox().height);
Si esto REALMENTE ofende tu sensibilidad, sin embargo, ¡y lo entendería! - puede generar fácilmente un objeto para recordar el ancho de cada carácter para una fuente determinada:
var paper = Raphael(0, 0, 500, 500),
alphabet = "abcdefghijklmnopqrstuvwxyz";
font = "Arial",
charLengths = {},
ascii_lower_bound = 32,
ascii_upper_bound = 126;
document.getElementById("widths").style.fontFamily = font;
for (var c = ascii_lower_bound; c <= ascii_upper_bound; c += 1) {
var letter = String.fromCharCode(c);
var L = paper.text(-50, -50, letter).attr("font-family", font);
charLengths[letter] = L.getBBox().width;
}
//output
for (var key in charLengths) if (charLengths.hasOwnProperty(key)) {
var row = document.createElement("tr");
row.innerHTML = "<td>" + key + "</td><td>" + charLengths[key] + "</td>";
document.getElementById("widths").appendChild(row);
}