2015-11-19 58 views
0

我想变形/动画svg路径数据没有SMIL或库(jQuery的,Snap.svg,Velocity.js等),只是纯粹的JavaScript(和可选的与CSS如果可能的话)。我想这样做是因为Chrome弃用了SMIL,并且他们建议使用CSS或“Web动画”进行动画制作 - 它们对于网页动画是什么意思 - 。比如我想在下面的代码变身ID为“Rect1的”以ID为“RECT2”路径路径:Javascript-morph/animate svg路径数据没有SMIL或库

<!DOCTYPE html> 
 
<html> 
 
\t <head> 
 
\t \t <meta charset="UTF-8"> 
 
\t \t <title>morph/animate svg path data WITHOUT SMIL or libraries (jquery, Snap.svg, Velocity.js etc.), just pure javascript</title> 
 
</head> 
 
<body> 
 

 
<svg 
 
\t xmlns="http://www.w3.org/2000/svg" 
 
\t xmlns:xlink="http://www.w3.org/1999/xlink" 
 
\t version="1.1" 
 
\t width="500px" height="500px" 
 
\t viewBox="0 0 500 500" 
 
\t > 
 
<g id="layer1"> 
 
    <path id="rect1" d="m25 7.3 61 12-6 57-71 6z" stroke="#f00" stroke-miterlimit="10" stroke-width="2" fill="none"/> 
 
</g> 
 
<g id="layer2"> 
 
    <path id="rect2" d="m9.3 34 59-27 26 41-54 42z" stroke="#f00" stroke-miterlimit="10" stroke-width="2" fill="none"/> 
 
</g> 
 
</svg> 
 

 
<script> 
 

 
\t // code for animating/morphing path with id "rect1" to path with id "rect 2" 
 

 
</script> 
 

 
</body> 
 

 
</html>

+0

的可能的复制[如何不使用SMIL动画路径形状?](http://stackoverflow.com/questions/33420323/how-to-animate-path-shape-without-using-smil) – Kaiido

+0

and [to quote](http://stackoverflow.com/questions/33420323/how-to-animate-path-shape-without-使用smil/33428336#comment-54649080)Robert Longson在这个愚蠢的问题上说:“SMIL拥有很棒的浏览器支持,通过https://leunen.me/fakesmile它可以处理任何支持SVG和javascript的东西,无论Chrome不赞成或不赞同。Chrome实际上有一个不同的非本地SMIL插件:https://github.com/ericwillige rs/svg-animation可用,所以有很多理由坚持使用SMIL“ – Kaiido

回答

1

要只使用JavaScript的动画路径数据,我建议缓存两条路径的原始路径数据。然后使用计时器来逐步完成动画过程。在每一步中,计算从开始路径数据到结束路径数据平滑移动的当前路径数据。

下面的代码等待1秒钟,然后运行2第二动画...

<script> 

(function() { 

    var path1; 
    var path2; 
    var startPoints; 
    var endPoints; 
    var currentStep = 0; 
    var maximumSteps = 100; 
    var timeBeforeFirstStep = 1000; 
    var timeBetweenSteps = 20; 

    function animatePath() { 
     if (currentStep < maximumSteps) { 
      currentStep = currentStep + 1; 
      for (var i = 0; i < path1.pathSegList.numberOfItems; i++) { 
       var item = path1.pathSegList.getItem(i); 
       if (item.pathSegType === SVGPathSeg.PATHSEG_MOVETO_REL || item.pathSegType === SVGPathSeg.PATHSEG_LINETO_REL) { 
        if (startPoints[i] && endPoints[i]) { 
         item.x = startPoints[i].x + (endPoints[i].x - startPoints[i].x) * (currentStep/maximumSteps); 
         item.y = startPoints[i].y + (endPoints[i].y - startPoints[i].y) * (currentStep/maximumSteps); 
        } 
       } 
      } 
      setTimeout(animatePath, timeBetweenSteps); 
     } 
    } 

    function window_load() { 
     path1 = document.getElementById("rect1"); 
     path2 = document.getElementById("rect2"); 
     startPoints = []; 
     for (var i = 0; i < path1.pathSegList.numberOfItems; i++) { 
      var item = path1.pathSegList.getItem(i); 
      if (item.pathSegType === SVGPathSeg.PATHSEG_MOVETO_REL || item.pathSegType === SVGPathSeg.PATHSEG_LINETO_REL) { 
       startPoints.push({"x": item.x, "y": item.y}); 
      } 
      else { 
       startPoints.push(null); 
      } 
     } 
     endPoints = []; 
     for (var i = 0; i < path2.pathSegList.numberOfItems; i++) { 
      var item = path2.pathSegList.getItem(i); 
      if (item.pathSegType === SVGPathSeg.PATHSEG_MOVETO_REL || item.pathSegType === SVGPathSeg.PATHSEG_LINETO_REL) { 
       endPoints.push({"x": item.x, "y": item.y}); 
      } 
      else { 
       endPoints.push(null); 
      } 
     } 
     setTimeout(animatePath, timeBeforeFirstStep); 
    } 

    window.addEventListener("load", window_load); 

}()); 

</script>