Crear elementos SVG con JavaScript
En HTML podemos crear nuevos elementos de manera dinámica utilizando javascript y el método createElement
:
var nuevaImagen = document.createElement('img');
Crear nuevos elementos en SVG es un poco diferente ya que tenemos que utilizar espacios de nombre.
Para crear un nuevo elemento svg:
- utilizamos el método createElementNS
donde NS viene de Namespace ( espacio de nombre en inglés ).
- A continuación utilizamos el método setAttributeNS
para establecer el valor de los atributos necesarios.
- Finalmente agregamos el nuevo elemento al elemento padre.
Crear un circulo
Un circulo en svg puede ser representado de esta manera: necesitamos un elemento <circle>
que tiene varios atributos: cx
, cy
, r
y opcionalmente fill
.
<circle cx="20" cy="25" r="20" fill="red" />
Para recrear esto en JavaScript primero hay que crear un nuevo elemento <circle>
const SVG_NS = "http://www.w3.org/2000/svg";
let circulo = document.createElementNS(SVG_NS, 'circle');
donde SVG_NS
representa el espacio de nombre XML definido para los elementos svg. Como que el espacio de nombre no cambia lo he guardarlo en una constante javascript: const SVG_NS
A continuación utilizamos el método setAttributeNS
para establecer el valor de los atributos necesarios: el centro del circulo ( cx
, cy
), el radio r
y el fill
.
circulo.setAttributeNS(null, "cx", 25);
circulo.setAttributeNS(null, "cy", 25);
circulo.setAttributeNS(null, "r", 20);
circulo.setAttributeNS(null, "fill", "red");
A veces los elementos svg pueden tener muchos atributos y para optimizar este proceso voy a poner todos estos atributos en un objeto donde el nombre de la propiedad es el mismo nombre del atributo y el valor de la propiedad es el valor del atributo.
let objeto = {cx:25, cy:25, r:20, fill:"red"}
Ahora podemos establecer el valor de todos los atributos "en bloque" de esta manera:
//para cada nombre de propiedad en el objeto de los atributos a definir
for (let nombre in objeto) {
//si el objeto tiene esta propiedad
if (objeto.hasOwnProperty(nombre)) {
// establece un nuevo atributo del circulo
circulo.setAttributeNS(null, nombre, objeto[nombre]);
/*el nombre de la propiedad es el mismo nombre del atributo y
el valor de la propiedad es el valor del atributo.*/
}
}
Podemos utilizar todo esto para crear la siguiente función:
function dibujarCirculo(objeto, elementoPadre) {
let circulo = document.createElementNS(SVG_NS, 'circle');
for (var nombre in objeto) {
if (objeto.hasOwnProperty(nombre)) {
circulo.setAttributeNS(null, nombre, objeto[nombre]);
}
}
// agrega el nuevo circulo al elemento padre
elementoPadre.appendChild(circulo);
//opcional: la función devuelve el circulo creado para poder utilizarlo más tarde
return circulo;
}
See the Pen SVG dibujarCirculo*** by Gabi (@enxaneta) on CodePen.
Crear una nueva forma geometrica en SVG
Observamos que de la misma manera podemos crear un elemento <ellipse>
let elipsis = document.createElementNS(SVG_NS, ellipse);
o un elemento <rect>
:
let rect = document.createElementNS(SVG_NS, rect);
o cualquier otra forma geométrica. Para esto podemos aprovechar la función anteriormente creada. Voy a añadir un nuevo argumento: el nombre del elemento que quiero crear por ejemplo nombreElemento = "circulo"
o nombreElemento ="rect"
. A la hora de crear un nuevo elemento voy a decir:
let elemento = document.createElementNS(SVG_NS, nombreElemento);
Así es como queda la función:
function dibujarElementoSVG(objeto, nombreElemento, elementoPadre) {
let elemento = document.createElementNS(SVG_NS, nombreElemento);
for (var nombre in objeto) {
if (objeto.hasOwnProperty(nombre)) {
elemento.setAttributeNS(null, nombre, objeto[nombre]);
}
}
elementoPadre.appendChild(elemento);
//opcional: la función devuelve el elemento creado para poder utilizarlo más tarde
return elemento;
}
Para crear un nuevo rectangulo puedo utilizar esta función de esta manera:
See the Pen dibujarElementoSVG*** by Gabi (@enxaneta) on CodePen.
Puedo utilizar la misma función para crear un cicle
o una ellipse
incluso un polygon
, una polyline
o un trazado path
Crear un nuevo elemento <svg>
Para crear un nuevo elemento svg voy a utilizar de nuevo el espacio de nombre de este que había guardado en una constante javascript: const SVG_NS = "http://www.w3.org/2000/svg"
const SVG_NS = 'http://www.w3.org/2000/svg';
let svg = document.createElementNS(SVG_NS, 'svg');
A continuación podemos establecer algunos atributos del elemento SVG como por ejemplo viewBox
, width
y hight
.
¡OJO! viewBox
va en camelCase. Todos estos atributos son opcionales. Si no los declaramos el elemento SVG tendrá una anchura de 300px y una altura de 150px.
svg.setAttributeNS(null, "viewBox", "0 0 200 100");
al final podemos anexar el nuevo elemento SVG al DOM:
divPadre.appendChild(svg);
Crear un nuevo elemento <symbol>
Un elemento <symbol> se utiliza para agrupar elementos SVG con el propósito de reutilizarlos más tarde. Para crear un elemento <symbol>
utilizamos como hasta ahora, el espacio de nombre de SVG
// crea un nuevo elemento symbol
let symbol = document.createElementNS(SVG_NS, 'symbol');
// lo agrega al DOM
svg.appendChild(symbol);
// crea un elemento path
let trazado = document.createElementNS(SVG_NS, 'path');
trazado.setAttributeNS(null, "d", "M25,25 L175,75");
trazado.setAttributeNS(null,"id","trazado");
// lo agrega al symbol que hemos creado anteriormente.
symbol.appendChild(trazado);
Crear un nuevo elemento <use>
Crear un nuevo elemento <use> con JavaScript es un poco más complicado ya que necesitamos otro espacio de nombre para XML Linking Language (XLink): http://www.w3.org/1999/xlink.
Exactamente como antes podemos guardar el espacio de nombre en una constante JavaScript:
const SVG_XLINK = "http://www.w3.org/1999/xlink";
// crea un nuevo elemento use utilizando el espacio de nombre para svg
let use = document.createElementNS(SVG_NS, 'use');
// establece el valor del atributo href utilizando el espacio de nombre
// para XML Linking Language (XLink):
use.setAttributeNS(SVG_XLINK, 'xlink:href', '#trazado');
// agrega el nuevo elemento use al svg
svg.appendChild(use);
Vea todo esto en Codepen
See the Pen Crear elementos svg, symbol, y use con JavaScript******* by Gabi (@enxaneta) on CodePen.
Artículos relacionados
Enlaces útiles
- Optimize el código SVG con SVG Optimiser
- Más información acerca del soporte de SVG en los navegadores
- Libros en ingles:
- SVG Essentials
- SVG Colors, Patterns & Gradients