logoApuntes agrupados: Imágenes svg


Imágenes svg (svg): Se encontraron 28 apuntes:

  1. SVG: Preliminares
  2. SVG: Mapa de España
  3. SVG: Estrellas
  4. SVG: Mapas con coordenadas relativas
  5. Rotando imágenes con svg
  6. Sencillo reloj analógico svg
  7. Mapas interactivos svg
  8. Reloj analógico configurable svg
  9. Generando estrellas svg
  10. SVG: crear sudokus
  11. Uso de estrellas svg: Alertas
  12. SVG: más que mapas
  13. SVG: creación dinámica
  14. SVG interactivo: sudokus
  15. SVG animado: algunos ejemplos sencillos
  16. Polígonos: svg vs. canvas
  17. Gradientes... y svg
  18. SVG: Recorridos circulares
  19. SVG vs. Ajax
  20. Etiquetando mapa SVG
  21. Fondos con SVG
  22. Postales en SVG
  23. Clip-Art: de wmf a svg
  24. SVG: Dibujando mapas
  25. SVG: Zoom en mapa de imagen
  26. Mapa de España SVG II: Vicisitudes
  27. Mapa de España SVG II: Herramientas
  28. Mapa de España SVG II: Reflexiones


Titulo: SVG: Preliminares


emoticón de Caricatos Publicado el día 25 de junio de 2012
id=89

Figuras geométricas Hemos trabajado con la imagen que tenemos junto a este párrafo a modo de "caso de estudio" en algunas ocasiones, como en los apuntes javascript: rollover en mapas y Áreas poligonales para efecto rollover. Ahora nos servirá también para iniciarnos en el formato SVG, motivados por el comentario que nos ha dejado en el primero de los apuntes citados el webmaster de uno de nuestros sitios amigos; Centell: Diseño Gráfico.

En principio vamos a poner el código para obtener la misma imagen, pero editable desde un simple editor de textos como el block de notas de cualquier sistema:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="100px" >
	<rect fill="#0000ff" x="8" y="8" width="21" height="22" />
	<polygon fill="#ff0000" points="82,7,85,7,86,6,86,7,88,9,88,10,90,12,90,13,91,14,91,15,93,17,93,18,95,20,95,21,97,23,97,24,93,28,93,29,88,34,88,35,84,39,83,39,82,38,80,38,79,37,77,37,76,36,75,36,74,35,72,35,71,34,70,34,69,33,67,33,66,32,65,32,65,25,66,24,66,12,67,11,70,11,71,10,74,10,75,9,77,9,78,8,81,8" />
	<polygon fill="#ffff00" points="143,59,144,59,145,60,146,60,147,61,148,61,149,60,151,60,152,59,153,59,154,58,155,58,166,47,166,46,168,44,168,43,169,42,169,40,171,38,171,35,172,34,172,33,173,32,173,31,174,30,174,26,175,25,175,24,177,22,177,19,178,18,178,17,179,16,179,15,183,11,183,10,184,10,185,9,191,9,194,12,194,18,193,19,193,20,191,22,191,23,189,25,189,28,188,29,188,30,186,32,186,34,185,35,185,37,184,38,184,40,183,41,183,43,182,44,182,45,181,46,181,47,180,48,180,49,179,50,179,51,178,52,178,53,177,54,177,55,174,58,174,59,166,67,165,67,164,68,162,68,161,69,160,69,159,70,158,70,155,73,143,73,141,71,139,71,138,70,136,70,135,69,134,69,133,68,132,68,130,66,130,64,129,63,129,62,128,61,128,60,127,59,127,41,128,40,128,39,129,38,129,37,131,35,131,34,133,32,134,32,135,31,137,31,138,30,140,30,141,29,150,29,151,30,152,30,152,31,153,32,153,38,151,40,146,40,145,41,144,41,140,45,140,46,139,47,139,53,140,54,140,56" />
	<polygon fill="#00ff00" points="206,49,207,50,209,50,213,54,213,56,214,57,214,62,213,63,213,65,209,69,207,69,206,70,201,70,200,69,198,69,194,65,194,63,193,62,193,57,194,56,194,54,198,50,200,50,201,49" />
</svg>

Viendo la imagen que acompaña este párrafo, parece que hemos copiado la misma imágen del principio, pero la primera es una imagen del tipo "png", y la segunda no es otra cosa que la inserción en este apunte del código que vemos en el recuadro anterior.

Para obtener las coordenadas hemos usado la misma herramienta que usamos en los dos apuntes mencionados en el primer párrafo con unas leves modificaciones, que hemos incluído también en este dominio, y puede accederse desde la sección "Otras páginas del dominio": Capturar áreas.

Figuras

Por ahora nos hemos interesado en las figuras que pueden usarse también en áreas de imágenes como en los apuntes que hemos mencionado, y como puede apreciarse en el código, existen rectángulos y polígonos; pero también líneas, círculos y elipses. Esta es la referencia: Basic Shapes.






Titulo: SVG: Mapa de España


emoticón de Caricatos Publicado el día 01 de julio de 2012
id=90

A partir de las coordenadas que ya hemos obtenido de las provincias de España, trataremos de generar el mapa de España en formato svg.

Para obtener el mapa que mostramos a continuación...

Hemos copiado del apunte :"Mapa de España", el array de las áreas de provincias que puede verse en su sección script: script.mapa_hispano, y luego hemos creado los polígonos con un sencillo bucle:

for (i in areas) {
	area = "<a xlink:href='http://es.wikipedia.org/wiki/" + i + "' xlink:title='" + i + "'>";
	area += "\\n\\t<polygon fill='#00FF00' points='" + areas[i].coors + "'>";
	area += "\\n\\t\\t<set attributeName='fill' from='#00FF00' to='#FF0000' begin='mouseover' end='mouseout'/>";
	area += "\\n\\t\\t<set attributeName='stroke' from='#00FF00' to='#000000' begin='mouseover' end='mouseout'/>";
	area += "\\n\\t</polygon>\\n</a>\\n";
	tag("textarea_mapa").value += area;
}

Nótese el efecto rollover cuyo funcionamiento lo hemos visto en este artículo: "Add interactivity to your SVG", aunque no funcione en todos los navegadores.

Formentera

Esta pequeña isla balear nos sirve de referencia para mostrar su código, simplemente por tratarse de la figura con menos coordenadas por ser de menor dimensión.

<a xlink:href='http://es.wikipedia.org/wiki/Formentera' xlink:title='Formentera'>
	<polygon fill='#00FF00' points='532,315,531,316,530,315,530,312,531,312,532,313'>
		<set attributeName='fill' from='#00FF00' to='#FF0000' begin='mouseover' end='mouseout'/>
		<set attributeName='stroke' from='#00FF00' to='#000000' begin='mouseover' end='mouseout'/>
	</polygon>
</a>

A diferencia del apunte anterior: SVG: Preliminares, dentro de la etiqueta polygon, que representa la figura poligonal de la isla, destacamos la forma de obtener el efecto rollover. También es de destacar la forma de enlazar de cada área.






Titulo: SVG: Estrellas


emoticón de Caricatos Publicado el día 15 de agosto de 2012
id=93

Para crear figuras geométricas sencillas podemos hacerlo "a ojo", y obtener los resultados que mostramos a continuación, pero si nos animamos con sencillos cálculos, seguro que mejoraremos los resultados.

Hemos implementado el efecto rollover en las figuras, y aún quedando bien (bonito), no es lo deseado en los casos de las estrellas de cinco y ocho puntas. Intentaremos pues obtener estrellas de otra manera.

Un poco de geometría

No profundizaremos mucho en cuestiones o ecuaciones matemáticas, pero para estos casos podemos usar la ecuación de la circunferencia. Y como precedente veremos el código de una vieja página donde implementamos con una librería gráfica propia, un reloj analógico; en concreto mostraremos como hemos pintado las marcas de las horas:

// creación de las 12 marcas...
radian = Math.PI / 180;
for (var i = 11; i < 24; i ++)	{
	alfa = 30 * i;
	colorMarca = (alfa % 90 == 0) ? "black" : "gray";
	anchoMarca =  (alfa % 90 == 0) ? 3 : 2;
	alfaX = parseInt(Math.sin(alfa * radian) * 45) + 50;
	alfaY = parseInt(Math.cos(alfa * radian) * 45) + 50;
	marca = new Esfera("", alfaX, alfaY, anchoMarca, colorMarca, "visible");
	laCaja.innerHTML += marca.generar();
}

Por lo pronto usaremos ese código para ver las coordenadas que recoge y fabricar un dodecágono:

A partir de las coordenadas obtenidas (28,88,49,95,72,88,88,72,95,51,88,28,72,12,51,5,28,12,12,28,5,49,12,72,28,88), hemos creado la figura que mostramos a la derecha; y echándole algo de imaginación, alternamos el radio en unas puntas por su mitad y obtenemos la estrella de seis puntas que se distingue a la izquierda de este párrafo. A diferencia del dodecágono, nuestra "estrella" de seis puntas está generada con valores reales, así que vamos a omitir mostrar esos puntos, aunque puede verse desde el código fuente del apunte; de todos modos mostraremos el código que genera los puntos.

Los retoques que hemos realizado al código lo reflejamos a continuación:

function seis_puntas() {
	coordenadas = [];
	radian = Math.PI / 180;
	for (var i = 11; i < 23; i ++)	{
		alfa = 30 * i;
		radio = (i % 2 == 1) ? 22.5:45;
		coordenadas.push((Math.sin(alfa * radian) * radio) + 50);
		coordenadas.push((Math.cos(alfa * radian) * radio) + 50);
	}
	return coordenadas;
}

Del código podemos deducir que para un determinado número de puntas necesitamos el doble de coordenadas alternando el radio de cada cálculo.

Cinco puntas

A partir de la última reflexión modificamos nuestro código y hemos conseguido la estrella que vemos a nuestra izquierda. Hemos cambiado algunos valores para ajustar el número de puntas y sus coordenadas.

También es posible crear estrellas como el asterisco que precede este párrafo agrupando lineas. Para insertar esta figura hemos añadido otros elementos básicos de las imágenes svg como la agrupación de elementos "g" y el atributo "viewbox".

A continuación mostramos variantes de la estrella de cinco puntas escaladas:

Nótese que al agrandar las imágenes, éstas no se pixelan como en los mapas de bits. En la última de las figuras hemos utilizado el atributo preserveAspectRatio para conseguir el efecto de estiramiento.






Titulo: SVG: Mapas con coordenadas relativas


emoticón de Caricatos Publicado el día 02 de septiembre de 2012
id=94

En un tema de los foros del web: Mapa de imagenes con coordenadas relativas, la única respuesta hasta ahora ha sido la mía recomendando el uso de imágenes svg. Para justificar mi recomendación me propuse hacer un ejemplo, pero para no saturar de "Mapas de España" este diario he decidido usar otro viejo ejemplo: "Rollover en mapa: Creando recortes circulares". A la derecha de este párrafo podemos ver una versión reducida del mismo mapa del citado apunte.

