先上效果图:
这只是SVG+JS驱动的动画的惊鸿一瞥,这里用到的技术,只是其皮毛。三次以上的贝塞尔曲线,更加复杂的函数控制SVG路径……路总要一步一步走,先总结一下当前实现的效果吧!html
功能:随意指定高度和宽度(在SVG path
的d
属性中填写相关参数),波浪的高度会在高度和-高度之间来会变更,时间控制使用了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