SVG+JS驅動的波浪動畫

先上效果圖:
這只是SVG+JS驅動的動畫的驚鴻一瞥,這裏用到的技術,只是其皮毛。三次以上的貝塞爾曲線,更加複雜的函數控制SVG路徑……路總要一步一步走,先總結一下當前實現的效果吧!html

功能:隨意指定高度和寬度(在SVG pathd屬性中填寫相關參數),波浪的高度會在高度和-高度之間來會變更,時間控制使用了setInterval,所以能夠指定動畫速度。segmentfault

圖片描述

<html>
 <head>
 </head>
<body>

<svg style="width:100%;height:250px;margin:0;padding:0;">
//繪製背景方框,大小爲50*6400
<path d="M0 110v50h6400v-50z" stroke="#fff" style="fill:#529BB3;stroke-width:0px;"></path>
//繪製二次貝塞爾曲線,q的控制點爲(50,20),其後跟隨的t會自動對稱該控制點,所以t命令中只要指定結束點便可
<path id="wave1" d="M0 110q50 20,100 0t100 0t100 0t100 0t100 0t100 0t100 0t100 0t100 0t100 0t100 0t100 0t100 0t100 0t100 0" stroke="#fff" style="fill:lightblue;stroke-width:1px;"></path>

</svg>
<script>
(function(){
  //利用正則獲取傳入元素的控制點高度並返回
  var getHeight=function($ele){
    var path=$ele.getAttribute('d');
    var height=parseInt(/q\d{2}\s(\-*\d{1,2})/.exec(path)[1]);
    return height;
  };
  //時間控制主函數
  var myTimer=function(id,callback){
    var $ele=document.querySelector(id);
    //利用前面的函數獲取高度
    var height=getHeight($ele);
    var num=height;
    //高度遞減時flag爲true
    var flag=true;
    setInterval(function(){
      if (flag) {
        height--;
        //若是高度達到最低點,則flag設爲false,高度開始遞增
        if (height <= -num) {flag = false;}
      } else {
        height++;
        if (height >= num) {flag = true;}
      };
      //調用回調函數,改變元素屬性值
      callback($ele,height);
    },50);
  };
  var changeHeight=function($ele,val){
    //利用正則提取元素控制點高度
    var array=$ele.getAttribute('d').split(/(q\d{2}\s)(\-*\d{1,2})/);
    //改變控制點高度
    array[2]=val;
    //給元素寫入改變後的高度
    $ele.setAttribute('d',array.join(''));
  };
  //執行主函數
  myTimer('#wave1',changeHeight);
})();
</script>
 </body>
 </html>

參考資料:
深度掌握SVG路徑path的貝塞爾曲線指令 « 張鑫旭-鑫空間-鑫生活
路徑 - SVG | MDN
如何獲取setInterval中函數的返回值?svg

相關文章
相關標籤/搜索