Mis notas sobre SVG – Mouseover animate
Archivado en: Diseño Gráfico Diseño Web SVG
Empiezo una nueva serie de entradas donde iré relatando los problemas que voy encontrando mientras utilizo SVG, y las soluciones a estos problemas. Lo llamare solución por llamarlo de alguna manera, ya que la solución a algunos problemas es directamente no utilizar ciertas cosas, y es que como viene siendo costumbre en este mundo nada funciona de la misma manera si lo vemos en Chrome, Safari, Firefox, Opera o IE.
Mouseover en animate
En el proceso de rediseño de mi web(si, estoy trabajando en una nueva versión) me decidí a incluir una animación en SVG que ocupara una buena parte de la cabecera, la idea era y es no tener que recurrir a JavaScript y conseguir todos los efectos con SVG, y para que la animación funcione poner todas y cada una de las animaciones en el HTML.
La parte principal de la animación consta de 288 polígonos a través de la etiqueta polygon
, cada uno de ellos con sus respectivas animaciones a través de la etiqueta animate
, cuando conseguí implementar todas las ideas que tenía para la animación me di cuenta de que aquello se me había ido completamente de las manos, la animación ocupaba mas o menos el 90% del HTML con un total de 1700 líneas, lo cual es una barbaridad y hace que el tamaño de un simple HTML alcance un peso de 158KB, así que me puse a buscar alguna solución para aquellas animaciones que eran iguales y se repetían continuamente en cada uno de los polígonos.
Si en lugar de tener un animate
tenemos un linearGradient
o un filter
tenemos la etiqueta defs
para almacenar los efectos, simplemente le colocamos un id
y luego lo invocamos a través de la etiqueta filter
o con el atributo url
, para hacer lo mismo pero con las animaciones ya sea animate
o animateTransform
(no pongo animateColor
ya que se ha desestimado para SVG 2) no disponemos de la etiqueta defs
para almacenar las animaciones.
Como había dicho anteriormente tengo 288 polígonos, y muchos de ellos reciben la misma animación, asi que vamos a intentar ahorrar código. Lo primero es declarar al principio un polygon
y dentro de las etiquetas cada una de nuestras animaciones a través de la etiqueta animate
, luego lo invocamos con la etiqueta use
y obtendremos un polygon con la mismas medidas y con todas las animaciones que tengamos declaradas, para mover de posicion el polygon nos bastara con utilizar las coordenadas x
e y
dentro de la etiqueta use
, parece fácil ¿no? pues deberemos olvidarnos de esto si a nuestra animación tiene la orden de comenzar con begin="mouseover"
, y es que los navegadores Chrome y Opera interpretan que estas declarando la animación sobre todos y cada uno de los polígonos, así que aunque tengamos declarados 288 use
si me posiciono en el número 1 se va a activar inmediatamente la animación en los 287 restantes y yo lo que quiero es que la animación de cada polygon
sea individual e independiente del resto. En cambio si probamos en Firefox si que se consigue el efecto deseado, es decir cada polygon es tratado de manera individual y solo se activaran las animaciones si nos posicionamos sobre uno de ellos. En Safari ni tan siquiera veremos los polígonos. Así que llegados a este punto si queremos conservar la animación deberemos declararla dentro de cada una de las etiquetas use
o si optamos por declarar los polygon
por separado pues dentro de su etiqueta correspondiente.
Aquí dejo el código por si alguien encuentra una solución, quizás este haciendo algo mal y si que se puede hacer : D!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<svg class="svgfondo" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="100%" height="100%"
viewBox="0 0 2000 800"
enable-background="new 0 0 2000 800"
xml:space="preserve">
<polygon id="animacion"
fill="#000" points="948.742,46.109 923.149,90.439 897.556,46.109">
<animate attributeName="fill" dur="8s"
values="#121;#EEBE0F" repeatCount="1"
begin="4s" fill="remove" />
<animate attributeName="fill" dur="5s"
values="#056158" repeatCount="1"
begin="mouseover" />
<animateTransform attributeName="transform"
type="rotate" from="0 32 32" to="-360 32 32"
dur="15s" repeatDur="5" begin="mouseover" />
</polygon>
<g>
<use xlink:href="#animacion" x="100" y="60" />
</g>
<use xlink:href="#animacion" x="110" y="105" />
<use xlink:href="#animacion" x="150" y="105" />
<use xlink:href="#animacion" x="200" y="105" />
<use xlink:href="#animacion" x="250" y="105" />
<use xlink:href="#animacion" x="300" y="105" />
<polygon fill="#000"
points="974.337,90.439 948.742,134.77 923.149,90.439 ">
<animate attributeName="fill" dur="8s"
values="#121;#EEBE0F" repeatCount="1"
begin="4s" fill="freeze" />
<animate attributeName="fill" dur="5s"
values="#056158" repeatCount="1" begin="mouseover" />
<animateTransform attributeName="transform"
type="rotate" from="0 32 32" to="-360 32 32"
dur="15s" repeatDur="5" begin="mouseover" />
</polygon>
</svg>
Aquí un vídeo donde se ve lo que hace cada navegador, el orden de aparición es: Opera, Firefox, Chrome y Safari.
Parece ser que es un error de los navegadores que llevan webkit, aquí una entrada de stackoverflow hablando sobre los animate en Chrome.
http://stackoverflow.com/questions/13530894/chrome-svg-animate-tag
Y el post de bugs.webkit
https://bugs.webkit.org/show_bug.cgi?id=21371
Y de regalo otro SVG(creado en 2003) que tan solo funciona en Firefox.
SCALABLE, un libro sobre SVGA lo largo de 15 capítulos, 120 páginas y más de 70 ejemplos vamos a ver todo lo que podemos hacer con SVG. Tu pones el precio, disponible desde 0$ para descargar desde LeanPub(PDF, ePUB y MOBI).