A continuación insertamos el código del mapa en miniatura que tiene la mitad del tamaño del original (300x197), en donde mostramos el mismo área original con su enlace; y hemos añadido otra área con otro enlace de otro de los caricaturistas que aparecen en la foto de familia:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="300px" height="197px" viewbox="0 0 600 394">
	<image x="0" y="0" width="600px" height="394px" xlink:href="diario.imagen.php?id=48&max=600" />
	<a xlink:href='http://www.caricaturasmarbella.com' xlink:title='caricaturas San Jorge'>
		<circle cx="231" cy="112" r="27" fill="transparent" stroke="gray" stroke-width="2" >
			<set attributeName='stroke' from='gray' to='red' begin='mouseover' end='mouseout'/>
		</circle>
	</a>
	<a xlink:href='http://www.sucaricatura.com' xlink:title='sucaricatura.com, su caricatura en Internet'>
		<circle cx="432" cy="225" r="27" fill="transparent" stroke="gray" stroke-width="2">
			<set attributeName='stroke' from='gray' to='red' begin='mouseover' end='mouseout'/>
		</circle>
	</a> 
</svg>

Lo único que estamos usando por primera vez en nuestros apuntes relacionados con las imágenes "svg" es la etiqueta "image".

SVG: etiqueta image

Esta etiqueta sirve para insertar una imagen en la posición especificada en los atributos x,y con las dimensiones width (ancho) y height (alto). Puede notarse la similitud con la etiqueta "img" en documentos "html"; en este caso no deben definirse etiquetas "map" ni sus "areas".

Atributo fill: none vs. transparent

La última curiosidad sobre los enlaces en las figuras (en este caso los círculos), es que si definimos la figura sin relleno (fill="none"), la zona caliente de esa figura tan solo es la línea del círculo, pero usando el valor "transparent", la zona caliente también es el interior de la figura.


Para poder comparar los resultados, a continuación mostramos el mismo "mapa" sin reducir.

Y si revisamos los códigos, la única deferencia entre ambos mapas se encuentra en los atributos width y height de las etiquetas svg.






Titulo: Rotando imágenes con svg


emoticón de Caricatos Publicado el día 13 de noviembre de 2012
id=102

A veces queremos un efecto sencillo en alguna de las imágenes que ponemos en nuestras páginas y tenemos que depender de javascript, y en ocasiones con códigos realmente complejos. He de admitir que no todos los navegadores reproducen las imágenes svg de la misma manera, así que iremos indicando cómo incrustarlas para notar las diferencias.

La primera de las imágenes se ha incrustado directamente en la página. El código se muestra a continuación:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="40px" height="40px" viewbox="0 0 40 40"
style="float: left; margin: 0 1em; border: 1px solid black; margin: 0 1em .5em 0">
	<image x="0" y="0" width="40px" height="40px" xlink:href="http://www.pepemolina.com/logo.png">
		<animateTransform attributeType="xml"
			attributeName="transform"
			type="rotate"
			from="0 20 20"
			to="360 20 20"
			dur="6s"
			repeatCount="indefinite"/>
	</image>
</svg>

"> Para esta segunda presentación se ha creado un fichero externo, y se ha utilizado una etiqueta object; donde se ha asociado el fichero externo a su atributo "data", y además hemos especificado el mime-type "image/svg+xml" en el atributo "type".

La imagen que está en este párrafo se ha insertado con la etiqueta "iframe"; al igual que en el anterior caso, usamos el mismo atributo "type" con el mismo valor mime-type: "image/svg+xml", y la dirección URL la asociamos al atributo "src".

logo animado Y esta última imagen se ha mostrado con la etiqueta "img", donde también utilizamos el atributo type, y como toda imagen tiene su atributo alt y como nos gusta hacer en este diario, también ponemos la etiqueta longdesc con la dirección de su descripción.






Titulo: Sencillo reloj analógico svg


emoticón de Caricatos Publicado el día 14 de noviembre de 2012
id=103

Si nos planteamos hacer el dibujo de un reloj analógico, sencillamente tenemos que hacer un círculo con doce (12) marcas indicando las horas y tres (3) líneas para las agujas. Pues con el formato svg es tan sencillo como eso.

Con respecto a la animación de las agujas, la idea es que el segundero da una vuelta completa (360º) en un minuto; el minutero lo hace en una hora y la aguja horaria la da en 12 horas. Pues con el formato svg, también es tan sencillo como eso.

Lo único que hemos hecho con un lenguaje distinto al svg+xml es la ubicación inicial de las agujas:

header("Content-type: image/svg+xml");
$ya = getdate();
$segundero = $ya["seconds"];
$minutero = $ya["minutes"];
$hora = $ya["hours"] % 12;
$rs = $segundero * 6;
$rm = ($minutero + ($segundero / 60)) * 6;
$rh = ($hora + ($minutero / 60) + $segundero / 3600) * 30;
echo <<< svg
<?xml version="1.0" 	standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100" height="100" preserveAspectRatio="no">
	<g id="esfera">
		<circle
			cx="50" cy="50" r="47" fill="white" stroke="red" stroke-width="3"/>
		<line x1="50" y1="10" x2="50" y2="20" stroke="black" stroke-width="4" />
		<line x1="50" y1="10" x2="50" y2="15" stroke="black" stroke-width="1"
			transform="rotate(30 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="15" stroke="black" stroke-width="1"
			transform="rotate(60 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="20" stroke="black" stroke-width="4"
			transform="rotate(90 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="15" stroke="black" stroke-width="1"
			transform="rotate(120 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="15" stroke="black" stroke-width="1"
			transform="rotate(150 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="20" stroke="black" stroke-width="4"
			transform="rotate(180 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="15" stroke="black" stroke-width="1"
			transform="rotate(210 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="15" stroke="black" stroke-width="1"
			transform="rotate(240 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="20" stroke="black" stroke-width="4"
			transform="rotate(270 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="15" stroke="black" stroke-width="1"
			transform="rotate(300 50 50)"/>
		<line x1="50" y1="10" x2="50" y2="15" stroke="black" stroke-width="1"
			transform="rotate(330 50 50)"/>
	</g>
	<g id="hora">
		<line x1="50" y1="25" x2="50" y2="55" stroke="black" stroke-width="3"
			transform="rotate($rh, 50 50)"/>
		<animateTransform attributeType="xml" attributeName="transform"
			type="rotate" from="0 50 50" to="360 50 50"
			dur="12h" repeatCount="indefinite"/>
	</g>
	<g id="minutero">
		<line x1="50" y1="15" x2="50" y2="55" stroke="blue" stroke-width="2"
			transform="rotate($rm, 50 50)"/>
		<animateTransform attributeType="xml" attributeName="transform"
			type="rotate" from="0 50 50" to="360 50 50"
			dur="1h" repeatCount="indefinite"/>
	</g>
	<g id="segundero">
		<line x1="50" y1="10" x2="50" y2="60" stroke="red" stroke-width="1"
			transform="rotate($rs, 50 50)"/>
		<animateTransform attributeType="xml" attributeName="transform"
			type="rotate" from="0 50 50" to="360 50 50"
			dur="1min" repeatCount="indefinite"/>
	</g>
</svg>
svg;

reloj analógico estirado En este caso la hora que mostramos es la del servidor donde está alojada la página, pero para otro apunte lo ajustaremos con la hora del navegador.

Al ser svg un lenguaje "escalable", podemos crear el efecto de relojes ovalados simplemente aplicando estilos distintos en altura y anchura (width-height) de la imagen.






Titulo: Mapas interactivos svg


emoticón de Caricatos Publicado el día 04 de diciembre de 2012
id=106

Volvemos a la temática sobre imágenes svg para mostrar otro mapa pero con nuevas características, como la redimensión (la "S" en Svg corresponde a "eScalable"). Otra razón para retomar la temática proviene de una consulta en los "Foros del web" sobre Mapa de España dinámico, donde se pide dinamismo, y aunque en anteriores temas sobre este formato de imágenes existía algún dinamismo, funcionaba de forma desigual en los distintos navegadores... y no debemos olvidar el deficiente soporte en las viejas versiones de éstos. También es desigual el comportamiento según la forma que decidamos incrustar nuestro mapa. A nuestra derecha se ha usado una etiqueta "img", y en el siguiente párrafo la etiqueta es "object".

A la izquierda de este párrafo se evidencia la escalabilidad del formato. También vemos que podemos variar los colores, resaltando si fuera necesario zonas concretas, y sin usar el lenguaje de programación habitual: javascript. El código fuente de esta imagen mayor es el mismo de la menor del primer párrafo, pero se ven distintas debido a los parámetros de cada una. También son distintos los parámetros de ésta más pequeña a la derecha, donde se resaltan todas las provincias de Andalucía. El código de nuestro comodín necesita de varios parámetros para indicar los colores que se muestran, ya sea de los elementos seleccionados, como del efecto "rollover", o la provincia o comunidad autónoma que deba resaltarse.

Para facilitar la creación de mapas para otros objetivos, hemos generado unos ficheros que esperamos sean de utilidad: la imagen del mapa de fondo, y los listados de comunidades con sus provincias, y de las provincias con sus coordenadas






Titulo: Reloj analógico configurable svg


emoticón de Caricatos Publicado el día 15 de diciembre de 2012
id=107

Después de comprobar con qué facilidad se puede dibujar un sencillo reloj analógico decidimos poderlo configurar; y a la vez compartirlo. El código se puede obtener desde el fichero reloj.txt y es el mismo que del reloj que acompaña este párrafo.

Tal vez algún curioso a comparado las direcciones de ambas referencias y habrá notado que una termina en ".txt" y la otra en ".php", pero debemos comprender que los ficheros del tipo "php" no se ven tal cual desde un navegador, sino que se procesa. De hecho, el fichero "reloj.php" tiene solamente este contenido:

<?php
	include("reloj.txt");
?>

Ya que estamos tratando la configuración de nuestro reloj, nos pondremos "manos a la obra"; pero aclarando que se trata de cosas básicas como los colores de sus componentes o la hora de inicio de su funcionamiento.

Configuración

Como siempre en este diario, procuraremos usar un sistema "accesible", aunque desde luego, el formato svg no es soportado por igual por los distintos navegadores. Los cambios podrán verse en el pequeño reloj del párrafo anterior, o si se tiene javascript habilitado, podría mostrarse en una ventana nueva del navegador (marcando el primer control del formulario asociado).

Tampoco será accesible la opción "hora del navegador", aunque siempre se podrá poner la hora de inicio de forma manual:

Destino :
Colores
Esfera :
:
:
Agujas :
:
:
Horario


: : :

Si se prueba la opción donde se abre una nueva ventana, el reloj se adaptará a las dimensiones de ésta, debido a que la declaración de las dimensiones en la etiqueta svg es de 100%.






Titulo: Generando estrellas svg


