动态地为svg元素设置动画

问题描述 投票:1回答:1

我正在实现一个简单的游戏,玩家将在屏幕中间控制一个红色圆圈。圆圈实现为SVG元素。

我希望能够使用SVG动画(SMIL)在SVG viewBox中的任意两个位置之间移动圆圈。每个动画的触发器是在屏幕上的任意位置左键单击。

我认为written code应该可以在Firefox和Chrome中使用。在Chrome中,它仅适用于第一个动画,而对于所有后续动画,圆圈只是“传送”。在Firefox中没有动画 (并且控制台中没有错误) 。

我的代码中是否存在错误,或者是否存在SMIL过于不成熟的一些常见问题?

我可以让SMIL在这个用例中工作,还是应该使用canvas?

这是我到目前为止的代码:

<!DOCTYPE html>
<html>
  <body>
    <svg id="canvas" width="800" height="800" onclick="Move()">
      <circle id="player1" cx="300" cy="300" r="40" stroke="blue" stroke-width="4" fill="red">
      </circle>
    </svg>
    <script>

      function createAnimation(attribute, playerID, duration, from, to) {
        var animation = document.createElementNS("http://www.w3.org/2000/svg", "animate")
        animation.setAttribute("attributeType", "XML")
        animation.setAttribute("attributeName", attribute)
        animation.setAttribute("dur", duration)
        animation.setAttribute("to", to)
        animation.setAttribute("from", from)
        animation.setAttribute("fill", "freeze")
        animationID = playerID + "animation" + attribute
        animation.setAttribute("id", animationID)
        player = document.getElementById(playerID)
        previous_animation = document.getElementById(animationID)
        if (previous_animation != null) {
          player.removeChild(previous_animation)
        }
        player.appendChild(animation)
      }

      function Move() {
        console.log(event.clientX);
        console.log(event.clientY);
        createAnimation("cx", "player1", "2s", document.getElementById("player1").getAttribute("cx"), event.clientX);
        createAnimation("cy", "player1", "2s", document.getElementById("player1").getAttribute("cy"), event.clientY);
      }

    </script>
  </body>

</html>
javascript animation svg smil
1个回答
3
投票

有很多问题......

  • 除非你从调用者传入一个对象,否则Firefox中没有事件(或更确切地说是evt)对象。此错误确实显示在Firefox浏览器控制台中。
  • Firefox仍然实现SVG 1.1动画,它不会更新属性值,您需要调用animVal来获取值
  • 一旦你动画一次,时间轴现在是2秒,所以下次你在2s的文档中从0到2秒动画动画时,它就会跳到那里。每次在下面的答案中移动时,我将时间线重置为0。

<!DOCTYPE html>
<html>
  <body>
    <svg id="canvas" width="800" height="800" onclick="Move(evt)">
      <circle id="player1" cx="300" cy="300" r="40" stroke="blue" stroke-width="4" fill="red">
      </circle>
    </svg>
    <script>
    
      function createAnimation(attribute, playerID, duration, from, to) {
        var animation = document.createElementNS("http://www.w3.org/2000/svg", "animate")
        animation.setAttribute("attributeType", "XML")
        animation.setAttribute("attributeName", attribute)
        animation.setAttribute("dur", duration)
        animation.setAttribute("to", to)
        animation.setAttribute("from", from)
        animation.setAttribute("fill", "freeze")
        animationID = playerID + "animation" + attribute
        animation.setAttribute("id", animationID)
        player = document.getElementById(playerID)
        previous_animation = document.getElementById(animationID)
        if (previous_animation != null) {
          player.removeChild(previous_animation)
        }
        player.appendChild(animation)
      }

      function Move(evt) {
        console.log(evt.clientX);
        console.log(evt.clientY);
        createAnimation("cx", "player1", "2s", document.getElementById("player1").cx.animVal.value, evt.clientX);
        createAnimation("cy", "player1", "2s", document.getElementById("player1").cy.animVal.value, evt.clientY);
        document.getElementById("canvas").setCurrentTime(0);
      }

    </script>
  </body>

</html>
© www.soinside.com 2019 - 2024. All rights reserved.