Historia breve del SVG
Antes de la aparición del HTML5, no existía la
posibilidad de trabajar con gráficos de tipo vectorial en una página web; Al
menos no existía de una manera estandarizada. SVG ya existía tal y como se
conoce, pero no era un estándar reconocido y sólo era soportado de manera
nativa por algunos navegadores. Por un lado existía SVG, pero por otro existía
el VML, una especificación de Microsoft que se propuso como estándar en el W3C.
Esto provocó que tan sólo Internet Explorer reconociese este tipo de formato,
mientras los navegadores de la competencia soportaban SVG; Lo cual hacía
bastante dificil crear páginas web utilizando estas tecnologías, y que se
pudiesen ver igual en todos los navegadores.
A consecuencia de esto, el programa de diseño FLASH tuvo su época dorada, ya
que era lo más comunmente utilizado para tratar con imágenes de tipo vectorial.
Pero FLASH es un programa 'de pago', un producto de Adobe que no es
precisamente gratis. Además al ser un archivo ejecutable, requería de la
instalación de un plugin para poder visualizar estos contenidos generados con
FLASH.
Por fortuna apareció la nueva versión del lenguaje HTML, conocida como HTML5.
En esta nueva especificación se reconoce el formato SVG como un estándar, lo
cual ha obligado a todos los navegadores a implementarlo de manera nativa,
incluido Internet Explorer, que soporta SVG a partir de su versión 9.
SVG, soporte universal en HTML5
Actualmente,
debido a lo anteriormente explicado, se pueden utilizar imágenes con formato
SVG de manera nativa en cualquier navegador moderno. Todos los navegadores de
uso mayoritario soportan el formato SVG en sus últimas versiones, dentro de una
página HTML5.
Esto ha permitido que los desarrolladores web puedan desligarse por fin del
programa FLASH y utilizar SVG, con todas las ventajas que eso conlleva.
Ventajas del formato SVG
¿Por qué utilizar SVG, qué
ventajas se obtienen con ello?
SVG es un formato de imágenes vectoriales. Las imágenes de tipo vectorial son
diferentes a las imágenes de mapa de bits, que son las más comunes. Imágenes de
mapa de bits son: JPG, GIF, BMP, PNG, etc. Este tipo de imágenes tiene la
caracteristica de que no son escalables. Es decir, tienen un tamaño optimo de
visualización, y si el tamaño en el que se visualizan es menor o mayor que el
tamaño propio de la imagen, sufren un efecto de pixelado, lo que hace inviable
utilizar una misma imagen de mapa de bits para hacer una miniatura o escalarla
para que aparezca más grande de lo que es realmente.
En contraposición, el formato SVG no está formado por un mapa de bits, sino por
coordenadas de puntos (unidas entre si por lineas rectas). Esta característica
hace que las imágenes vectoriales puedan ser escaladas hasta el infinito sin
perder detalle ni sufrir pixelización. Además suelen ser de carga más rápida
que las imágenes de mapa de bits, ya que son datos númericos que se descargan
muy rápido en el navegador.
Como se crean las imágenes SVG
Para
poder utilizar SVG dentro de una página HTML5, lo primero que debemos tener, obviamente,
es una imagen SVG.
¿Cómo se crean este tipo de imágenes? Existen por internet muchas aplicaciones
que generan este tipo de imágenes de forma sencilla, te recomiendo una busqueda
por google para conocer este tipo de programas. Pero realmente no se necesita
ningún programa externo para generar este tipo de imágenes, ya que realmente
estas imágenes son...XML!
Una imagen de tipo SVG realmente es un XML al que se ha añadido la extensión
SVG, en vez de la tipica, XML. Pero en esencia y estructura son iguales.
Unicamente varía la DTD empleada en ese XML, y que el nodo superior del XML es
un nodo con nombre 'svg', en vez del típico 'xml'.
Código de una imagen SVG:
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400px"
height="400px">
<g id="Cube">
<g id="caras_bordes.Cube" stroke-width="1.0px"
stroke-linejoin="miter" stroke-linecap="round"
stroke="rgb(51,26,0)">
<polygon fill="rgb(45,20,0)" points="288.0611,131.3717
179.4857,124.30176 87.0314,143.82837 241.66351,166.68231 " />
<polygon fill="rgb(47,21,0)" points="270.74426,239.27365
288.0611,131.3717 241.66351,166.68231 229.75984,324.47355 " />
<polygon fill="rgb(154,69,0)" points="229.75984,324.47355
241.66351,166.68231 87.0314,143.82837 116.26482,267.61168 " />
</g>
</g>
</svg>
SVG en una página web HTML5
Una
vez que disponemos de una o varias imágenes SVG, nos queda saber la forma en la
que podemos utilizarlas dentro de una página web.
Existen varias maneras de utilizar este tipo de imágenes, vamos a ver algunas.
SVG incrustado en una etiqueta IMG
SVG
puede ser incrustado como cualquier otro tipo de imagen, en una etiqueta de
tipo img, dentro de una página web. En la propiedad 'src' de la etiqueta img,
sólo debemos poner la ruta de la imagen SVG que queramos utilizar, y se
mostrará sin problemas en cualquier navegador moderno, siempre y cuando la
página web utilizada sea una página HTML5. Así de sencillo!
Este
sistema, aunque es el más sencillo, tiene sus desventajas. Utilizando este
sistema es más dificil acceder a las propiedades SVG de la imagen. SVG tiene su
propio DOM (Document Object Model) que puede ser utilizado para modificar este
tipo de imágenes con JavaScript. Pero incrustando el SVG en una etiqueta img es
más dificil acceder a este DOM. Por tanto este sistema lo podemos utilizar para
imágenes de tipo SVG que vayan a ser 'estáticas' dentro de nuestra página web;
Es decir, que no van a sufrir ninguna transformación posterior directamente
sobre ese objeto SVG. Pero si que es posible sustituir la ruta del objeto
imagen que lo contiene, pudiendo de esta manera generar animaciones. En
artículos posteriores se profundizará en este concepto.
Imagen SVG dentro de una etiqueta img:
<!DOCTYPE html>
<html>
<head>
<title>
</title>
</head>
<body>
<div style="width:90%;height:30em;">
<img src="public/img/tutorial_svg1b.svg" class="imgSVG"
alt="imagen SVG" title="imagen SVG" />
</div>
<script>
window.onload=function(){
alert(document.images[0].getAttribute("src"));
}
</script>
</body>
</html>
SVG incrustado en etiqueta EMBED
Con HTML5 se estándariza por fin
la etiqueta/objeto embed, que en la versión HTML4 no era un estándar. Esta
etiqueta nos permite insertar diversos tipos de documento en una página web.
Por ello se puede utilizar para insertar un documento SVG en ella.
Pero hacerlo así tiene las mismas
limitaciones que hacerlo a traves de una etiqueta img. Es decir, no podremos
acceder en principio al objeto SVG que se encuentra incrustado en el embed.
Igual que en la etiqueta img, podemos acceder a la propiedad src de embed y
desde allí ir cargando diversos svg creando una animación. Pero no podremos
acceder al DOM del objeto SVG.
SVG incrustado en etiqueta EMBED en una pagina HTML5:
<!DOCTYPE
html>
<html>
<head>
<title>
</title>
</head>
<body>
<div style="width:90%;height:100%;">
<embed src="public/img/tutorial_svg1b.svg"
id="contenedorSvg1"
type="image/svg+xml"style="width:100%;height:100%;"/>
</div>
<script>
window.onload=function(){
/*
insertando el svg en una etiqueta embed, no podremos después acceder al objeto
svg.
*/
var contenedorSvg=document.getElementById("contenedorSvg1");
alert(contenedorSvg.src)
}
</script>
</body>
</html>
SVG en etiqueta OBJECT
La etiqueta object permite cargar
diversos tipos de contenido y puede ser utilizada también para cargar un
documento SVG.
En cuanto al aceso al documento
SVG subyacente, tiene los mismos problemas que insertarlo en una etiqueta img o
embed. No hay un procedimiento estándarizado para acceder al SVG en todos los
navegadores. Internet Explorer si permite el acceso a traves de una propiedad
"object" que se han inventado. Por tanto no es un estándar reconocido
en otros navegadores, pero es bueno saber que existe.
Imagen SVG incrustado en etiqueta OBJECT en una pagina
HTML5:
<!DOCTYPE
html>
<html>
<head>
<title>
</title>
</head>
<body>
<div style="width:90%;height:100%;">
<object data="public/img/tutorial_svg1b.svg"
width="100%" height="100%" type="image/svg+xml"
id="contenedorSvg1">
</object>
</div>
<script>
window.onload=function(){
try{
var contenedorSvg=document.getElementById("contenedorSvg1");
var miOjSvg=new Object();
/*
el objeto svg sólo se puede recuperar en Internet Explorer 9.
*/
if(navigator.AppName=="Microsoft Internet Explorer"){
miOjSvg=contenedorSvg.object.childNodes[0];
}else{
miOjSvg=contenedorSvg.childNodes[0];
}
alert("miOjSvg: "+ miOjSvg +"");
}catch(e){
alert(e)
}
}
</script>
</body>
</html>
SVG incrustado en el documento
Hemos visto diversas maneras de
insertar un documento SVG en una página HTML5 a traves de etiquetas
"auxiliares". Pero HTML5 permite la inserciónde un documento XML (y
SVG es un documento XML) dentro de la propia página directamente.
Esta opción puede parecer la idónea pero a decir verdad tiene un inconveniente
bastante grande. Si se inserta un documento XML directamente en una página web,
no estamos separando las diversas capas de presentación. Existe una forma de
diseñar páginas web que se puede considerar más óptima. Esta forma de diseño lo
que hace es tratar de separar contenidos, presentación y la lógica de la
página, que se trata como si fuese una aplicación.
Es por ello que trataremos de que los estilos de la página (el CSS) vaya en
archivos separados, los scripts los guardaremos también en archivos js
separados, etc.
Esto permite la modificación posterior de manera más sencilla. Permite más
escalabilidad y es más fácil también entender el código y lo que hace. Hay
muchas más ventajas sobre estos tipos de diseño por capas y hay muchísimo
escrito en internet. Una de las maneras más conocidas de este tipo de diseño es
el MVC, Modelo-Vista-Controlador. Recomiendo una busqueda por internet para
saber más sobre ello.
En estos ejemplos no se están separando las tres capas de presentación para
facilitar el entendimiento del lector.
Volviendonos a centrar en el
tema, si insertamos un documento SVG directamente en la página web, ya no
tendremos problema para acceder al DOM del objeto SVG porque el documento SVG
pasa a formar parte del DOM de la propia página. Accederemos al objeto SVG como
se accede a cualquier tipo de elemento en una página web, a través del método
getElementById y métodos existentes similares. Una vez accedemos al elemento,
ya podemos utilizar los métodos, propiedades etc propios de SVG.
Profundizaremos en ello en posteriores tutoriales.
SVG incrustado directamente en una pagina HTML5:
<!DOCTYPE
html>
<html>
<head>
<title>
</title>
</head>
<body>
<div style="width:90%;height:100%;">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400px" height="400px"
id="ojSvg">
<g id="Cube">
<g id="caras_bordes.Cube" stroke-width="1.0px"
stroke-linejoin="miter" stroke-linecap="round"
stroke="rgb(51,26,0)">
<polygon fill="rgb(45,20,0)" points="288.0611,131.3717
179.4857,124.30176 87.0314,143.82837 241.66351,166.68231 " />
<polygon fill="rgb(47,21,0)" points="270.74426,239.27365
288.0611,131.3717 241.66351,166.68231 229.75984,324.47355 " />
<polygon fill="rgb(154,69,0)" points="229.75984,324.47355
241.66351,166.68231 87.0314,143.82837 116.26482,267.61168 " />
</g>
</g>
</svg>
</div>
<script>
window.onload=function(){
try{
var miOjSvg=document.getElementById("ojSvg");
/*
el objeto svg se puede recuperar
*/
alert("miOjSvg: "+ miOjSvg +"");
}catch(e){
alert(e)
}
}
</script>
</body>
</html>
SVG generado con JavaScript
Hemos
visto algunas formas estáticas de inserción de documentos SVG en una página
HTML5. Ahora veamos una manera dinámica de hacerlo. Mediante JavaScript.
A
traves del DOM podemos generar cualquier tipo de elemento en una página web.
Los documentos de tipo SVG son algo especiales pues son en realidad XML y deben
ser tratados con métodos enfocados al XML. Por tanto utilizaremos algunos
métodos sustitutivos de los tradicionales createElement, o setAttributes. En
sustitución a estos utilizaremos createElementSN o setAttributeSN. Son métodos
necesarios para conseguir que se genere un SVG visible en todos los
navegadores. En el ejemplo siguiente puedes ver como se genera un documento SVG
idéntico al que antes teníamos alojado en un archivo SVG aparte.
Este tema es bastante amplio como para explicarlo en un sólo capítulo. De
momento veremos como se genera un documento SVG y en tutoriales posteriores
veremos como acceder al DOM de SVG y sus diversos métodos, propiedades, eventos
etc. con el fin de poder realizar diversas transformaciones en nuestro SVG.
Imagen SVG generada con JavaScript en una pagina HTML5:
<!DOCTYPE
html>
<html>
<head>
<title>
Generar SVG con JavaScript
</title>
</head>
<body>
<div id="contenedorSvg">
</div>
<script>
function crearSvg(ancho,alto){
try{
var svgNS="http://www.w3.org/2000/svg";
var xlinkNS="http://www.w3.org/1999/xlink";
var miSvgNew=document.createElementNS(svgNS,"svg");
var capaContenedor=document.getElementById("contenedorSvg");
capaContenedor.appendChild(miSvgNew);
var miAtt=document.createAttributeNS(xlinkNS,"xlink");
miAtt.nodeValue=xlinkNS;
miSvgNew.setAttributeNodeNS(miAtt);
miSvgNew.setAttribute("version","1.0");
miSvgNew.setAttribute("width",""+ ancho +"px");
miSvgNew.setAttribute("height",""+ alto +"px");
miSvgNew.setAttribute("id","miSvg1");
var miSvg1=document.getElementById("miSvg1");
var miSvgShape=document.createElementNS(svgNS,"g");
miSvgNew.appendChild(miSvgShape);
miSvgShape.setAttribute("id","Cubo");
var miSvgMarco=document.createElementNS(svgNS,"g");
miSvgShape.appendChild(miSvgMarco);
miSvgMarco.setAttribute("id","caras_bordes.Cubo");
miSvgMarco.setAttribute("stroke-width","1.0px");
miSvgMarco.setAttribute("stroke-linejoin","miter");
miSvgMarco.setAttribute("stroke-linecap","round");
miSvgMarco.setAttribute("stroke","rgb(51,26,0)");
var miSvgPoligon1=document.createElementNS(svgNS,"polygon");
miSvgMarco.appendChild(miSvgPoligon1);
miSvgPoligon1.setAttribute("fill","rgb(45,20,0)");
miSvgPoligon1.setAttribute("points","288.0611,131.3717
179.4857,124.30176 87.0314,143.82837 241.66351,166.68231");
var miSvgPoligon2=document.createElementNS(svgNS,"polygon");
miSvgMarco.appendChild(miSvgPoligon2);
miSvgPoligon2.setAttribute("fill","rgb(47,21,0)");
miSvgPoligon2.setAttribute("points","270.74426,239.27365
288.0611,131.3717 241.66351,166.68231 229.75984,324.47355");
var miSvgPoligon3=document.createElementNS(svgNS,"polygon");
miSvgMarco.appendChild(miSvgPoligon3);
miSvgPoligon3.setAttribute("fill","rgb(154,69,0)");
miSvgPoligon3.setAttribute("points","229.75984,324.47355
241.66351,166.68231 87.0314,143.82837 116.26482,267.61168");
}catch(e){
alert(e)
}
}
window.onload=function(){
crearSvg(400,400);
var miOjSvg=document.getElementById("miSvg1");
/*
el objeto svg se puede recuperar
*/
alert("miOjSvg: "+ miOjSvg +"");
}
</script>
</body>
</html>
DEMOSTRACIÓN
En Visual Studio vamos a dar click en menú File à New à Project
En la Ventana emergente le damos click a Web y espacio
Name colocamos el nombre del proyecto que para el Ejemplo es “Demo 11 20480” y
luego presionamos el botón OK
Le
damos click a OK y Nos aparecerá la siguiente ventana donde Seleccionamos Emty
y tildamos la opción de WebForm:
Al
dar click en OK, En el espacio de nombre del proyecto damos click derecho y
seleccionamos Add à
New Items
En
la siguiente ventana seleccionamos la Opción “Pagina HTML” y colocamos como
nombre del archivo “SvgDocument.html”, para luego presionar el botón Add.
En
el elemento <HEAD></HEAD> escribiremos nuestro código HTML:
En
el elemento <BODY></BODY> escribiremos nuestro código HTML:
Y
finalizamos con un <SCRIPT></SCRIPT>
Procedemos
a establecer la página como Inicio
Y
corremos la aplicación
Le
damos click en el botón Transformations
Y
ahora en “Events”.
Si
le damos click al gráfico de color Rojo
Si
le damos click al de Azul