emoticón de Caricatos Publicado el día 25 de diciembre de 2012
id=108

Después de crear estrellas de cinco puntas, nos faltaría hacerlas con distintas características, variando el número de puntas u otras variantes.

Aunque nuestra imagen también es de cinco puntas basta con añadir el parámetro "puntas" con el valor que nos interese para que obtengamos otra estrella, por ejemplo de nueve (9) puntas.

Si han pulsado sobre el enlace del final del anterior párrafo, habrán notado que no solo ha cambiado el número de puntas de la estrella, sino que las puntas son de diferentes tamaños.

Las opciones

Ya hemos visto que se pueden obtener estrellas con distintas formas, y claro que podemos modificar sus colores, y aunque se generan con 100 pixeles de radio, son estrellas "escalables".

Para mostrar las distintas posibilidades crearemos un formulario cuyos resultados se notarán en la estrella superior:

Forma

Colores

Podemos obtener efectos muy curiosos con un número elevado de puntas, aunque tal vez no sea de utilidad.






Titulo: SVG: crear sudokus


emoticón de Caricatos Publicado el día 01 de enero de 2013
id=109

sudoku Simplemente haremos un recuadro con nueve (9) filas y nueve (9) columnas, resaltando recuadros agrupados en tres (3) filas y tres (3) columnas. Los parámetros adicionales son la anchura de cada casilla y los valores iniciales donde cualquier valor distinto del rango de números aceptados [1..9] corresponderá a una casilla vacía. En la imagen asociada a este párrafo tenemos un ejemplo; y si miramos su código podemos afirmar que sería muy fácil implementar otras opciones como los colores del mismo.

Para conseguir entonces distintos sudokus, vamos a facilitar un formulario con la inicialización del mismo como parámetro:

:

Como podemos ver, con este apunte solo generamos el recuadro con sus casillas y los valores que nosotros pongamos. Investigaremos en su resolución.






Titulo: Uso de estrellas svg: Alertas


emoticón de Caricatos Publicado el día 08 de enero de 2013
id=110

estrella Existen muchos posibles usos para dibujos con forma de estrella; tal vez uno de los más comunes son los sistema de evaluación muy usados en blogs o páginas parecidas (como este diario), pero nosotros lo aplicaremos en una alerta para indicar que tenemos nuevas fotos en la página de un amigo caricaturista: Caricaturas "San Jorge".

Usaremos la misma estrella del apunte "Generando estrellas svg", pero con un número mayor de puntas, y con el borde rojo (tal como la estrella adjunta). Tal como vemos en la imagen, estará estirada y le añadiremos un texto en dos (2) líneas. En nuestro caso concreto "Nuevas Fotos".

estrella Para darle algo de dinamismo le hemos añadido un efecto de rotación a las puntas de la estrella con una duración de cinco (5) segundos por cada giro.

Para los visitantes que no dispongan de un navegador que soporte este tipo de imágenes (podríamos considerarlos como navegadores obsoletos o anticuados), también se generan estrellas estáticas añadiendo el parámetro "img" con un valor distinto de "svg". La imagen del párrafo anterior de este apunte es un ejemplo; en nuestro caso hemos programado el evento de error de carga de la imagen (onerror).

<img src="ficheros/estrella.php?texto=Nuevas|Fotos"
	id="estrella_ejemplo"
	alt="estrella"
	onerror="this.src += '&img=gif'"/>

El código completo se puede obtener desde su fuente original: estrella.txt; tan solo se debe cambiar la extensión del archivo o insertar el código con la instrucción include de php.






Titulo: SVG: más que mapas


emoticón de Caricatos Publicado el día 23 de enero de 2013
id=112

Hemos usado el formato svg para crear mapas interactivos muy sencillos; ahora iremos ampliando las posibilidades de este formato.

En el apunte "SVG: Mapa de España", mostramos un sencillo efecto rollover (imagen de sustitución), también utilizando el lenguaje XLink hemos creado enlaces y añadido títulos (igual que los mapas de imágenes); pero vamos a intentar añadir más vistosidad.

El efecto en la provincia de Málaga, no solo cambia el color de la provincia, también muestra un icono previamente ocultado con estilos. De la misma manera podríamos tener escondidos otros elementos salpicados por el resto del mapa.

Hemos reservado para la capital (con borde negro) una novedad en esta serie de apuntes, la inserción de elementos svg dentro de una imagen svg. Son cinco (5) estrellas que se ubicarán en la esquina superior derecha del dibujo.

Insertando estrellas

Nos ayudaremos del código que habíamos usado en el apunte Generando estrellas svg. El código de la estrella de cinco (5) puntas lo hemos copiado e insertado dentro de nuestro mapa con distintas coordenadas y otro tamaño. Para poder ubicar la misma estrella, con los mismos puntos y dimensiones, pero en distintos sitios y un tamaño menor, hemos usado otros tantos elementos svg, tan solo variando la coordenada x.

Por último, crearemos dinámicamente una provincia -Gerona-, y la enlazaremos al apunte sobre el Congreso que aconteció el año 2011. Detallaremos esta inserción dinámica en un futuro apunte.






Titulo: SVG: creación dinámica


emoticón de Caricatos Publicado el día 01 de febrero de 2013
id=114

Volviendo a las imágenes SVG, vamos a crear nuestro mapa de forma dinámica. Advertimos que este apunte (al menos lo que intentamos mostrar) depende de que javascript esté habilitado en nuestro navegador (aunque sea lo habitual, está bien aclararlo; es más, aconsejamos hacer páginas navegables sin la dependencia de javascript).

Ya habíamos insertado la provincia de Gerona dinámicamente en el apunte anterior: SVG: más que mapas, pero ahora vamos a insertar todas las provincias; mostrando inicialmente el norte del continente africano, que servirá de referencia.

Para inserta las provincias españolas, pulse el siguiente botón: ... y veremos aparecer pausadamente y de forma caótica todas las provincias españolas.

Vemos que se ha formado el mapa íntegramente, aunque no tenemos enlaces y el efecto de imagen de sustitución se consigue con estilos, que aunque sea correcto, podemos conseguir el efecto con código svg+xml. Así que modificaremos nuestro código.

Insertando polígonos

En principio hemos usado las coordenadas que teníamos guardadas en el fichero provincias.txt, que aunque tenga el formato de los ficheros php solo puede ser visto como código fuente, o también puede ser insertado con una instrucción "include" del lenguaje; y es eso lo que hemos hecho en el fichero "provincias.php", que genera un fichero svg con la imagen que vemos a continuación: mapita español (pulse sobre la miniatura para ampliarla).

Al tratarse de un fichero svg, a la vez es un fichero xml, que nos vale para obtener datos con la tecnología Ajax. El código que genera la imagen lo vemos a continuación:

<?php
	$fill = (isset($_GET["fill"])) ? $_GET["fill"]:"green";
	$ancho = (isset($_GET["ancho"])) ? $_GET["ancho"] : 625;
	$alto = 571 * $ancho / 625;
	include("provincias.txt");
	header("Content-type: image/svg+xml");
	$svg =<<< svg
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
	"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
	xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
	width="$ancho" height="$alto" preserveAspectRatio="none" viewBox="0 0 625 571">
svg;

	foreach($provincias as $p => $item)	{
	$pr = htmlspecialchars($p);
	$svg .=<<< p

		<polygon id="$p" fill="$fill" stroke="black" points="$item" />

p;
}
echo <<< mapa
$svg
</svg>

mapa;
?>

Teniendo las provincias y sus coordenadas en nuestro fichero xml+svg, tan solo nos queda insertarlas con javascript.

A diferencia de elementos normales html, los elementos xml se crean con "document.createElementNS", y los atributos se asignan con setAttributeNS. La coletilla "NS" viene de namespace o Espacio de nombres, y será el primero de los parámetros que tendrá la instrucción createElementNS.

Antes de continuar, explicaremos cómo hemos llegado a esto. El código que habíamos utilizado es el siguiente:

provincias = [];

function suma_provincia()	{
	if (provincias.length > 0)	{
		p = provincias.pop();
		provincia = p.provincia;
		puntos = p.puntos;
		nueva = document.createElementNS(svgns, "polygon");
		nueva.setAttributeNS(null, "id", provincia);
		nueva.setAttributeNS(null, "fill", "lime");
		nueva.setAttributeNS(null, "points", puntos);
		nueva.setAttributeNS(null, "stroke", "black");

		tag("crear_mapa_din").appendChild(nueva);
		setTimeout(suma_provincia, Math.floor(Math.random() * 200));
	}
	else	{

		tag("espera").style.display = "none";
		tag("restar_provincias").disabled = false;
	}
}

function obtener_provincias(continuar) {
	ajax = objetoAjax();
	ajax.open("get", "ficheros/provincias.php", true);
	ajax.onreadystatechange = function()	{
		if (ajax.readyState == 4) {
			resultado = ajax.responseXML;
			polys = resultado.getElementsByTagName("polygon");
			for (i = 0, total = polys.length; i < total; i++)
				provincias.push({"provincia": polys[i].getAttribute("id"), "puntos": polys[i].getAttribute("points")});
			window[continuar]();
		}
	}
	ajax.send(null);
}

function crear_mapa()	{
	tag("espera").style.display = "inline";
	tag("sumar_provincias").disabled = true;
	tag("sumar_provincias_link").disabled = true;
	obtener_provincias("suma_provincia");
}

Podemos ver que el espacio de nombres es usado en la creación del elemento "polygon", pero no debe especificarse en los atributos del elemento. Pero con los enlaces debemos usar otra táctica.

Ahora los enlaces

Hasta ahora hemos usado "null" para espacio de nombres de los atributos de los polígonos, pero si bien al insertar una etiqueta "a", seguimos creándola con el espacio de nombres svg; tanto el atributo href como el title es parte del lenguaje XLink, así que al definirlos, debemos asociarlos a esa otra librería.

svgns = "http://www.w3.org/2000/svg";
xlinkns = "http://www.w3.org/1999/xlink";

function suma_provincia_link()	{
	if (provincias.length > 0)	{
		p = provincias.caos();
		provincia = p.provincia;
		puntos = p.puntos;
		nueva = document.createElementNS(svgns, "polygon");
		nueva.setAttributeNS(null, "id", provincia);
		nueva.setAttributeNS(null, "fill", "lime");
		nueva.setAttributeNS(null, "points", puntos);
		nueva.setAttributeNS(null, "stroke", "black");

		enlace = document.createElementNS(svgns, "a");
		enlace.setAttributeNS(xlinkns, "href", "diario.jocker.php?extra=info_hispano&provincia=" + escape(provincia));
		enlace.setAttributeNS(xlinkns, "title", provincia);

		setenlace = document.createElementNS(svgns, "set");
		setenlace.setAttributeNS(null, "attributeName", "fill");
		setenlace.setAttributeNS(null, "begin", "mouseover");
		setenlace.setAttributeNS(null, "end", "mouseout");
		setenlace.setAttributeNS(null, "from", "lime");
		setenlace.setAttributeNS(null, "to", "blue");

		nueva.appendChild(setenlace);

		enlace.appendChild(nueva);

		tag("crear_mapa_din").appendChild(enlace);
		setTimeout(suma_provincia_link, Math.floor(Math.random() * 300));
	}
	else	{

		tag("espera_link").style.display = "none";
		tag("restar_provincias").disabled = false;
	}
}

