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.