jueves, 25 de diciembre de 2008

¡Hola mundo! (2ª parte)

Una vez vistos los programas que se pueden en C para crear ficheros SVG (programas que en principio, se podrían escribir también en PHP y cualquier lenguaje), voy a explicar un hola mundo según el otro enfoque del blog: ficheros SVG interactivos.
El formato SVG permite dos tipos de interactividad, que explicadas un poco por encima serían estas dos:
  • Mediante guiones (scripts): en este caso se meten guiones en el fichero SVG (o en un fichero a parte, que luego se enlazan al fichero SVG). Esos guiones permiten interactuar con los elementos del fichero SVG. Por ejemplo, se puede conseguir que al pulsar un botón cambie el color de un elemento, o bien su posición, o bien cambie el texto de un elemento de texto. Este sistema también permite añadir elementos nuevos al fichero SVG que no estaban definidos inicialmente (por ejemplo, cada vez que se hace clic en un cuadrado aparece un círculo nuevo en pantalla en una posición diferente). Unos ejemplos:

    svgDocument.getElementById('holamundo').firstChild.data = "¡Hola mundo!";
    svgDocument.getElementById('panel_epicicloides').setAttributeNS(null, "visibility", "visible" ); svgDocument.getElementById('laser').setAttributeNS(null, "points", puntos );

    El primer ejemplo modifica un texto (sustituye su contenido por ¡Hola mundo!). El segundo hace aparecer un grupo (llamado panel_epicicloides), ese grupo contiene varias figuras que actuan como un diálogo. Lo que hace, es modificar su propiedad de visibilidad (visibility) activándola. El último caso, modifica la trayectoria de una polilinea (llamada laser) y hace que tenga los puntos que se metieron antes en la variable de texto puntos. Se modifica la propiedad points.
  • Mediante animaciones SMIL: en este caso no se usan guiones, sino más etiquetas SVG donde se indican las acciones. Estas etiquetas no tienen tanta potencia como los guiones (scripts), pero facilitan mucho la creacción de algunos efectos interactivos, como el cambio de color de un elemento mientras se pasa el ratón por encima. Una pega de este sistema es que Firefox 3 no está adaptado (el fichero SVG es mostrado sin estos efectos), aunque no creo que tarden en incluir esta mejora.
    Hay dos tipos de etiquetas: set y animate. Set permite aplicar un atributo de forma directa, sin una transición intermedia (ejemplo: un rectángulo rojo, inmediatamente se pone en verde). En cambio animate permite producir una transición con una duración, y permite establecer varios pasos intermedios y una interpolación de los valores intermedios. Por ejemplo, se puede tener el rectángulo rojo de antes, pero al ponerse en verde pasa por el color morado, el azul y finalmente el verde, durante una transición de colores de tres segundos de duración. En ambos casos, hay que indicar un evento donde se inicia el cambio, un atributo y el valor para el atributo.
    Unos ejemplos (clic para ampliar):
    En las dos primeras lineas se usa set. Son entradas alternativas, la primera se activa cuando el ratón entra dentro del grupo g_hola_mundo, y la segunda cuando sale. El atributo que modifican es el relleno (fill) y dan el color indicado en to. Su funcionamiento permite realizar un cambio de color cuando se pasa el ratón encima del grupo g_hola_mundo (que vendría a actuar a modo de botón).
    En la tercera linea hay una animación donde se modifica el color a través de una transición de varios colores que dura un segundo.
El ejemplo de "¡Hola mundo!" interactivo sería este código (lo subiré a una página web que estoy preparando junto con el fichero SVG listo para ver en el navegador). En el se usan las dos maneras de dar interactividad:

Se vería más o menos así:
El funcionamiento es sencillo: inicialmente solo aparece el botón "clic". Al pulsar el botón aparece ¡Hola mundo!. Mientras, el botón toma un color verdoso al pasar el ratón por encima (en Firefox 3 no se aprecia esto último).
En el se puede destacar varios detalles:
  • La cabecera del SVG es diferente del hola mundo de la entrada del blog anterior, ya que en esa no funcionaban las animaciones. Esa cabecera nueva la copié del primer enlace de las fuentes (apike.ca), y también copié la primera función del script. Si programando te encuentras que el fichero SVG parece tonto y no hace nada, puede ser dos cosas, que te hayas equivocado en el script (una coma mal puesta puede detener su ejecución), o que la cabecera esté mal indicada.
  • Hay un grupo (llamado g_hola_mundo) que agrupa un rectángulo (r_hola_mundo) y un texto (clic). Este grupo lo señalo en verde y tiene asignado que cuando se pulse el ratón sobre el se llame la función "hola mundo" del guión. Esta función se asigna sobre el grupo y no sobre el rectángulo, porque si se asignara sobre el rectángulo solo funcionaría en el área que se ve del rectángulo, es decir, si se hace clic justo sobre las letras del texto no haría nada. En cambio, si se asigna la función sobre el grupo entero (texto y rectángulo), funciona en todo el área.
    Digamos que este grupo sería a efectos prácticos... un botón como los de cualquier cuadro de diálogo.
  • Un guión con una función (hola_mundo) que se activa al hacer clic en el grupo "g_hola_mundo". Esta función modifica el texto del elemento de texto "holamundo" (la última entrada del fichero SVG), sustituyendo el espacio que tenía originalmente por el texto ¡Hola mundo!
  • Dos etiquetas para animar el color de fondo del rectángulo que forma el botón para activar el hola mundo. La primera asigna un color más verdoso al fondo cuando el ratón pasa por encima del grupo. La segunda asigna el color original cuando el ratón sale de esta zona. El evento es al meter el ratón dentro del grupo, porque si se hiciera en función del rectángulo solo habría un problema: al pasar el ratón por encima de las letras del texto se interpretaría de la misma forma que sacar el ratón del rectángulo, y fallaría.
  • El rectángulo aparece en dos etiquetas en vez de una sola. Esto se hace cuando hay que añadir propiedades de animación al rectángulo.
    La primera linea (sombreada en amarillo) sería para definir un rectángulo que no va a tener animación ni nada. Es una sola etiqueta y tiene la barra para indicar el final (/) que se pone en las etiquetas de cierre.
    Las otras lineas (sombreadas en verde) también definen un rectángulo, pero entre medias se pueden introducir etiquetas para definir animación. Es muy importante destacar que la barra inclinada (/) solo aparece en la segunda etiqueta, la de cierre y nunca en la primera.
    El resto de elementos (círculos, lineas, polilineas...) funcionan de forma parecida. Normalmente se definen usando una sola etiqueta, pero si se quiere añadir animaciones, hay que usar dos y poner las etiquetas para definir las animaciones entre medias.

Fuentes:
  • http://apike.ca/prog_svg_smil.html
  • http://rendergraf.wordpress.com/2008/09/12/animacion-svg-%E2%80%93-llega-la-alternativa-a-flash-pero-con-un-estandar-libre/

sábado, 20 de diciembre de 2008

¡Hola mundo!