function crear_mapa_link()	{
	tag("espera_link").style.display = "inline";
	tag("sumar_provincias").disabled = true;
	tag("sumar_provincias_link").disabled = true;
	obtener_provincias(suma_provincia_link);
}

Para probar el código expuesto, en primer lugar limpiaremos el mapa que acabamos de crear pulsando en el botón .

Y ahora podemos crear la nueva versión pulsando el botón que vemos a continuación:


En próximos apuntes veremos más cosas sobre estas imágenes.






Titulo: SVG interactivo: sudokus


emoticón de Caricatos Publicado el día 09 de febrero de 2013
id=115

Veremos como podemos resolver un sudoku introduciendo los números por teclado. No intentaremos resolverlo con código, ya que nuestra intención es otra: la interacción.

Podemos escoger entre los sudokus en miniatura, o incluír cada número pulsando sobre cada casilla. En este caso no hacemos ninguna verificación.

Puede seleccionar una miniatura
sudoku alternativo sudoku alternativo sudoku alternativo sudoku alternativo

Algunos de los ejemplos los hemos visto ya en anteriores apuntes.

Eventos

Para responder a un evento hay que asociarlo de la misma forma que con cualquier elemento html. Hemos asignado un identificador "id" a cada casilla de forma que la primera tiene id="casilla_0_0" y la última : id="casilla_8_8"; y dentro de cada casilla tenemos un elemento "text" (texto) con similar identificador, reemplazando "casilla_" por "txt_":

function tag(id)	{return document.getElementById(id);}
function poner_evento(elemento, evento, f)	{
	if (document.addEventListener)
		elemento.addEventListener(evento, f, true);
	else
		if (document.attachEvent)
			elemento.attachEvent("on" + evento, f);
		else
			elemento["on" + evento] = f;
}
// De la inicialización de la página, nos interesan estas pocas líneas.
for (i = 0; i < 9; i++)	for (j = 0; j < 9; j++)	{
	tag("txt_" + i + "_" + j).appendChild(document.createTextNode(""));
	poner_evento(tag("casilla_" + i + "_" + j), "click", entrada);
}

Podemos resumir en estas pocas líneas que a cada casilla le asociamos al evento "click" (onclick) la función "entrada()" que mostramos a continuación:

function entrada() {
	id = this.id;
	coleta = id.substr(8);
	xy = coleta.split("_");
	n_actual = tag("txt_" + coleta).firstChild.data;
	n = prompt("nuevo valor para la casilla [" + xy + "] : ", n_actual)[0];
	if ("123456789".indexOf(n) != -1)	{
		sudoku = document.forms.form_sudoku.inicio.value;
		valores = sudoku.split("");
		posi = parseInt(xy[0]) * 9 + parseInt(xy[1]);
		valores[posi] = n;
		document.forms.form_sudoku.inicio.value = valores.join("");
		tag("txt_" + coleta).replaceChild(document.createTextNode(n), tag("txt_" + coleta).firstChild);
	}
}

Sobre este último código, solo reseñaremos que tanto la lectura como escritura de nodos de texto se hace de la misma manera que hemos hecho hasta el momento.






Titulo: SVG animado: algunos ejemplos sencillos


emoticón de Caricatos Publicado el día 15 de febrero de 2013
id=116

Hemos hecho un par de animaciones rotando nuestro logo y las manecillas de un reloj analógico. Ahora nos toca volver a animar nuestro logo pero con movimientos lineales. Básicamente moveremos la imagen en tres direcciones:

Horizontal Vertical Diagonal

Para obtener las tres (3) animaciones con un solo fichero, debemos pasarle como parámetro el tipo (t) y los valores serán:

El código lo mostramos en este enlace al extra: logo_animado_path_svg (donde se puede comentar y valorar), y junto a estas líneas:

// descripción para la sindicación:
/*
	Este comodín sirve para animar el logo con tres (3) movimientos lineales.
*/
$tipo = (isset($_GET["t"])) ? $_GET["t"]:"v";
if (!in_array($tipo, array("v", "h", "d")))	$tipo = "v";

if ($tipo == "v") $poner =<<< vertical
		<use x="0" y="-40" transform="rotate(180 20 -20)" xlink:href="#logo_svg" />
		<animateMotion path="M 0 0 V 40 Z" dur="2s" repeatCount="indefinite" />
vertical;

elseif ($tipo == "h") $poner =<<< horizontal
		<use x="-40" y="0" xlink:href="#logo_svg" />
		<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0" to="40" dur="2s" repeatCount="indefinite" />
horizontal;

else $poner =<<< diagonal
		<use x="0" y="-40" xlink:href="#logo_svg" />
		<use x="-40" y="0" xlink:href="#logo_svg" />
		<use x="-40" y="-40" xlink:href="#logo_svg" />
		<animateMotion path="M 0 0 L 40 40 M 0 0 Z" dur="2s" repeatCount="indefinite"/>
diagonal;

header("Content-type: image/svg+xml");
echo <<< svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="40" height="40" preserveAspectRatio="yes">
	<defs>
		<image id="logo_svg" width="40" height="40" xlink:href="http://www.pepemolina.com/logo.png" />
	</defs>
	<g>
		<use x="0" y="0" xlink:href="#logo_svg" />
$poner
	</g>
</svg>
svg;

Vemos nuevos elementos en nuestra imagen svg que comentaremos a continuación.

Los entresijos

Entre las novedades vemos el elemento "defs" (definiciones), y dentro definimos un elemento image, con identificador (id) "logo_svg".

La imagen, tal como indica su id, es nuestro logo y tiene definidos los atributos de tamaño. Luego vemos una etiqueta "g" donde agrupamos un elemento nuevo: "use", donde se "usa" la imagen definida en la sección defs; y también vemos una variable php cuyo valor es según el tipo de animación, uno o tres elementos "use" similares pero con distintos valores de posicionamiento (x, y). También se agrupa la etiqueta de la animación (animateMotion o animateTransform).

Ya habíamos usado animateTransform en nuestras anteriores animaciones y eran del tipo "rotate" (rotación); en este caso hemos usado translate (traslado), y su uso es similar, así que no nos detendremos en explicarlo. En el caso de animateMotion encontramos atributos similares como dur (duración) y repeateCount (repeticiones), pero las coordenadas se definen con el atributo "path", cuyo contenido es el mismo del atributo "d" (data/datos) de la etiqueta de igual nombre: "path".

Recorridos del "path"

Para entender, al menos básicamente, los valores del recorrido, debemos pensar que cada recorrido es una serie de letras o comandos seguidos de coordenadas. Empezamos con el comando M (moveTo/mover a coordenada), y en ambos casos sigue con "0 0"; o sea que el inicio de nuestro recorrido es la coordenada (0, 0), pero para no confundirnos, iremos por partes. El primer recorrido:

path="M 0 0 V 40 Z"

