Анимировать вращающийся элемент SVG на веб-странице - PullRequest
6 голосов
/ 08 июня 2010

Итак, у меня есть файл SVG, созданный в Inkscape, встроенный в веб-страницу, и я бы хотел, чтобы он медленно вращался. Я пытался использовать Javascript и вставлять команды анимации непосредственно в SVG, но ничего не работает. Я не хочу загружать всю библиотеку JS для этой задачи. Это то, что я до сих пор:

<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>

Ответы [ 2 ]

8 голосов
/ 08 июня 2010

Интересная тема, потому что AFAIK в настоящее время Firefox не поддерживает анимацию в SVG.
Поэтому я провел небольшое расследование и нашел рабочее решение. Протестировано в Firefox 3.6, IE7 с плагином Adobe, Opera 10.51, Safari 4.0.5, Chrome 5.0.
Фон области SVG не имеет прозрачности в IE7, Safari и Chrome ... Я мог бы попробовать с тегом object (не поддерживается IE, возможно, нужен некоторый условный HTML ...).

[РЕДАКТИРОВАТЬ] ОК, я изменил использование более стандартного объекта ( embed никогда не определялся в HTML ...) за исключением IE, где он не поддерживается плагином Adobe SVG. Последний позволяет добавить атрибут, чтобы иметь прозрачность объекта embed . Для браузеров на основе Webkit нет прозрачности: см. объект, встроенный в HTML: фон по умолчанию должен быть прозрачным ошибка.

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>

Код SVG, который я использовал (важен только идентификатор, SVG из 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 голосов
/ 08 июня 2010
  • Добавьте элемент <g> внутри элемента <svg>, который оборачивает все внутри элемента <svg>, и добавьте <animateTransform type="rotate" attributeName="transform" values="0 cx cy;360 cx cy" dur="30s"/> как дочерний элемент этого элемента <g> и замените "cx" и "cy" на все, что угодно Фактическая абсолютная точка, которую вы хотите использовать в качестве центра вращения, например, «100 300». Должен работать в новейшем поколении веб-браузеров, кроме IE9.
  • Анимируйте вращение с помощью CSS3 2d-преобразований, отметив, что в процессе вам придется использовать как минимум три разных префикса вендора (-webkit-transform, -moz-transform, -o-transform). Должен работать в новейшем поколении веб-браузеров, хотя не уверен насчет IE9.
  • Добавьте элемент <g> внутри элемента <svg>, который оборачивает все внутри <svg>, а затем добавьте <script> внутри него, который yourGelement.setAttribute("transform", "rotate(" + (newRotation++) + " cx cy)") из таймера window.setInterval, как и прежде, замените cx и Cy с вашим центром вращения. Это решение должно содержать менее 10 строк кода и должно работать нормально даже в старых реализациях, которые не поддерживают декларативную (SMIL) анимацию (например, IE9, Firefox2, Safari3).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...