Imágenes vectoriales SVG

Profesores:JAB y Ester Torres

¿Qué son las imágenes SVG?

Con el elemento SVG (Scalable Vector Graphics) podemos crear imágenes vectoriales redimensionables de manera dinámica o interactiva utilizando diferentes atributos. Al convertirse en 2001 en una recomendación del W3C ya es aceptado en la mayoría de navegadores (Firefox desde la versión 1.5, Opera desde su versión 8, Chrome y Safari de manera conjunta, y también increiblemente Internet Explorer, desde su versión 9).

Estos atributos son rect (para crear rectángulos), circle (que no hace falta traducir), line, ellipse, polygon, polyline (multi-lineas) y text.
Antes de tratarlos un poco más extensamente, vamos a presentar algunos ejemplos rápidos y socorridos, ... como no ... con banderas de algunos países, ya que la mayoría son fáciles de dibujar.

Varios ejemplos simples

Japón
<svg width="150" height="90" xmlns="http://www.w3.org/2000/svg">
  <rect width="150" height="90"  fill="white" stroke="black" stroke-width="1"/>
  <circle cx="75" cy="45" r="35" fill="red"/>
</svg>
	
Italia
<svg width="150" height="90" xmlns="http://www.w3.org/2000/svg">
  <rect width="150" height="90"  fill="green" stroke="black" stroke-width="1"/>
  <rect x="50" y="1" width="50" height="90" fill="white"/>
  <rect x="100" y="1" width="50" height="90" fill="red"/>
</svg>
	
Alemania
<svg width="150" height="90" xmlns="http://www.w3.org/2000/svg">
  <rect width="150" height="90"  fill="black" stroke="black" stroke-width="1"/>
  <rect x="0" y="30" width="150" height="30" fill="red"/>
  <rect x="0" y="60" width="150" height="30" fill="yellow"/>
</svg>
Catalunya
  <rect width="150" height="90"  fill="yellow" stroke="black" stroke-width="1"/>
  <rect x="0" y="10" width="150" height="10" fill="red"/>
  <rect x="0" y="30" width="150" height="10" fill="red"/>
  <rect x="0" y="50" width="150" height="10" fill="red"/>
  <rect x="0" y="70" width="150" height="10" fill="red"/>
Noruega
  <rect width="150" height="90"  fill="red" stroke="black" stroke-width="1"/>
  <rect x="38" y="0" width="30" height="90" fill="white"/>
  <rect x="0" y="33" width="150" height="30" fill="white"/>
  <rect x="45" y="0" width="16" height="90" fill="blue"/>
  <rect x="0" y="40" width="150" height="16" fill="blue"/>
Suiza
<svg width="150" height="90" xmlns="http://www.w3.org/2000/svg">
  <rect width="150" height="90"  fill="red" stroke="black" stroke-width="1"/>
  <rect x="40" y="33" width="70" height="24" fill="white"/>
  <rect x="63" y="10" width="24" height="70" fill="white"/>
</svg>

Para el dibujo de estas banderas se han utilizado únicamente rectángulos (rect) y un círculo (circle) dentro de sus respectivos (svg), pero existen otros atributos muy interesantes.

La etiqueta <svg

>
<svg>
Lo primero y obligatorio es agrupar todos los atributos dentro de un <svg>.
Cabe decir que en los casos de Catalunya y Noruega (de los ejemplos superiores) los 'rect' utilizados no se han encerrado en un <svg> para no romper la maquetación que iguala a todas las banderas, pero para que su código sea correcto debe estar contenido entre un <svg> y un </svg>.
<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg">
</svg>
En este caso se crea un "lienzo" de 300 píxeles de ancho por 200 píxeles de alto. Si dentro de estos 2 tags no se introduce ningún atributo no se dibuja nada.
rect
Para la creación de rectángulos y cuadrados tenemos el atributo rect, que tiene las siguientes propiedades (las que no se utilicen se pueden omitir):
<rect x="0" y="0" rx="12" ry="12" width="60" heigh="60" fill="gold" stroke="green" stroke-width="1" opacity="0.8"/>

En este caso se trataría de un cuadrado de unas dimensiones de 60 píxeles de ancho por 60 píxeles de alto, que empieza a dibujar en las coordenadas 0/0 (tomando como inicio la esquina superior izquierda donde está ubicado el svg), con unos ángulos suaves y redondeados (12). Con un color oro (gold) de relleno, un grosor de 1 píxel de color verde y todo con una transparencia del 80%.
circle
Para la creación de círculos (no elipses, para los que existe un atributo propio):
<circle cx="100" cy="100" r="45" fill="olive" stroke="black" stroke-width="1" opacity="0.9"/>

Círculo con un radio de 45px (por lo tanto medirá 90 píxeles de ancho y alto), ubicado el centro del círculo en las coordenadas 100/100. Con un color 'oliva' de relleno, un grosor de 1 píxel de color negro y todo con una opacidad del 90%.
ellipse
Para la creación de círculos (no elipses, para la que existe un atributo propio):
<ellipse cx="100" cy="100" rx="50" ry="25" fill="purple" stroke="black" stroke-width="1"/>