Comprobamos que comienza desde el origen que ya comentamos, y sigue con la instrucción "V" (línea vertical) con el valor 40. Un solo valor porque no varía la coordenada x; o sea pasa de (0, 0) a (0, 40). Luego vemos la instrucción "Z" (close path) que indica que hemos terminado y cerramos el recorrido (volviendo al origen (0, 0).

El otro recorrido "path" es diagonal:

path="M 0 0 L 40 40 M 0 0 Z"

También iniciamos el recorrido en la coordenada (0, 0), pero la siguiente instrucción es "L" (LineTo/línea), seguido de las coordenadas (40, 40), o sea desde la esquina superior izquierda a la esquina inferior derecha. Y antes de cerrar el recorrido nos movemos (M) al origen, consiguiendo el efecto de un movimiento contínuo en diagonal... si omitiésemos el último comando "M", o lo hubiésemos reemplazado por un comando "L", el efecto sería similar al recorrido vertical antes descrito.






Titulo: Polígonos: svg vs. canvas


emoticón de Caricatos Publicado el día 01 de abril de 2013
id=118

polígonos Vamos a empezar con la imagen que vemos a nuestra derecha, que ya nos ha servido en el apunte: SVG: Preliminares para iniciar una serie de apuntes sobre este formato vectorial. Recordemos los pasos que hemos dado para obtener la misma imagen en formato svg.

En primer lugar hemos comprobado que la imagen tiene colores planos y bien vistosos: azul , rojo , amarillo y lima . Hay diversas formas para saber si una imagen tiene colores planos, entre ellos la misma herramienta que nos servirá para obtener sus polígonos: Capturar áreas en imágenes, que curiosamente tiene esta misma imagen de ejemplo.

Al seleccionar una imagen para capturar sus áreas, encontraremos la paleta de colores de esa imagen, y en este caso, junto a los colores que habíamos indicado, se suma el color de fondo, que a pesar de ser transparente, se muestra blanco.

Las coordenadas

Ya con nuestra imagen mostrada en nuestra aplicación tan solo tenemos que pinchar en la forma que deseemos capturar para que obtengamos el resultado esperado.

Para crear la imagen en formato svg, tal como vemos en este párrafo, podemos usar un fichero externo y enlazarlo con la típica etiqueta "img", o incrustar el código directamente en la página web donde querramos mostrarla; ese código lo podemos ver desde el código fuente de la página (aunque lo mostraremos en este apunte).

Pero las coordenadas también pueden servirnos para crear las imágenes dinámicamente. Entre las posibilidades para crear esas imágenes, existe la posibilidad de generarlas en un servidor por ejemplo con el lenguaje php y sus librerías GD. Y con javascript tenemos otras posibilidades como las imágenes svg y canvas, cuyas posibilidades comentaremos a continuación.

Códigos

Aquí distintos códigos para obtener el mismo resultado visual:

SVG incrustado: Se puede usar directamente en los navegadores modernos (con soporte para este tipo de imágenes), las etiquetas "svg". También puede ser un fichero externo con la cabecera xml, y el resto del código presentado; enlazándolo con las etiquetas "img", "embed", "iframe" u "object".

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="100px" class="flotado_izquierdo" >
	<polygon fill="#0000ff" points="29,8,29,30,8,30,8,8" />
	<polygon fill="#ff0000" points="82,7,85,7,86,6,86,7,88,9,88,10,90,12,90,13,91,14,91,15,93,17,93,18,95,20,95,21,97,23,97,24,93,28,93,29,88,34,88,35,84,39,83,39,82,38,80,38,79,37,77,37,76,36,75,36,74,35,72,35,71,34,70,34,69,33,67,33,66,32,65,32,65,25,66,24,66,12,67,11,70,11,71,10,74,10,75,9,77,9,78,8,81,8" />
	<polygon fill="#ffff00" points="143,59,144,59,145,60,146,60,147,61,148,61,149,60,151,60,152,59,153,59,154,58,155,58,166,47,166,46,168,44,168,43,169,42,169,40,171,38,171,35,172,34,172,33,173,32,173,31,174,30,174,26,175,25,175,24,177,22,177,19,178,18,178,17,179,16,179,15,183,11,183,10,184,10,185,9,191,9,194,12,194,18,193,19,193,20,191,22,191,23,189,25,189,28,188,29,188,30,186,32,186,34,185,35,185,37,184,38,184,40,183,41,183,43,182,44,182,45,181,46,181,47,180,48,180,49,179,50,179,51,178,52,178,53,177,54,177,55,174,58,174,59,166,67,165,67,164,68,162,68,161,69,160,69,159,70,158,70,155,73,143,73,141,71,139,71,138,70,136,70,135,69,134,69,133,68,132,68,130,66,130,64,129,63,129,62,128,61,128,60,127,59,127,41,128,40,128,39,129,38,129,37,131,35,131,34,133,32,134,32,135,31,137,31,138,30,140,30,141,29,150,29,151,30,152,30,152,31,153,32,153,38,151,40,146,40,145,41,144,41,140,45,140,46,139,47,139,53,140,54,140,56" />
	<polygon fill="#00ff00" points="206,49,207,50,209,50,213,54,213,56,214,57,214,62,213,63,213,65,209,69,207,69,206,70,201,70,200,69,198,69,194,65,194,63,193,62,193,57,194,56,194,54,198,50,200,50,201,49" />
</svg>

PHP + librería GD: En servidores con soporte para el lenguaje php, puede tenerse el código presentado en un fichero con extensión "php" (por ejemplo: figuras.php), enlazándolo con una etiqueta img (también valdrían las alternativas del caso anterior).

<?php
$formas = array(
	array("color" => "0000ff", "puntos" => "29,8,29,30,8,30,8,8"),
	array("color" => "ff0000", "puntos" => "82,7,85,7,86,6,86,7,88,9,88,10,90,12,90,13,91,14,91,15,93,17,93,18,95,20,95,21,97,23,97,24,93,28,93,29,88,34,88,35,84,39,83,39,82,38,80,38,79,37,77,37,76,36,75,36,74,35,72,35,71,34,70,34,69,33,67,33,66,32,65,32,65,25,66,24,66,12,67,11,70,11,71,10,74,10,75,9,77,9,78,8,81,8"),
	array("color" => "ffff00", "puntos" => "143,59,144,59,145,60,146,60,147,61,148,61,149,60,151,60,152,59,153,59,154,58,155,58,166,47,166,46,168,44,168,43,169,42,169,40,171,38,171,35,172,34,172,33,173,32,173,31,174,30,174,26,175,25,175,24,177,22,177,19,178,18,178,17,179,16,179,15,183,11,183,10,184,10,185,9,191,9,194,12,194,18,193,19,193,20,191,22,191,23,189,25,189,28,188,29,188,30,186,32,186,34,185,35,185,37,184,38,184,40,183,41,183,43,182,44,182,45,181,46,181,47,180,48,180,49,179,50,179,51,178,52,178,53,177,54,177,55,174,58,174,59,166,67,165,67,164,68,162,68,161,69,160,69,159,70,158,70,155,73,143,73,141,71,139,71,138,70,136,70,135,69,134,69,133,68,132,68,130,66,130,64,129,63,129,62,128,61,128,60,127,59,127,41,128,40,128,39,129,38,129,37,131,35,131,34,133,32,134,32,135,31,137,31,138,30,140,30,141,29,150,29,151,30,152,30,152,31,153,32,153,38,151,40,146,40,145,41,144,41,140,45,140,46,139,47,139,53,140,54,140,56"),
	array("color" => "00ff00", "puntos" => "206,49,207,50,209,50,213,54,213,56,214,57,214,62,213,63,213,65,209,69,207,69,206,70,201,70,200,69,198,69,194,65,194,63,193,62,193,57,194,56,194,54,198,50,200,50,201,49")
);

function rgbColor($fondo)	{
	$red = (int) hexdec(substr($fondo, 0, 2));
	$green = (int) hexdec(substr($fondo, 2, 2));
	$blue = (int) hexdec(substr($fondo, 4, 2));
	return array($red, $green, $blue);
}

$imagen = imagecreate(300, 100);
$transpa = imagecolorallocate($imagen, 254, 254, 254);
imagefill($imagen, 0, 0, $transpa);
imagecolortransparent($imagen, $transpa);

foreach ($formas as $f => $i)	{
	$color = rgbColor($i["color"]);
	$_rr = (int) $color[0];
	$_rg = (int) $color[1];
	$_rb = (int) $color[2];
	$_relleno = imagecolorallocate($imagen, $_rr, $_rg, $_rb);
	$puntos = explode(",", $i["puntos"]);
	$npuntos = count($puntos) / 2;
	imagefilledpolygon($imagen, $puntos, $npuntos, $_relleno);
}

header("Content-type: image/png");
imagepng($imagen);
imagedestroy($imagen);
?>

SVG dinámico: Así como mostramos con el ejemplo anterior un array con los colores y coordenadas de las distintas figuras que tenemos, podemos tener un array similar en javascript y crear el fichero svg.

formas = [
	{"color": "#0000ff", "puntos": "29,8,29,30,8,30,8,8"},
	{"color": "#ff0000", "puntos": "82,7,85,7,86,6,86,7,88,9,88,10,90,12,90,13,91,14,91,15,93,17,93,18,95,20,95,21,97,23,97,24,93,28,93,29,88,34,88,35,84,39,83,39,82,38,80,38,79,37,77,37,76,36,75,36,74,35,72,35,71,34,70,34,69,33,67,33,66,32,65,32,65,25,66,24,66,12,67,11,70,11,71,10,74,10,75,9,77,9,78,8,81,8"},
	{"color": "#ffff00", "puntos": "143,59,144,59,145,60,146,60,147,61,148,61,149,60,151,60,152,59,153,59,154,58,155,58,166,47,166,46,168,44,168,43,169,42,169,40,171,38,171,35,172,34,172,33,173,32,173,31,174,30,174,26,175,25,175,24,177,22,177,19,178,18,178,17,179,16,179,15,183,11,183,10,184,10,185,9,191,9,194,12,194,18,193,19,193,20,191,22,191,23,189,25,189,28,188,29,188,30,186,32,186,34,185,35,185,37,184,38,184,40,183,41,183,43,182,44,182,45,181,46,181,47,180,48,180,49,179,50,179,51,178,52,178,53,177,54,177,55,174,58,174,59,166,67,165,67,164,68,162,68,161,69,160,69,159,70,158,70,155,73,143,73,141,71,139,71,138,70,136,70,135,69,134,69,133,68,132,68,130,66,130,64,129,63,129,62,128,61,128,60,127,59,127,41,128,40,128,39,129,38,129,37,131,35,131,34,133,32,134,32,135,31,137,31,138,30,140,30,141,29,150,29,151,30,152,30,152,31,153,32,153,38,151,40,146,40,145,41,144,41,140,45,140,46,139,47,139,53,140,54,140,56"},
	{"color": "#00ff00", "puntos": "206,49,207,50,209,50,213,54,213,56,214,57,214,62,213,63,213,65,209,69,207,69,206,70,201,70,200,69,198,69,194,65,194,63,193,62,193,57,194,56,194,54,198,50,200,50,201,49"}
]

Y con esos datos generar la imagen por ejemplo con un simple botón como el que mostramos a continuación:

A continuación el código:

function generar_svg()	{
	var xmlns = "http://www.w3.org/2000/svg";
	tag_svg = document.createElementNS(xmlns, "svg");
	tag_svg.style.width = "300px";
	tag_svg.style.height = "100px";
	tag_svg.style.border = "1px solid black";
	for (i = 0, ti = formas.length; i < ti; i++)	{
		tag_polygon = document.createElementNS(xmlns, "polygon");
		tag_polygon.setAttributeNS(null, "fill", formas[i].color);
		tag_polygon.setAttributeNS(null, "points", formas[i].puntos);
		tag_svg.appendChild(tag_polygon);
	}
	tag("espacio_svg").appendChild(tag_svg);
	this.disabled = true; // deshabilitamos el botón...
}

canvas dinámico: El mismo array de formas que hemos definido para crear las figuras svg dinámicamente nos servirá para crear la imagen canvas también con otro botón:

El código es parecido al principio, pero al no existir polígonos en canvas hay que fabricar su recorrido:

function generar_canvas()	{
	tag_canvas = document.createElement("canvas");
	tag_canvas.width = "300";
	tag_canvas.height = "100";
	tag_canvas.style.border = "1px solid black";
	for (i = 0, ti = formas.length; i < ti; i++)	{
		forma = tag_canvas.getContext("2d");
		forma.fillStyle = formas[i].color;
		puntos = formas[i].puntos.split(",");
		y = puntos.pop();
		x = puntos.pop();
		forma.beginPath();
		forma.moveTo(x, y);
		while(puntos.length > 0) {
			y = puntos.pop();
			x = puntos.pop();
			forma.lineTo(x, y);
		}
		forma.closePath();
		forma.fill();
	}
	tag("espacio_canvas").appendChild(tag_canvas);
	this.disabled = true;
}

Con un código muy parecido al último mostrado se podrían crear recorridos "path" para imágenes svg.

Un extra

Tal vez nos pueda interesar obtener un recorrido path desde las coordenadas de un polígono. El resultado visual será igual, pero la etiqueta path puede servirnos para otras cosas que veremos más adelante:

Ahora sí que nos encontramos con un código casi calcado al anterior:

function generar_svg_path()	{
	tag_svg = document.createElementNS(xmlns, "svg");
	tag_svg.style.width = "300px";
	tag_svg.style.height = "100px";
	tag_svg.style.border = "1px solid black";
	for (i = 0, ti = formas.length; i < ti; i++)	{
		puntos = formas[i].puntos.split(",");
		y = puntos.pop();
		x = puntos.pop();
		path = ["M " + x + " " + y];
		while(puntos.length > 0) {
			y = puntos.pop();
			x = puntos.pop();
			path.push("L " + x + " " + y);
		}
		path.push("Z");
		tag_path = document.createElementNS(xmlns, "path");
		tag_path.setAttributeNS(null, "fill", formas[i].color);
		tag_path.setAttributeNS(null, "d", path.join(" "));
		tag_svg.appendChild(tag_path);
	}
	tag("espacio_svg_path").appendChild(tag_svg);
	this.disabled = true;
}

La lógica es similar, pero el recorrido en vez de generarse con una instrucción por trazo a partir de unas coordenadas iniciales, hemos guardado en un array los distintos trazos, el primero con una instrucción M (Move -> mover a coordenadas absolutas), y el resto de trazos mediante usando la instrucción L (Line -> línea hacia coordenada absoluta); terminando con una instrucción Z (cerrar recorrido absoluto).






Titulo: Gradientes... y svg


emoticón de Caricatos Publicado el día 04 de agosto de 2013
id=123

Conseguir fondos en colores degradados (o gradientes) cada vez es más fácil. Hace algunos años hemos dedicado algunas páginas y artículos al respecto que comentaremos a continuación.

Un poco de historia

En las viejas "FAQs Javascript" de los "Foros del Web" (véase "Mis recomendaciones", a la izquierda de esta página) habíamos compartido un mensaje sobre "Fondo degradado" en páginas web, donde abusando de tablas creábamos ese efecto.

Un evidente signo de progreso ha sido la implementación de una aplicación que generaba imágenes para poder ser descargadas de la web: Gradientes (php + librerías GD), donde los gradientes eran imágenes de 1 pixel de altura o anchura (según el caso que fuera) y la otra dimensión era la longitud que necesitásemos.

Los resultados se conseguían de una forma muy sencilla, simplemente separando los componentes y calcular el incremento por cada uno de ellos (incluso negativos. El siguiente es el código javascript insertado en otra de las FAQs del foro:

function decahex(n) {
	return hexa.charAt(n / 16) + hexa.charAt(n % 16);
}

function colorHexa(c) {
	return "#" + decahex(c[0]) + decahex(c[1]) + decahex(c[2]);
}

function transitar(ini, fin, pasos) {
	var dato = desglose(ini);
	var rIni = dato[0];
	var gIni = dato[1];
	var bIni = dato[2];

	var intermedios = new Array(pasos);
	intermedios[0] = dato;

	var dato = desglose(fin);

	intermedios[pasos - 1] = dato;

	var rFin = dato[0];
	var gFin = dato[1];
	var bFin = dato[2];

	var rMed = (rFin - rIni) / (pasos - 1);
	var gMed = (gFin - gIni) / (pasos - 1);
	var bMed = (bFin - bIni) / (pasos - 1);

	for (var i = 1; i < pasos - 1; i ++)	{
		var rgb = new Array(3);
		rgb[0] = parseInt(rIni + (rMed * i));
		rgb[1] = parseInt(gIni + (gMed * i));
		rgb[2] = parseInt(bIni + (bMed * i));
		intermedios[i] = rgb;
	}
	for (i = 0; i < intermedios.length; i ++)
		intermedios[i] = colorHexa(intermedios[i]);

	return intermedios;
}

function desglose(color) {
	if (color.length != 6)
		return "poblema";
	else	{
		devolver = new Array(3);
		devolver[0] = hexadec(color.substr(0, 2));
		devolver[1] = hexadec(color.substr(2, 2));
		devolver[2] = hexadec(color.substr(4, 2));
	}
	return devolver;
}
var hexa = "0123456789abcdef";

function hexadec(x) {
	x = x.toLowerCase();
	return parseInt(hexa.indexOf(x.charAt(0))) * 16 + parseInt(hexa.indexOf(x.charAt(1)))
}

Podemos ver en funcionamiento el código, desde el siguiente enlace: Efecto fundido en texto, que aunque trate de otro asunto, genera los colores necesarios para un gradiente entre dos colores y un número de pasos estipulado.

Nuevas opciones

En la actualidad disponemos de otras opciones que deberían generar los mismos resultados. Nosotros plantearemos fondos aplicando estilos y las imágenes SVG.

gradiente del rojo al azul con 200 pixeles

De los tres gradientes que hemos expuesto, el primero es una imagen generada con un código similar al que expusimos al principio de este apunte. El segundo de los casos es simplemente una capa con estilos; que es precisamente lo que nos interesa, pero a día de hoy no es estándar, aunque es de esperar que pronto lo sea.

El último de los casos se trata de una imagen svg cuyo código es:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
x="0" y="0" width="200" height="10" preserveAspectRatio="none" viewBox="0 0 200 10" id="gradientes_svg">
	<defs>
		<linearGradient id="rojo_azul_svg" x1="0%" y1="0%" x2="100%" y2="0%" >
			<stop offset="0%" stop-color="red"/>
			<stop offset="100%" stop-color="blue"/>
		</linearGradient>
	</defs>
	<rect fill="url(#rojo_azul_svg)" width="100%" height="100%" />
</svg>

Nos falta usar canvas, para no depender del uso de javascript.






Titulo: SVG: Recorridos circulares


emoticón de Caricatos Publicado el día 01 de diciembre de 2013
id=127

Juguemos a encontrar diferencias entre las dos imágenes que vemos junto a este párrafo... Ambas tienen el mismo color, el mismo borde y la misma forma. Entonces... ¿Hay diferencias?

Pues si que hay una sutil diferencia, la primera imagen está construida por un círculo y la segunda por un camino o recorrido "path". A continuación mostramos el código de esas imágenes:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="50px" height="50px">
	<circle fill="#ff6666" cx="50" cy="50" r="49" stroke="#000000" transform="scale(.5)"/>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="50px" height="50px">
	<path fill="#ff6666" stroke="#000000" d="M 50, 50 m -49, 0 a 49, 49 0 1, 0 98, 0 a 49, 49 0 1, 0 -98, 0" transform="scale(.5)"/>
</svg>

Y ¿para qué puede interesarnos hacer un circulo con un camino "path"? Veamos un sencillo ejemplo:

El mundo gira...

Junto a estas líneas vemos que "El mundo gira...", una imagen que hemos sacado de nuestra galería, que representa a nuestro planeta girando permanentemente. Pero el texto con el que hemos etiquetado a nuestra imagen también gira de la misma manera.

PEPEMOLINA.COM PEPEMOLINA.COM La intención de usar dos arcos para crear un círculo, en nuestro caso es para adaptar un texto a esos arcos. También podemos valernos de uno solo de los arcos mencionados para alinear un texto a la línea base de un semicírculo.

Sobre el uso de recorridos para alinear textos debemos tener en cuenta información adicional como el tipo de alineación y el lugar donde empezaremos el recorrido.

El código de las dos imágenes etiquetadas con el nombre del dominio "pepemolina.com", del párrafo anterior es el siguiente:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="80px" height="80px" style="padding: 1em; border: 1px solid blue; margin: 0 0 .5em 1em; float: right;" preserveAspectRatio="none" viewBox="0 0 100 100">
	<use xlink:href="#vuelta_horaria" fill="pink" stroke="blue"/>
	<image xlink:href="diario.imagen.php?id=12&max=100" x="0" y="0" width="100%" height="100%" />
	<text x="0" y="0" style="font-weight: bold">
		<textpath xlink:href="#vuelta_horaria" text-anchor="middle" startoffset="25%">
			<tspan dy="-4">
				PEPEMOLINA.COM
			</tspan>
		</textpath>
	</text>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100px" height="50px" style="padding: 1em; border: 1px solid blue; margin: 0 0 .5em 1em; float: right;" preserveAspectRatio="none" viewBox="0 0 100 50">
	<text x="0" y="0" style="font-weight: bold;">
		<textpath xlink:href="#media_vuelta_inversa" text-anchor="middle" startoffset="50%" method="align" >
			<tspan dy="10">
				PEPEMOLINA.COM
			</tspan>
		</textpath>
	</text>
	<use xlink:href="#media_vuelta_inversa" fill="none" stroke="black">
</svg>

Previamente habíamos definido los recorridos junto al fondo en degradado del círculo de una de ellas en otra etiqueta svg:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="0" height="0">
	<defs>
		<path id="vuelta_horaria" d="M 50, 50 m -50 0 a 50, 50 0 1, 1 100, 0 a 50, 50 0 1, 1 -100, 0"/>
		<path id="vuelta_inversa" d="M 50, 50 m -50 0 a 50, 50 0 1, 0 100, 0 a 50, 50 0 1, 0 -100, 0"/>
		<path id="media_vuelta_horaria" d="M 0, 50 a 50, 50 0 1, 1 100, 0"/>
		<path id="media_vuelta_inversa" d="M 0, 0 a 50, 50 0 1, 0 100, 0"/>
		<radialGradient id="fondo_svg" cx="50%" cy="50%" r="50%">
			<stop offset="60%" style="stop-color: white; stop-opacity: 1" />
			<stop offset="80%" style="stop-color: gold; stop-opacity: 1" />
			<stop offset="100%" style="stop-color: magenta; stop-opacity: 1" />
		</radialGradient>
	</defs>
</svg>

Con respecto a la alineación centrada del texto en un recorrido, debemos poner el atributo "text-anchor" con el valor "middle" y el atributo "starOffset" con el valor "50%". Notese que hemos asignado el valor "25%" en un recorrido circular para centrar el texto en la parte superior del recorrido.

Y poco más...

La manera de obtener los recorridos circulares está basada en el algoritmo:

<path
	d="
		M cx cy
		m -r, 0
		a r,r 0 1,0 (r * 2),0
		a r,r 0 1,0 -(r * 2),0
	"
/>

La discusión donde obtuvimos el algoritmo es "Circle drawing with SVG's arc path".






Titulo: SVG vs. Ajax


emoticón de Caricatos Publicado el día 01 de junio de 2014
id=136

Después de añadir a nuestro Mapa de España las ciudades autónomas de Ceuta y Melilla hemos hecho algunas reflexiones:

A pesar de que nos ha sido de mucha utilidad el mapa usado, tuvimos que añadir Ceuta y Melilla de manera "muy artesanal", cuando existen otros mapas con sus coordenadas mucho más precisas. También notamos la ausencia del resto del continente europeo, aparentando ser una gran isla, y no un país integrado en su continente.

Intentaremos saber si nuestro navegador permite el formato svg simplemente cargando la imagen que vamos a usar, y que se encuentra en la wikipedia: Provincias de España.svg. Si se carga correctamente podemos crear una imagen nueva basándones en las características de la recientemente cargada

Pinchando sobre el botón que acompaña este párrafo (si todo va bien) realizaremos una petición Ajax para obtener los datos básicos de la etiqueta svg, junto a las distintas etiquetas "path" y "polygon" para dibujar sus siluetas. No olvidemos que los ficheros SVG son también XML (responseXML).

Antes de analizar los resultados, vemos el código que hemos usado:

svgns = "http://www.w3.org/2000/svg";
_colores_ = ["red", "lime", "blue", "green", "aqua"];
_color_ = 0;
function _obtener_tags_svg_(url, donde) {
	ajax = objetoAjax();
	ajax.open("get", url, true);
	ajax.onreadystatechange = function()	{
		if (ajax.readyState == 4) {
			resultado = ajax.responseXML;

			// elemento raíz

			_svg_ = resultado.getElementsByTagName("svg")[0];
			xmlns = _svg_.getAttribute("xmlns");
			ancho = _svg_.getAttribute("width");
			alto = _svg_.getAttribute("height");
			box = _svg_.getAttribute("viewBox");

			_imagen_ = document.createElementNS(svgns, "svg");
			_imagen_.setAttribute("xmlns", xmlns);
			_imagen_.setAttribute("width", ancho);
			_imagen_.setAttribute("height", alto);
			_imagen_.setAttribute("viewBox", box);
			_imagen_.style.border = "1px solid black";
			tag(donde).appendChild(_imagen_);

			// buscando formas (polygon, path)

			_tags_ = resultado.getElementsByTagName("*");
			for (i = 0, total = _tags_.length; i < total; i++)	{
				switch(_tags_[i].tagName.toLowerCase())	{
					case "polygon":
						_puntos_ = _tags_[i].getAttributeNS(null, "points");
						_figura_ = document.createElementNS(svgns, "polygon");
						_figura_.setAttributeNS(null, "points", _puntos_);
						_figura_.setAttributeNS(null, "stroke", _colores_[(_color_++ % _colores_.length)]);
						_figura_.setAttributeNS(null, "stroke-width", "1");
						_figura_.setAttributeNS(null, "fill", "none");
						_imagen_.appendChild(_figura_);
					break;

					case "path":
						_path_ = _tags_[i].getAttributeNS(null, "d");
						_figura_ = document.createElementNS(svgns, "path");
						_figura_.setAttributeNS(null, "d", _path_);
						_figura_.setAttributeNS(null, "stroke", _colores_[(_color_++ % _colores_.length)]);
						_figura_.setAttributeNS(null, "stroke-width", "1");
						_figura_.setAttributeNS(null, "fill", "none");
						_imagen_.appendChild(_figura_);
					break;
				}// switch
			}// for
		}
	}
	ajax.send(null);
}

A partir del resultado que vemos, sabiendo que solo hemos añadido siluetas, nos resulta raro encontrarnos con textos. Evidentemente se han insertado con polígonos o recorridos (path). Podríamos reconocerlos y eliminarlos, pero al ver el resto de las siluetas, encontramos algunas líneas incorrectas, así que buscaremos otros mapas que nos puedan interesar más.

Otros Mapas

Haciendo una búsqueda en la Wikipedia, hemos encontrado otros mapas que mostramos a continuación; Pulsando sobre cada uno de ellos se mostrarán las siluetas de sus formas en el "Espacio para mostrar otro mapa":

http://upload.wikimedia.org/wikipedia/commons/6/61/Provincias_de_Espa%C3%B1a_centrado.svg http://upload.wikimedia.org/wikipedia/commons/e/e8/Provincias_de_Espa%C3%B1a_%28an%29.svg http://upload.wikimedia.org/wikipedia/commons/3/35/Prov%C3%ADncies_d%27Espanya.svg

Espacio para mostrar otro mapa

Si todo ha ido bien y podemos ver las diferencias en las siluetas, nos decantaremos por el tercero de los mapas, que en un futuro apunte trataremos de estudiar más a fondo.






Titulo: Etiquetando mapa SVG


emoticón de Caricatos Publicado el día 19 de noviembre de 2014
id=139

Entre las reflexiones hechas en el apunte SVG vs. Ajax, hemos decidido utilizar el mapa que se ve a continuación. Para mostrarlo hemos filtrado las etiquetas polygon y path; y hemos usado un color para cada etiqueta: rojo para "path" y verde para "polygon". El resultado, aunque parece bastante bueno, nos ha movido a estudiar más a fondo el mapa escogido.

Vicisitudes

Notamos a simple vista una tonalidad no esperada en la provincia de Cáceres, razón por la cual revisamos las etiquetas originales de la imagen para ver si encontrábamos algo extraño, y ¡eureka! (*). Vemos dentro de la lista de , la de "polyline", que básicamente es igual al polígono, así que arreglamos este problema tratando esta etiqueta igual que "polygon".

También vemos una forma rara en África de tono rojizo, por lo que podemos deducir que es una etiqueta "path", aunque viendo el mapa original deducimos que se trata de la línea fronteriza entre los dos países africanos: Marruecos y Argelia.

Al ver el fondo en tonalidad verdosa, y aún más intenso el recuadro de las islas canarias, deducimos que son cuadrados hechos con polígonos.

Antes de continuar describiremos unas sencillas herramientas para poder analizar más a fondo el mapa.

Herramientas

A la vez que generamos el mapa que estamos mostrando, hemos generado una variable de tipo objeto con los datos básicos que nos interesa: Tamaño y lista de formas que representan provincias y otros países. Con esos datos actualizamos un formulario que podemos mostrar y ocultar con el control que aparece a continuación: .

El formulario que aparece al pulsar el botón (y que puede volver a ocultarse volviéndolo a pulsar), nos muestra un control que nos permite seleccionar las formas. Seguidamente vemos el nombre que tiene la forma activa, que originalmente coincide con la etiqueta "svg" de la misma (path, polygon o polyline).

Luego encontramos el selector de estilos, que sirve para diferenciar la apariencia de las formas seleccionadas. El siguiente control es útil para reconocer los elementos pequeños, como Ceuta y Melilla. Aunque el "zoom" permite una ampliación de 20x, con una escala pequeña es suficiente.

Reflexiones

Con esos controles que hemos descrito hemos obtenido un que evidentemente nos da motivos de reflexión.

Tanto las islas Canarias, como las Baleares están unidas en una sola etiqueta (las primeras citadas en dos), y nos interesa separarlas. Las fronteras entre provincias mostradas con elementos path no coinciden con los polígonos

Nos queda por comentar que hemos añadido un par de comportamientos a las formas del mapa: se pueden seleccionar simplemente pinchando sobre ella y al posar el puntero del ratón nos muestra el nombre que lleva. Creemos que son utilidades muy propicias para nominar cada elemento.






Titulo: Fondos con SVG


emoticón de Caricatos Publicado el día 28 de diciembre de 2014
id=140

Las imágenes SVG también pueden servirnos para personalizar los fondos de nuestras páginas, o de algunos de sus elementos. En un mensaje de los foros, pensé que este formato de imágenes escalables podría ser ideal para dar la respuesta al tema "letras en diagonal (para el background)". Un estilo de fondo similar al de la respuesta es el que hemos puesto para el cuerpo de ésta página:

body	{
	background: url("data:image/svg+xml;iso-8859-1,
	<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300' x='0' y='0'>
		<text x='150' y='150' style='font: bold 36px arial; dominant-baseline: middle; fill: red; text-anchor: middle; opacity: .2' transform='rotate(-45,150,150)'>
			pepemolina.com
		</text>
	</svg>"
	);
}

En el código original no existen saltos de línea ni tabuladores.

Otro elemento svg que estamos usando de fondo es el mapa de España que aparece junto al título del apunte, que es el mismo del apunte: Mapas interactivos svg, y su código hemos modificado levemente para permitir opacidad: mapa_comunidades_hispanas.

Ajustes

pepemolina.com El fondo de la página lo hemos aislado a un lado de este párrafo para mostrar mejor sus detalles. También hemos eliminado la opacidad, y para distinguir la alineación, añadimos una línea que cruza diagonalmente el recuadro, aunque también hemos reducido algo el tamaño (no nos olvidemos de la escalabilidad del formato), ya que no era necesario usar la misma resolución que el fondo.

De todos modos, despreocupándonos del tamaño al escalarla, tenemos una imagen del 300x300 (digamos que nos referimos a puntos), donde el texto lo ubicamos en el centro (150x150). Para el centrado horizontal usamos el estilo/atributo text-anchor, dándole el valor "middle" (mitad), y usamos el mismo valor para el centrado vertical en el estilo/atributo dominant-baseline.

Dejamos de lado el estilo de las letras, solo nos queda rotar nuestro texto: "transform='rotate(-45, 150, 150)'".

Sobre el mapa de España en la esquina superior derecha del espacio reservado para el apunte, solo comentaremos que hemos modificado el código que genera ese mapa, añadiendo la posiblidad de aplicarle opacidad.

Algunas sugerencias

Si revisamos nuestros grupos de apuntes, hemos tratado distintos tipos de ficheros svg. Un reloj analógico, figuras geométricas, mapas, textos con distintas sinuosidades, gradientes, animaciones... incluso postales digitales.






Titulo: Postales en SVG


emoticón de Caricatos Publicado el día 18 de febrero de 2015
id=142

Tenemos nuestras postales digitales también en formato svg:

Podemos incrustarlas en nuestras páginas siguiendo los siguientes pasos:

Elegimos nuestra postal de la galería.
Al principio vemos una postal en primer plano elegida al azar, y a pie de página el resto. Si no nos interesa la que aparece aleatoriamente, pulsamos la miniatura que nos interese y aparecerá seleccionada.
Teniendo nuestra postal en primer plano pulsamos sobre el título o el identificador (id).
Aparecerá la postal sin el menú de selección de las mismas, y unas opciones de las que nos interesa: "Generar fichero svg".
Vemos en nuestro navegador una imagen en formato svg.
Tan solo debemos copiar su código fuente en otro fichero con extensión "svg".

Pero aún hay más...

Más opciones

Podemos tener las imagenes incrustadas sin la dependencia de Internet, eliminando de la línea de comandos del navegador el texto "&url=si".

También podemos escalarla (no nos olvidemos que la "s" de "svg" se debe a "eScalable") añadiendo "?&porcentaje=" + el porcentaje del escalado. Por ejemplo añadiendo "&porcentaje=50" nos mostrará la misma postal en la mitad de su tamaño... cambiando 50 por 200 será el doble de grande respecto a la original; etc.






Titulo: Clip-Art: de wmf a svg


emoticón de Caricatos Publicado el día 08 de marzo de 2015
id=143

Hace algunos años las revistas sobre temas informáticos nos inundaron de dibujitos conocidos como "clipart" (o clip-art).

Aquellos dibujos digitales eran sobre todo imágenes animadas en formato gif, o vectoriales wmf. Los primeros podrían ser útiles en presentaciones en ordenadores, y los segundos eran muy importantes en diseño gráfico para impresión.

Para obtener el mismo dibujo, pero en formato svg existen algunas aplicaciones para su conversión. La más conocida y de libre uso es Inkscape. Y sin ser libre existen aplicaciones de edición vectorial entre los que destacamos CorelDRAW.

Otras aplicaciones interesantes para la conversión son:

SVG Factory
Conversor de imagenes wmf y bmp. Puede convertir ficheros o carpetas.
EMF to SVG Converter
Conversor de imagenes wmf. Puede convertir ficheros o carpetas.

Usando estas aplicaciones hemos notado que en algunas ocasiones no funcionaba correctamente así que pensamos usar Inkscape, pero ayudados por un fichero de sistema por lotes.

Copiando estructura y generando el fichero .bat.

Primero hemos creado un par de carpetas en nuestro sistema "localhost": clipart_wmf y clipart_svg. Luego hemos copiado el sistema de archivos wmf a la carpeta "clipart_wmf", y hemos creado un fichero php con el siguiente código:

<?php
$l = Array();
function hacer($origen, $destino) {
	global $l;

	function recorrer($co, $cd)	{
		global $l;
		if (!is_dir($cd))
			mkdir($cd);
		$puntos = Array(".", "..");
		$d = dir($co); $cuenta = 0;
		while (false !== ($entry = $d->read()))	{

			if (!in_array($entry, $puntos))
				if (is_dir("$co/$entry"))	{
					recorrer("$co/$entry", "$cd/$entry");
				}
				else	{
					if (strpos(strtolower($entry), ".wmf"))	{
						$base = substr($entry, 0, strrpos(strtolower($entry), ".wmf")).".svg";
if (!is_file("$cd/$base"))
						array_push($l, "c:\Inkscape\Inkscape ".str_replace("/", "\\", $co)."\\$entry --export-plain-svg=".str_replace("/", "\\",$cd)."\\$base");
						$cuenta++;
					}
				}
		}
		echo "carpeta: $co ($cuenta dibujos)<br/>\n";
	}

	if (is_dir($origen))	{
		recorrer($origen, $destino);
		file_put_contents("exportar.bat", implode("\n", $l));

	}
	else
		echo "no existe carpeta $origen";
}

hacer("dibus_wmf", "dibus_svg");
?>

El código recorre la carpeta de ficheros wmf y por cada carpeta leída en origen, genera la misma carpeta en el destino; y por cada fichero wmf encontrado se añade a un array una línea de texto que luego se volcará a un fichero "exportar.bat".

Luego ejecutamos "exportar.bat", y si todo funciona correctamente, obtendremos los resultados deseados.

Notas adicionales

Según el número de ficheros y carpetas del sistema que tengamos, podría abortarse la página, así que deberíamos seguir la premisa: "divide y vencerás".

Podemos hacer la conversión por etapas, cancelando el proceso manualmente; en tal caso deberíamos generar nuevamente el fichero por lotes "exportar.bat", o eliminar las líneas de texto del fichero en cuestión referentes a los dibujos ya creados.






Titulo: SVG: Dibujando mapas


emoticón de Caricatos Publicado el día 24 de enero de 2017
id=150

Hemos visto con el apunte anterior, que mapear una imagen ahora es fácil y preciso gracias a nuestra aplicación para Capturar áreas en imágenes. Ahora intentaremos hacerlo más bonito y divertido mostrando la evolución del trazado de cada área.

Vemos a continuación el mismo mapamundi del apunte Mapear una imagen paso a paso (que ya hemos mencionado), junto a unos controles que luego comentaremos.

Controles Selección de áreas:



A continuación indicaremos las características de los controles que hemos añadido al mapamundi.

Los controles

La selección de áreas sencillamente aplica los parámetros seleccionados en el resto de controles. Si el trazo está hecho, simplemente se deshace, con el tiempo actualizado, y con el mismo trazo que fue creado. En el caso de haber una variación de otros parámetros, no se procesarán hasta la generación de un nuevo trazo.

El Tiempo en segundos es lo que tardará en dibujarse o desdibujarse el polígono que elijamos. Puede dibujarse el el mínimo tiempo (1 segundo) y desdibujarse en el máximo (10).

El Tipo de dibujo que tenemos activo es "punto a punto" donde se incluye un punto más visible en cada coordenada del área que se seleccione. La siguiente opción es el trazo de línea, que es muy parecida a las siguientes dos opciones, ambas se refieren al trazado de polígonos; y se diferencian porque el trazo de tarta se inicia desde el centro del polígono.

Sobre el Color de relleno, se aplicará a las figuras que se creen nuevas; y en el caso de que sea ddel tipo "punto a punto", el relleno se aplicará a cada punto y no al área.

Algunas reflexiones

Las áreas nuevas se crean encima de las viejas, así que podemos ver como se han detectado los puntos en nuestra aplicación. Usando un tiempo mayor, mejor se aprecia ese desarrollo.

Sobre el tipo de dibujo, en vez de comentar, invito a probarlo. Nótese la diferencia entre el trazo de líneas y de polígonos.

También invito a descubrir la diferencia entre el color transparente y la ausencia de color (sin color).

Puede verse el código javascript del apunte.






Titulo: SVG: Zoom en mapa de imagen


emoticón de Caricatos Publicado el día 03 de febrero de 2017
id=151

Hacer zoom en una imagen SVG es más fácil de lo que se puede pensar. Recomendamos para obtener el mapa nuestra aplicación "Capturar áreas en imágenes".

Sabiendo las coordenadas y tamaño de lo que queremos ampliar, simplemente tenemos que poner esos datos en el atributo "viewBox" de la etiqueta "svg".

Zona (sin zoom) [] | [] | [] | [] | [] | []
Aspecto

Podemos apreciar el efecto en el mapa que mostramos (mapamundi). Haciendo doble click en algunos de los países que listamos o pinchando sobre el nombre en los controles de "Zona". Nótese la casilla "flexible", que cambia el valor del atributo svg preserveAspectRatio.

Por último enlazamos al código javascript correspondiente.






Titulo: Mapa de España SVG II: Vicisitudes


emoticón de Caricatos Publicado el día 29 de marzo de 2017
id=152

Províncies d'Espanya Teníamos pendiente actualizar el mapa de España por varios motivos y nos hemos puesto en ello. Nos habíamos fijado en unos de los que nos ofrece la wikipedia, y que mostramos de manera reducida. Detallaremos los pequeños retoques que se nos ocurre hacer, basándonos en los distintos atributos de los elementos seleccionados.

Empezaremos "destripando" lo que nos interesa, utilizando como base el código del apunte SVG vs. Ajax, donde se dibujan los elementos sin usar relleno.

Revisando el código hemos visto que por cada elemento se asignan estilos en el propio ídem, así que como primer paso hemos declarado una primera sección.

Estilos

Hemos definido clases para reducir el código... una primera aproximación vemos a continuación:

<![CDATA[
.provincia	{
	stroke:	#ccc;
	fill:	#fff8e3;
}
.provincia:hover	{
	fill:	red;
}
.nada	{
	fill:	none;
	stroke:	#999;
}
.marco	{
	fill:	none;
	stroke:	black;
	stroke-width: 2;
	stroke-miterlimit:	4;
}
.marco_canario	{
	fill:	none;
	stroke:	#1a171b;
	stroke-miterlimit:	4;
}
.linde_canario	{
	fill:	black;
	fill-rule:	evenodd;
	stroke:	#ccc;
	stroke-width:	0.5;
	stroke-linecap:	butt;
	stroke-linejoin:	miter;
	stroke-opacity:	1;
	fill-opacity:	1;
	opacity:	0.9;
	stroke-miterlimit:	4;
	stroke-dasharray:	none;
}
.agua	{
	fill:	#d3ebfa;
}
.exterior	{
	fill:	#f4e2ba;
	stroke:	#999;
}
]]>

Evidentemente se trata de código "provisional", ya que la clase "nada" es algo concreto que ya trataremos; y posiblemente algunos estilos sean innecesarios.

También notamos el uso del elemento CDATA, para conseguir un fichero XML "bien formado", y así propiciar su edición, por ejemplo con programas como inkscape.

El resultado (provisional)

Vemos como queda esta primera versión del nuevo mapa de España que usaremos en adelante.

Como nota final hemos probado insertar la imagen con los distintos métodos que ya hemos usado en un apunte anterior: Rotando imágenes con svg, y detectamos que no se inserta correctamente usando la etiqueta "img". Procuraremos averiguar el motivo.






Titulo: Mapa de España SVG II: Herramientas


emoticón de Caricatos Publicado el día 12 de abril de 2017
id=153

Para ver en detalle los distintos elementos del mapa que hemos elegido de la Wikipedia, ya habíamos desarrollado una sencilla herramienta que lee las etiquetas y atributos que nos interesan de una imagen en formato "SVG".

Hemos retocado nuestra herramienta para nuestras nuevas pretenciones. Ahora, a partir del fichero elegido obtendremos un código bastante simplificado. Empezaremos con un sencillo formulario:

Cuando se pulsa el botón del formulario, debajo de estas líneas se muestra el mapa de España, y se actualizan los recuadros de más abajo con datos recogidos del mapa.

Se pueden seleccionar los elementos por su nombre o pulsando sobre ellos en el mapa. Nótese un botón marcado como "zoom"; que también puede conseguirse con un doble click sobre el elemento.

edición

datos

		

Terminamos mostrando el código resultante, junto a los estilos y una vista previa.

Código CSS
Código SVG
Imagen

Después de revisar los detalles de cada provincia con el zoom, hemos creado una sencilla hoja de estilos que mostramos en la primera pestaña.

Puede verse el código de estas herramientas en este enlace, y podemos afirmar que el ressultado aún no es el definitivo.






Titulo: Mapa de España SVG II: Reflexiones


emoticón de Caricatos Publicado el día 07 de diciembre de 2017
id=154

Después de usar las "herramientas" del apunte anterior, vamos a hacer algunas valoraciones.

Tal vez para comprender alguna de las reflexiones sea interesante tener el apunte anterior en otra pestaña de nuestro navegador.

Path vs. Polygon (y Polyline)

La etiqueta Polyline es básicamente igual a Polygon (polilínea y polígono), así que la única aparición de esta primera etiqueta la hemos cambiado por la segunda (polyline242: Badajoz). Es más, para convertir la primera en la segunda tan solo hay que repetir la primera coordenada al final de todas las coordenadas; o sea que la primera y última coordenada deben ser la misma para cerrar ese polígono, cosa que no ocurre en el fichero original, así que podemos concluir que se trata simplemente de un descuido.

Las que sí son distintas son polygon y path, ya que esta última admite curvas, y además pueden tener más de una forma.

Una de las herramientas convierte las etiquetas "path" a sus correspondientes "polygon" basándonos sólamente en los puntos. Al convertir una etiqueta "path" podemos obtener más de un polígono, pero se puede conseguir el mismo resultado agrupando polígonos dentro de una etiqueta "g" (lo contemplaremos más adelante).

Más descuidos

Hemos encontrado más imperfecciones que en el futuro trataremos de reparar, entre las que citaremos alguna:
Cáceres vs. Ciudad Real: Al convertir en polígonos la provincia de Cáceres, obtenemos dos formas de las cuales, una se corresponde realmente con Cáceres; y la otra forma pertenece a la provincia de Ciudad Real.
Gerona y Llivia: Llivia es un pequeño municipio (polygon112), perteneciente a la provincia de Gerona (polygon100)

Correcciones

De las herramientas hemos corregido un par de errores: reinicializamos la variable "_poligonear_" al cargar el mapa (cada vez que se hace). Y en los nuevos polígonos hemos copiado los estilos en el objeto _mapa_.



Zona de comentarios

Esto grupo aún no tiene comentarios.

Evaluación

Valoración de esta página: (grupo.svg) valor

Valoración evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar

Respuesta: Zona de mensajes (proceso de evaluación)

Copyright © 2002-2024 www.pepemolina.com
RSS rss | Ver Mapa del sitio