Lo mejor para empezar es con el clásico Hola mundo. Hacer que un programa genere un Hola Mundo no es difícil, basta pegar las entradas del fichero SVG dentro de la función fprintf o fputs donde se va escribiendo el fichero SVG.
Es muy importante añadir una barra inversa (\) antes de cada comillas ("), ya que sino, se interpreta el final de la cadena y fallará el programa o no se podrá compilar.

En breve subiré el código fuente a otra página web donde publicar código fuente, ficheros SVG y descargas con comodidad, ya que este blog falla a la hora de copiar el código fuente.
Quedaría algo así:

No hay mucho que explicar de este hola mundo:
  • La codificación (encoding="ISO-8859-1") es para indicar la codificación de carácteres del fichero SVG. Si se indica mal, los acentos y signos de puntuación no ingleses aparecerán mal. El valor introducido depende de como se guarde el fichero de texto cuando se escriba.
  • width y height indican el tamaño que ocupará en pantalla el fichero SVG. Si su valor es 100%, indican que el fichero SVG ocupará el 100% del espacio de pantalla o el espacio que le indique la etiqueta EMBED. Si son números sin porcentaje, indican un tamaño fijo que no se cambia. Si la etiqueta EMBED da al fichero SVG un tamaño más pequeño que lo indicado por las cifras, este aparecerá recortado, y si es mayor, aparecerá con una zona en blanco sin ocupar.
  • ViewBox en cambio, indica la porción de la imágen SVG que se recortará y se encajará en el recuadro indicado por width y height.
  • La etiqueta text indica el texto. La forma más simple de usarla es introduciendo el texto diréctamente entre la etiqueta de abrir y la de cerrar. Sus propiedades indican la fuente, color, posición... text-anchor permite alinear el texto (izquierda con end, derecha con start y centro con middle) respecto del punto indicado por las coordenadas x,y (en este caso 60 para los dos valores).
El anterior código fuente funciona bien, pero no hace nada especial que no se pueda hacer con el Block de notas o cualquier otro editor de texto (VI, Gedit...) o con Inkscape. Sustituyendo algunas funciones por printf y cambiando algunos valores numéricos por variables, se puede conseguir un programa que genere un fichero SVG del tamaño dado, con la frase ¡Hola mundo! centrada en el fichero SVG.

El programa ahora usa dos variables para determinar el ancho y alto de la imagen SVG. Además, sitúa el texto en el centro mediante el uso del parámetro text-anchor="start" en la etiqueta de texto y de situar el punto donde se alinea el texto justo en el centro de la imagen. Si se cambian los valores de alto y ancho, el archivo SVG que sale será más grande o más pequeño. Además, ahora el texto tiene una fuente un poco más grande que antes.
¿Que se podría destacar de este programa?
  • Puede crearse algo similar en PHP. En mi caso he usado C por su sencillez de comprensión en ejemplos sencillos, pero con PHP se podría hacer un programa similar.
  • Las variables ancho y alto reciben el valor en la compilación, pero un programa "bien hecho" tomaría los valores de estas variables de parámetros que se le pasan al programa, de ficheros de texto de entrada de datos, de bases de datos... cada caso es un mundo.
  • Se usa %.1f en printf ya que en pantalla no se necesita una precisión superior a un decimal. Si no se pone nada, printf dejaría 6 decimales, lo cual aumentaría el tamaño del fichero. En este ejemplo con pocos usos no importa mucho este detalle, pero en una polilínea de 500 puntos, si influye más este detalle.
  • Para situar el texto se usan números en punto flotante (%.1f), mientras que el tamaño de la imágen SVG se usan números enteros (%i). Esto es porque el tamaño de la imágen tiene que ser un número entero, pero luego, a la hora de situar los elementos dentro de esta, se pueden usar números en punto flotante.
  • Se escribe (float) delante de cada cálculo con números float. Esto es porque si no se hace, el valor se calcula primero como número entero y luego se convierte a float (es decir, se haría la división sin decimales). En cambio si se convierte el número antes a float, se hace el cálculo como coma flotante, y así se permite que el resultado de las operaciones pueda llevar decimales, haciendo que la posición del texto sea más precisa que si se calcula sin decimales.
Fuente:
  • http://vanus01.net/web/generando-imagenes-svg/2/

domingo, 14 de diciembre de 2008

Introducción breve a SVG

El tema principal de este blog será programar usando el estándar SVG de ficheros vectoriales. Ese estándar es muy similar a SWF, aunque tiene diferentes ventajas e inconvenientes diferentes a SWF.

El principal inconveniente es que a penas está extendido en Internet, solo son compatibles Opera, Google Chrome y Firefox. Internet Explorer puede ser compatible con una extensión de Adobe que se instala a parte, pero pocos usuarios estarían dispuestos a instalarla. Actualmente más del 25% de navegadores del mundo estarían en condiciones de usar SVG sin problemas, aunque este porcentaje va en aumento constante. (1)

Otro motivo de su poco uso es que a penas hay recursos para SVG (foros, tutoriales...), mientras que para SWF hay bastantes más.

Como ventajas de SVG destacaría que es un formato basado en texto y lenguaje XML. Esto es que permite ser creado fácilmente sin necesidad de usarse bibliotecas adicionales por cualquier programa. Otra ventaja, es que es un formato libre, sin patentes ni regalías (royalties), y que puede ser usado sin problemas.

En cuanto a programación, se utiliza ECMAScript, que es un lenguaje similar a Java Script.

Los ficheros SVG siempre guardan el carácter de abiertos (a no ser que se use un ofuscador de código), ya que no se compilan y llevan todo el código visible. Los ficheros SWF se crean a partir de ficheros FLA con todo "el material" y se distribuyen "compilados", en formato SWF (hay aplicaciones especiales que permiten descompilarlos, aunque nunca se llega a recuperar el código original).

Otra ventaja de SVG es que permite usar ficheros CSS de estilo, y que se integran mejor en las páginas web. Por último, destacaría que al ser un formato XML, es menos probable que surgan problemas de compatibilidad con versiones diferentes de SVG.

En cuanto a soporte para teléfonos móviles, PDAs... el formato SVG suele ser bastante compatible mediante unas versiones reducidas llamadas SVG Tiny y SVG Basic. Estas versiones no tienen las mismas posibilidades que la versión completa (no tienen filtros, por ejemplo). Aunque muchos modelos no se limitan a SVG Tiny y SVG Basic incluyen algunas características del formato SVG completo.

A la hora de decidirse por uno o otro hay que valorar las ventajas de cada uno.

Ahora también trukis para SVG

Esta es la primera publicación de este nuevo blog. Mi objetivo es hablar de algunos proyectillos sueltos que he ido haciendo sobre SVG. Voy a comentar un poco que hago en cada uno, y así aportar ideas sueltas a otras personas que necesiten hacer algo parecido a lo que haya hecho yo.

Podría hablar también de como hacer juegos en SVG, pero no esperéis que me dedique ha hacer grandes juegos como los que se ven en flash, como mucho serían juegos sencillos donde explico algunos trucos.

Otra idea también es comentar ficheros SVG que hayan hecho otras personas y explicar como funcionan.

En principio tengo estos tres proyectos para comentar, y de los que iré hablando poco a poco. Estos proyectos están alojados también en otra página web (para permitir ver el SVG diréctamente desde el navegador). Esa página web tiene uso de ventanas emergentes (pop-ups), aunque este blog no hará uso de publicidad intrusiva (si tengo pensado añadir en el futuro publicidad Ad-sense, que es poco molesta). Tener un bloqueo de pop-ups puede ser suficiente en esa otra web.
  • Gráfico con las comunidades autónomas españolas. Es un programa que a partir de un documento de texto con datos (como la población en este caso) genera un fichero SVG con cierta interactividad, donde al pasar el ratón por encima de las siluetas se modifica el texto que hay abajo. Para el futuro sería interesante poder usar varios mapas.
    En la primera versión he usado este mapa:
    http://commons.wikimedia.org/wiki/File:Mapa_Espanha_CC_AA.png
    Así que los mapas que se hagan con el serían con licencia GFDL. El programa lo liberaré con licencia BSD.
  • Gráfico de superficie 3D. Es un programa en C que genera un fichero SVG estático con el gráfico con efecto de iluminación y varias posiciones. Mi idea es que se pudiera girar este gráfico. La pega de este proyecto, es que con cierto número de polígonos el navegador tarda mucho en dibujar el gráfico (este sería el caso de la imágen, que puede tardar 10'' en dibujarse complétamente). Ya, lo que es crear un motor de renderizado completo en SVG... creo que pilla fuera de mis posibilidades, jejeje.
  • Simulador de láser haciendo figuras de Lissajous. Es un fichero SVG con varios botones que modifica la forma de un polígono dando las formas similares a un efecto típico que se realiza con lásers, o que se puede visualizar en osciloscopios. Una idea de futuro sería la posibilidad de añadir nuevas figuras, y que aparezca un diálogo o otro según la figura que sea.