CANVAS模仿龍卷風特效


大學時候,有一段時間對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>

 

更多特效請關注公眾號:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM