大学时候,有一段时间对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>

 

更多特效请关注公众号: