Texto creado dinamicamente
En JavaScript, para crear un elemento <text> o cualquier otro elemento SVG necesitamos utilizar el método createElementNS
const SVG_NS = 'http://www.w3.org/2000/svg';// define el espacio de nombres
let text = document.createElementNS(SVG_NS, 'text');
Qué son los espacios de nombre en SVG
También necesitamos darle al <text> un textContent, ya que sin el textContent el elemento <text> es un elemento vacío.
text.textContent = 'el texto que tu quieras';
A continuación agregamos el elemento <text> al svg y lo hacemos utilizando el método appendChild.
elSvg.appendChild(text);
const SVG_NS = 'http://www.w3.org/2000/svg';
let text = document.createElementNS(SVG_NS, 'text');
text.textContent = 'el texto que tu quieras';
elSvg.appendChild(text);
Y ya tenemos un elemento <text> aunque no es un elemento muy interesante. Almeno que el viewBox empiece con valores negativos en y ( por ejemplo viewBox='0 -50 200 100' ), o que el svg tenga overflow:visible no podemos ver este texto.
Un elemento <text> sin argumentos toma los valores por defecto que sitúan el texto en el origen del lienzo svg (x='0' y ='0'). Además el valor por defecto de dominant-baseline es auto lo que en modo de escritura horizontal (como el español) equivale a dominant-baseline = 'alphabetic'. Esto quiere decir que lo único que podremos ver son las astas descendentes de algunas letras como p o g.
Cómo alinear texto en SVG
En el siguiente ejemplo voy a centrar el texto en el medio del lienzo svg, o sea alrededor del punto x='50' y='25'. Así que voy a necesitar algunos atributos más:
text.setAttributeNS(null,'x',50); text.setAttributeNS(null,'y',25); text.setAttributeNS(null, 'dominant-baseline','middle'); text.setAttributeNS(null, 'text-anchor','middle');
A diferencia de x e y podemos declarar los otros dos atributos, dominant-baseline y text-anchor en CSS, aunque no hay que olvidar que los atributos de presentación tienen una especificidad muy baja, justo por encima de los estilos por defecto, y pueden ser fácilmente sobreescritos con reglas CSS.
text{
dominant-baseline : middle;
text-anchor : middle;
}
Cuando tenemos tantos atributos por definir en JavaScript, lo podemos hacer de una manera más eficiente si los ponemos dentro de un objeto:
let o = {
props: {
x: 50,
y: 25,
'font-size':10,
'dominant-baseline': 'middle',
'text-anchor': 'middle'
},
txtConent: 'el texto que tu quieras'
};Por favor observe que las propiedades que llevan guión aparecen entre comillas.
A continuación podemos escribir una función para crear cualquier elemento de <text>. La función toma como argumentos el elemento padre (al cual agregamos el texto), y un objeto ( como el de arriba ) que contiene las propiedades y el texto para el nuevo elemento:
function dibujarTexto(o, parent) {
// crea un nuevo elemento de texto
let text = document.createElementNS(SVG_NS, 'text');
//itera el objeto o.props
for (let name in o.props) {
if (o.props.hasOwnProperty(name)) {
// establece el valor de un nuevo atributo del elemento text
text.setAttributeNS(null, name, o.props[name]);
}
}
// define el texto del nuevo elemento
text.textContent = o.txtConent;
// agrega el texto al elemento padre
parent.appendChild(text);
// devuelve el elemento creado para el caso en el cual necesitamos utilizarlo de nuevo
return text;
}Reutilizar el elemento de texto
En el siguiente ejemplo hay un <input type='text' donde podemos escribir el texto que queramos que aparezca en el SVG.
el nombre:
Necesitamos también una función que actualiza el texto:
function actualizarTexto(text,txtConent){
text.textContent = txtConent;
}El primer argumento de esta función es el elemento <text> que queremos actualizar. El segundo argumento es el contenido del texto.
let txt = dibujarTexto(o, elSvg);// crea y dibuja un nuevo elemento text
//utilizamos el método addEventListener para detectar el cambio de valor del input #elNombre y utilizar el nuevo valor como textContent
elNombre.addEventListener('input', ()=>{actualizarTexto(txt,elNombre.value)})See the Pen Crear un elemento de texto en SVG by Gabi (@enxaneta) on CodePen.