先上效果圖:
這只是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