用于svg时setTimeout不起作用

时间:2016-10-27 10:27:08

标签: javascript svg

我希望在3秒后移动一个圆圈。我正在使用JS动态绘制一个圆圈并将其移动并使用setTimeout进行时间延迟。当我加载页面时,圆圈在3秒后出现,但同时在线上行进了一段距离(它应该从行的开头开始,即(30,y1))。我无法弄清楚我哪里出错了。 这里有相关的代码:

train.js

    function RunTrain(x,y,desti,time,r)
     {
        var xmlns="http://www.w3.org/2000/svg";
        var C=document.createElementNS(xmlns,"circle");
        C.setAttributeNS(null,"cx",x);
        C.setAttributeNS(null,"cy",y);
        C.setAttributeNS(null,"r",r);
        C.setAttribute("style","stroke-width:1;stroke:blue;fill:skyblue");

        var animate=document.createElementNS(xmlns,"animate");
        animate.setAttribute("attributeName","cx");
        animate.setAttribute("attributeType","XML");
        animate.setAttribute("from",x);
        animate.setAttribute("to",desti);
        animate.setAttribute("dur","2s");
        animate.setAttribute("begin","0s");
        animate.setAttribute("repeatCount","1");
        animate.setAttribute("fill","freeze");

        C.appendChild(animate);
        document.getElementById("id1").appendChild(C);
        //id1 is the id of svg tag
     }

call.js

setTimeout(function(){ RunTrain(30,y1,Mlx2,5,10); },3000);

demo.html

<svg height = 5000 width = 5000 id="id1">  </svg>   
<script src="/static/train.js"></script>
<script src="/static/call.js"></script>

注意:它是django项目的一部分。我正在使用mozilla。

修改
即使在调用beginElement上,这个animateTransform也会造成麻烦。

 var animateTransform=document.createElementNS(xmlns,"animateTransform");
    animateTransform.setAttribute("attributeName","transform");
    animateTransform.setAttribute("attributeType","scale");
    animateTransform.setAttribute("dur","2s");
    animateTransform.setAttribute("begin","3s");
    animateTransform.setAttribute("from","0 0");
    animateTransform.setAttribute("to","160 "+ y1);
    animateTransform.setAttribute("fill","freeze");

2 个答案:

答案 0 :(得分:1)

创建SVG文档时,SMIL动画的动画计时器开始计时。因此,如果您说begin="0s"这意味着动画应该在首次创建文档时启动。在您的情况下,即将<svg>添加到DOM时。不是在三秒钟后添加<circle><animate>元素时。所以动画开始就像你已经跑了三秒钟一样。

对代码的最简单修复是设置begin="indefinite"并在添加元素后开始运行动画。你可以通过致电beginElement()来做到这一点。请参阅下面的演示。

function RunTrain(x,y,desti,time,r)
{
    var xmlns="http://www.w3.org/2000/svg";
    var C=document.createElementNS(xmlns,"circle");
    C.setAttributeNS(null,"cx",x);
    C.setAttributeNS(null,"cy",y);
    C.setAttributeNS(null,"r",r);
    C.setAttribute("style","stroke-width:1;stroke:blue;fill:skyblue");

    var animate=document.createElementNS(xmlns,"animate");
    animate.setAttribute("attributeName","cx");
    animate.setAttribute("attributeType","XML");
    animate.setAttribute("from",x);
    animate.setAttribute("to",desti);
    animate.setAttribute("dur",time);
    animate.setAttribute("begin","indefinite");
    animate.setAttribute("repeatCount","1");
    animate.setAttribute("fill","freeze");

    C.appendChild(animate);
    document.getElementById("id1").appendChild(C);
    //id1 is the id of svg tag
  
    animate.beginElement();
}

var y1 = 30;
var Mlx2 = 400;

setTimeout(function(){ RunTrain(30,y1,Mlx2,5,10); },3000);
<svg height="5000" width="5000" id="id1"></svg>

答案 1 :(得分:0)

您需要先调用您的函数,然后再在setTimeout中再次调用它。像这样的东西会起作用:

RunTrain(<initial args>)
setInterval(() => RunTrain(<args for future>), 3000)