2010-06-08 27 views
5

Tengo un archivo SVG creado en Inkscape incrustado en una página web, y me gustaría rotarlo lentamente. He intentado usar Javascript e insertar comandos de animación directamente en el SVG, pero nada funciona. No quiero cargar en una biblioteca JS completa para esta tarea. Esto es lo que tengo hasta ahora:Animación del elemento SVG giratorio en la página web

<html> 
    <body bgcolor="#333333"> 
     <embed src="gear.svg" id="gear" width="1000" height="1000" style="position: absolute; top: -500px; left: -500px;" /> 
     <script type="text/javascript"> 
      var gear = document.getElementById("gear"); 
      window.setInterval(function() { 
       // Somehow animate the gear. 
      }, 10); 
     </script> 
    </body> 
</html> 

Respuesta

7

Tema interesante porque AFAIK actualmente Firefox no es compatible con la animación en SVG.
Así que hice una pequeña investigación y encontré una solución de trabajo. Probado en Firefox 3.6, IE7 con Adobe plug-in, Opera 10.51, Safari 4.0.5, Chrome 5.0.
El fondo del área SVG no tiene transparencia en IE7, Safari y Chrome ... Podría probar con el objeto etiqueta (no es compatible con IE, probablemente necesite un poco de HTML condicional ...).

[EDIT] OK, he cambiado a utilizar la más estándar objeto ( incrustar nunca se han definido en HTML ...) a excepción de IE en los que no está bien soportado por Adobe SVG plugin. Este último permite agregar un atributo para tener transparencia del objeto embed. Para navegadores basados ​​en Webkit, sin transparencia: consulte el error object embedded in HTML: default background should be transparent.

El código HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
         "http://www.w3.org/TR/html4/strict.dtd"> 
<html lang="en"> 
    <head> 
     <title>Animating SVG</title> 
    </head> 
    <body bgcolor="#CCAAFF" onload="RotateSVG()"> 
     <!--[if !IE]> --> 
     <object id="gear" data="gear.svg" type="image/svg+xml" 
       width="500" height="500" 
       style="position: absolute; top: -250px; left: -250px;"> 
     <!--<![endif]--> 
      <embed id="gear" src="gear.svg" type="image/svg+xml" 
        width="500" height="500" wmode="transparent" 
        style="position: absolute; top: -250px; left: -250px;"/> 
     <!--[if !IE]> --> 
     </object> 
     <!--<![endif]--> 

     <div onclick="RotateSVG()" 
       style="position: absolute; top: 250px; background-color: #ACF;">Start/Stop</p> 

     <script type="text/javascript"> 
var animator; 
var angle = 0; 
function RotateSVG() 
{ 
    if (animator != null) 
    { 
     // Just stop 
     clearInterval(animator); 
     animator = null; 
     return; 
    } 

    var svgTag = document.getElementById("gear"); 
    var svgDoc = null; 
    try 
    { 
     // Most modern browsers understand this 
     svgDoc = svgTag.getSVGDocument(); 
    } 
    catch (ex) {} // Ignore error 
    if (svgDoc == undefined) 
    { 
     svgDoc = svgTag.contentDocument; // For old Mozilla? 
     if (svgDoc == undefined) 
     { 
      alert("Cannot get SVG document"); 
      return; 
     } 
    } 

    var gear = svgDoc.getElementById("gearG"); 
    if (gear == null) 
    { 
     alert("Cannot find gearG group"); 
     return; 
    } 

    animator = setInterval(
     function() 
     { 
      angle += 5; 
      gear.setAttribute("transform", "rotate(" + angle + " 250 250)"); 
     }, 100); 
} 
     </script> 
    </body> 
</html> 

El código SVG utilicé (sólo el ID es importante, el SVG es de Mozilla SVG Project):

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    version="1.1" 
    baseProfile="full"> 
<!-- http://www.mozilla.org/projects/svg/ --> 
    <g id="gearG" fill-opacity="0.7" stroke="black" stroke-width="0.1cm"> 
    <circle cx="6cm" cy="2cm" r="100" fill="red" 
        transform="translate(0,50)" /> 
    <circle cx="6cm" cy="2cm" r="100" fill="blue" 
        transform="translate(70,150)" /> 
    <circle cx="6cm" cy="2cm" r="100" fill="green" 
        transform="translate(-70,150)" /> 
    </g> 
</svg> 
8
  • Añadir un elemento <g> dentro de su elemento <svg> que envuelve todo dentro de la <svg>, y añadir <animateTransform type="rotate" attributeName="transform" values="0 cx cy;360 cx cy" dur="30s"/> como un hijo de ese elemento <g>, y reemplazar "cx" y " cy "con cualquier punto real real que desee usar como centro de rotación, p. ej." 100 300 ". Debería funcionar en la última generación de navegadores web, aparte de IE9.
  • Anima la rotación utilizando las transformaciones CSS3 2d, teniendo en cuenta que deberás usar al menos tres prefijos de proveedor diferentes en el proceso (-webkit-transform, -moz-transform, -o-transform). Debería funcionar en la última generación de navegadores web, sin embargo, no está seguro acerca de IE9.
  • Añadir un elemento <g> dentro de su elemento <svg> que envuelve todo dentro de la <svg> y luego añadir un <script> en su interior que hace yourGelement.setAttribute("transform", "rotate(" + (newRotation++) + " cx cy)") de un temporizador window.setInterval, como antes reemplazar el CX y CY con su centro de rotación. Esta solución debe tener menos de 10 líneas de código, y debería funcionar bien incluso en implementaciones antiguas que no admiten animaciones declarativas (SMIL) (por ejemplo, IE9, Firefox2, Safari3).
+1

Bueno, la respuesta completa, que era más rápido que yo ! :-) ¿FF3 es compatible con la animación de Smil ahora? No lo he intentado todavía – PhiLho

+0

El Firefox 3.7 alpha I ha admitido al menos partes de él: http://blog.dholbert.org/2009/10/smil-enabled-by-default-on-nightly.html. No dude en probarlo usted mismo contra el w3c svg testsuite, http://dev.w3.org/SVG/profiles/1.1F2/test/harness/ –

Cuestiones relacionadas