大學時候,有一段時間對flash比較感興趣。去圖書館借了一本很厚很厚的falsh書籍。
翻了幾頁之后,就再沒有往后看過。印象比較深的是作者說他用flash完成了一個龍卷風效果。
一直到現在我也沒有看到那個效果。
我也曾經想過實現一下。但是大學時候的技術水平,也支撐不起這個想法。慢慢就忘記了。
偶爾間我看到了離心運動。突然就想到一個寫法。
演示地址如下:
http://suohb.com/work/wind2.htm
最終效果圖如下:
龍卷風,我們可以看做一個向上旋轉的氣流。
風本身是不可見的,我們就用某個質點的移動軌跡畫出來,表示風。
從上向下俯視,就是這樣,一個質點做離心運動的路徑。
從側面看,是這樣在,一個質點繞Y軸左右搖擺,擺動越來越大的的運動的路徑。
我們就用這個來做為側視圖的效果,來做一個2D的龍卷風。
那么開始代碼設計:
我們定義一個點,這個點Y軸上恆定速率運動,X軸上,向這中線方向有一個向心力G。一旦點運動超過這條中線,向心力倒轉為-G。
這樣就會畫出上面側視圖的效果。
然后每個周期都新增一些這樣的點,畫出軌跡。如圖;
基本上這樣就已經完成了,我們不需要畫出完整的路徑,只要畫出最新的一段就可以。
當到達一定高度之后,就將這條線慢慢移除出去。就得到最終效果
代碼如下:
1 <!doctype html> 2 <html> 3 <head> 4 <meta http-equiv="Pragma" content="no-cache" /> 5 <meta http-equiv="Cache-Control" content="no-cache" /> 6 <meta http-equiv="Expires" content="0" /> 7 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> 8 <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" /> 9 <style type="text/css"> 10 html{ 11 height: 100%; 12 } 13 html,body,ul,li,canvas{ 14 margin: 0; 15 padding: 0; 16 } 17 </style> 18 </head> 19 <body bgcolor="#000000"> 20 <canvas id="knife"></canvas> 21 </body> 22 <script> 23 var canvas = document.getElementById("knife"); 24 canvas.style.position = "absolute" ; 25 canvas.style.top = 0 ; 26 var w = window.innerWidth ; 27 var h = window.innerHeight ; 28 canvas.width = w ; 29 canvas.height = h ; 30 var cxt = canvas.getContext("2d"); 31 cxt.strokeStyle = "#FFF" ; 32 var list = []; 33 var G = 0.4 ;//向心加速度 34 var SPEED_Y = -1 ;//向上速度 35 var centerLine = w/2 ;//龍卷風中線 36 function addLine(){ 37 var LEN = 2 ; 38 for(var i = 0 ;i < LEN ; i ++){ 39 list.push({ 40 x:w/2, 41 y:h/1.3, 42 g:G, 43 c:centerLine+2*Math.random(), 44 sx:(Math.random()-0.5)*4, 45 sy:SPEED_Y+0.5*(Math.random()-0.5), 46 len:Math.round(Math.random()*10+5), 47 list:[{x:w/2,y:h/1.3}] 48 }); 49 } 50 } 51 function step(){ 52 cxt.clearRect(0,0,w,h); 53 addLine(); 54 var obj ; 55 for(var i = 0 ; i < list.length; i ++){ 56 obj = list[i] ; 57 if(obj.y < h/2.5){//如果超過這個高度,就刪除一個點 58 obj.len -- ; 59 if(obj.len == 0){ 60 list.splice(i,1); 61 i -- ; 62 continue ; 63 } 64 } 65 obj.x += obj.sx ; 66 obj.y += obj.sy ; 67 obj.sx += obj.g ; 68 obj.g = obj.x > obj.c ? -G : G ; 69 obj.list.unshift({x:obj.x,y:obj.y});//記錄下質點運動軌跡 70 obj.list = obj.list.slice(0,obj.len);//僅僅畫出其中一段線就好 71 //畫出所有點的連線 72 cxt.beginPath(); 73 cxt.moveTo(obj.list[0].x,obj.list[0].y); 74 for(var j = 1 ; j < obj.list.length; j ++){ 75 cxt.lineTo(obj.list[j].x,obj.list[j].y); 76 77 } 78 cxt.stroke(); 79 } 80 requestAnimationFrame(step); 81 } 82 requestAnimationFrame(step); 83 </script> 84 </html>
更多特效請關注公眾號: