2015-11-19 24 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>