Ellipse con un radio horizontal de 50px (por lo tanto mediría 100 píxeles de ancho), y un radio vertical de 25 (tendrá una altura total de 50 píxeles) ubicado (el centro de la elipse) en las coordenadas 100/100. Con un color púrpura de relleno y un grosor de 1 píxel de color negro (sin transparencia, ya que se ha omitido -opacity-).
line
Se puedan crear líneas rectas, pudiendo especificar el tipo de línea:
<line x1="0" y1="0" x2="260" y2="40" stroke="fuchsia" stroke-width="4" stroke-dasharray="18,7,9,20"/>
18 7 9 20
Línea que va desde la posición 0,0 (esquina superior izquierda definida por el svg) hasta 260 píxeles a la derecha y 40 hacia abajo (osea, será una línea diagonal) de un color fucsia de 4 píxeles de grosor y con un tipo de línea discontinua.
Los 4 valores de stroke-dasharray (18,7, 9,29) indican (por parejas) la continuidad de la línea. Así, los dos primeros valores (18,7) indican, el primero, un tramo visible de una longitud de 18 píxeles, seguido de un tramo de linea no visible de 7 píxeles. Seguidamente, los dos valores siguientes (9,20), indican un tramo de 9 píxeles de línea visible, seguido de 20 píxeles de tramo no visible, repitiendo dichos valores hasta el final de la longitud de la línea.
polyline
Con más potencia que line, con polyline es posible crear múltiples líneas que normalmente forman figuras con una forma abierta.
<polyline points="0,90, 10,90, 10,40, 40,10, 50,20, 50,10, 60,10, 60,30, 70,40, 70,90, 80,90" fill="none" stroke="black" stroke-width="3"/>
;
Con estas 10 líneas se dibuja el contorno de una casa. Las líneas se describen por parejas, siendo los valores del primer punto (0,90, coordenada situada en la esquina inferior izquierda del espacio definido por el svg), que describe una línea que se extiende hasta las coordenadas descritas en el siguiente par de valores (10,90). Es decir, la primera línea se extiende desde la coordenada (x=0/y=90) hasta la coordenada (x=10/y=90).
Así, estos primeros 4 valores dibujan una línea horizontal de 10 píxeles. Para todo este conjunto de líneas se utiliza un color negro de 3 píxeles de grosor sin ningún tipo de relleno.
polygon
Con más potencia que line y muy parecido a polyline, con polygon es posible crear figuras de forma normalmente cerradas, a diferencia que polyne, que está más orientado a figuras abiertas.
<polygon points="50,0, 82,100, 0,37, 100,37, 20,100, 50,0" fill="gold" stroke="black" stroke-width="3"/>
<polygon points="50,0, 62,37, 100,37, 70,61, 82,100,  50,75,  20,100,  31,61, 0,37,  39,37,  50,0" fill="gold" stroke="black" stroke-width="3"/>

; ;

Con estos dos polígonos se representan dos estrellas basadas en una misma forma. El primer polígono compuesto por 5 líneas y el segundo, algo más elaborado, compuesto por 10 líneas.
Las líneas se describen y dibujan siempre por parejas. Por ejemplo, en la primera estrella, los valores del primer punto (50,0: situado en la esquina superior central) describe una línea que va hasta las coordenadas descritas en el siguiente par de valores (82,100). Así, estos primeros 4 valores dibujan una línea en diagonal que va desde el punto superior de la estrella hasta su extremo inferior derecho. Ambos polígonos tienen definido un relleno (fill) y una línea con color (negro) y grosor (3), por lo que podemos ver que, aunque comparten la misma forma, ambas estrellas son bastante diferentes en cuanto a su construcción.

Sin embargo, si en ambos polígonos sustituimos stroke="black" por stroke="none", el resultado visual de ambos polígonos es idéntico:

; ;
text
Permite "dibujar" texto (vectorial), pudiendo personalizar la rotación de cada una de las letras que componen dicho texto.
<text x="30" y="35" rotate="17 0 -9 11 10 -3" fill="red" stroke="white" stroke-width="2">
  Javier
</text>
Javier
Con este cógido se crea un imagen vectorial de un texto en el que se han definido una serie de parámetros comunes para todo el texto (tipo de letra, tamaño, colores y posición), al mismo tiempo que se definido un grado de rotación diferente para cada una de las letras que forman el texto (siendo 17º para la letra "J", 0 grados para la "a" o bien -9º, que realiza una rotación de la letra "v" hacia la izquierda.

Aunque lo más sorprendente de ésto es que este texto (vectorial) sigue siendo texto y que por lo tanto se puede seleccionar como si de texto plano se tratase ... inténtalo que es gratis ...

.. y ya por último,

Un truco útil

¿Qué pasaría si nos pasamos un par de horitas definiendo coordenada a coordenada un dibujo complejo y cuando acabamos nos damos cuenta de que queremos MOVER todo el dibujo unos píxeles a la derecha o arriba para que cuadre y encaje en el html correctamente?

Al estar definidas todas las coordenadas píxel a píxel, lo único que podríamos hacer sería mover el SVG entero.
Para ello podemos colocar al final del código un sencillo 'transform' para mover todo el codigo anterior los píxeles que deseemos...
<text x="30" y="35" rotate="17 0 -9 11 10 -3" fill="red" stroke="white" stroke-width="2" transform="translate(20,5)">
  Javier
</text>
Con este 'transform' final moveríamos todo el código anterior 20 píxeles a la derecha y 5 píxeles hacia abajo (pudiendo utilizar números negativos si queremos moverlo hacia la izquierda o hacia arriba).