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