【问题标题】:JavaScript appending SVG animations. How to start them up?JavaScript 附加 SVG 动画。如何启动它们?
【发布时间】:2015-11-16 02:15:30
【问题描述】:

我从 this previous question 扩展了我的学习代码,以学习如何使用 JavaScript 附加 SVG 动画。我试过这样:

(我没有包含函数NormSInv()的定义以节省空间。如果需要,它是this answer中的那个)。

      function randomPath(){
      var x = 500;
      var y = 400;
      var xstep = 0;
      var ystep = 0;
      var path = '500,400';
      for (var k = 0; k < 3 ; k++) {
          path += ' ';
          path += (x).toString();
          path += ',';
          path += (y).toString();
          xstep = NormSInv(Math.random());
          ystep = NormSInv(Math.random());
          xstep *= 10;
          ystep *= 10;
          x += Math.trunc(xstep);
          y += Math.trunc(ystep);
        };
        return path;
      };

      window.onload = function() {

    var figure = document.createElementNS('http://www.w3.org/2000/svg','svg');
    figure.id = 'brownian-figure';
    figure.setAttribute('height', '100%');
    figure.setAttribute('width', '100%');

    var pathArray = [];
    for (var i = 0; i < 10; i++){
    pathArray[i] = document.createElementNS('http://www.w3.org/2000/svg','polyline');
    pathArray[i].id = "hair" + (i).toString();
    var path = randomPath();
    pathArray[i].setAttribute('points', path);
    pathArray[i].setAttribute('style', 'fill:none;stroke:rgba(0,0,20,1);stroke-width:1');
    figure.appendChild(pathArray[i]);
    };

    var divfigure = document.createElement('div');
    divfigure.id = 'divfigure';
    divfigure.onclick = moveHair;
    divfigure.style = 'margin:0pt;padding:0pt;border:0pt none;background-color:rgba(240,240,240,0.66);position:absolute;top:0vh;left:0vw;width:50vw;height:99vh;';
    divfigure.appendChild(figure);


    var content = document.getElementById('content-container');
    document.body.insertBefore(divfigure, content);
  };

  function moveHair(){
    var a_hair_number = Math.trunc(10 * Math.random());
    var paths = document.getElementById('brownian-figure').childNodes;
    var hair = paths[a_hair_number];
    var animation = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
    animation.setAttribute('xlink:href', '#hair' + a_hair_number.toString());
    animation.setAttribute('attributeName', 'points');
    animation.setAttribute('dur', '2s');
    animation.setAttribute('repeatCount', 'indefinite');
    animation.setAttribute('from', hair.getAttribute('points'));
    animation.setAttribute('values', hair.getAttribute('points') + '; ' + randomPath() + '; ' + hair.getAttribute('points'));
    animation.setAttribute('to', hair.getAttribute('points'));
    var divfigure = document.getElementById('brownian-figure');
    divfigure.appendChild(animation);
  };

有问题的部分是函数moveHair(),最后。代码运行,并插入带有预期属性的动画。我可以通过使用 FireBug 检查页面来看到它的发生。 但没有任何动静。

我在 FireBug 中看到的 SVG 的一个示例(部分缩短)是

<svg id="brownian-figure" height="100%" width="100%">
  <polyline id="hair3" points="500,400 500,400 521,390 510,374" style="fill:none;stroke:rgba(0,0,20,1);stroke-width:1">
  <animate xlink:href="#hair3" attributeName="points" dur="2s" repeatCount="indefinite" from="500,400 500,400 521,390 510,374" values="500,400 500,400 521,390 510,374; 500,400 500,400 508,419 515,440; 500,400 500,400 521,390 510,374" to="500,400 500,400 521,390 510,374">
</svg>

如果我直接使用这个 SVG 代码,它确实可以工作并且事情会发生变化。

是命名空间的问题吗?起初我用createElement 创建animate,它们在FireBug 检查器中显示为灰色。然后我使用createElementNS 创建它们,并使用与 SVG 及其子节点相同的命名空间。这样做会使animates 在 FireBug 检查器中正确显示。但他们仍然没有采取任何行动。

【问题讨论】:

    标签: javascript animation svg


    【解决方案1】:

    var elem = document.getElementById("elem")
    var anim = document.createElementNS("http://www.w3.org/2000/svg", "animate")
    anim.setAttribute("begin", "indefinite")
    anim.setAttribute("from", 10)
    anim.setAttribute("to", 50)
    anim.setAttribute("fill", "freeze")
    anim.setAttribute("dur", "1s")
    anim.setAttribute("repeatCount", "indefinite")
    anim.setAttribute("attributeName", "r")
    
    elem.appendChild(anim)
    
    
    function startAnim() {
      anim.beginElement()
    }
    <svg viewBox="0 0 100 100" width="200" height="200">
      <circle id="elem" cx="50" cy="50" r="10" fill="orange" />
    </svg>
    
    <button type="button" onclick="startAnim()">start animation</button>

    您没有设置默认为 0s(文档时间)的 begin 属性...简而言之,您可以将 begin 设置为“不确定”并在附加动画后调用 animation.beginElement()。

    【讨论】:

    • 刚刚试了一下。我在appendChild 行之前添加了animation.setAttribute('begin', 'indefinite');,在appendChild 行之后添加了animation.beginElement();。它没有用,虽然你说的听起来很合理。
    • 变量animation 附加到svg 后是否一直指向animate 对象?我要求确保animation.beginElement() 行实际上是在要求开始该特定动画。
    • 我现在尝试输入begin=accessKey(s),这样我就可以尝试通过按“s”来手动触发启动。它也没有工作。
    • 哦...当我将您的moveHair() 签名更改为moveHair(evt) 然后执行 evt.target.appendChild(animation) 所以使用嵌套动画而不是使用 xlink:href 定位您的元素也有效
    • 我现在可以使用它了。非常感谢。 xlink:href 也不适合我。我仍然需要了解原因。我按照您所说的将动画嵌套在折线内使其工作。
    猜你喜欢
    • 1970-01-01
    • 2022-10-19
    • 2021-10-24
    • 1970-01-01
    • 2019-09-28
    • 2018-06-27
    • 2019-06-14
    • 1970-01-01
    相关资源
    最近更新 更多