3D龙卷风旋转特效

  1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2  
  3   <embed src="D:\音乐\G.E.M.邓紫棋 - 龙卷风.mp3 " width="0" height="0" type="audio/mpeg loop="ture" autostart="ture" volume="0" .></EMBED>
  4 <HTML>
  5 <HEAD>
  6     <TITLE> New Document </TITLE>
  7     <META NAME="Generator" CONTENT="EditPlus">
  8     <META NAME="Author" CONTENT="">
  9     <META NAME="Keywords" CONTENT="">
 10     <META NAME="Description" CONTENT="">
 11     <style>
 12         html, body {
 13             margin: 0px;
 14             width: 100%;
 15             height: 100%;
 16             overflow: hidden;
 17             background: #000;
 18         }
 19 
 20         #canvas {
 21             position: absolute;
 22             width: 100%;
 23             height: 100%;
 24         }
 25     </style>
 26 </HEAD>
 27 
 28 <BODY>
 29     <canvas id="canvas"></canvas>
 30     <script>
 31         function project3D(x, y, z, vars) {
 32 
 33             var p, d;
 34             x -= vars.camX;
 35             y -= vars.camY - 8;
 36             z -= vars.camZ;
 37             p = Math.atan2(x, z);
 38             d = Math.sqrt(x * x + z * z);
 39             x = Math.sin(p - vars.yaw) * d;
 40             z = Math.cos(p - vars.yaw) * d;
 41             p = Math.atan2(y, z);
 42             d = Math.sqrt(y * y + z * z);
 43             y = Math.sin(p - vars.pitch) * d;
 44             z = Math.cos(p - vars.pitch) * d;
 45             var rx1 = -1000;
 46             var ry1 = 1;
 47             var rx2 = 1000;
 48             var ry2 = 1;
 49             var rx3 = 0;
 50             var ry3 = 0;
 51             var rx4 = x;
 52             var ry4 = z;
 53             var uc = (ry4 - ry3) * (rx2 - rx1) - (rx4 - rx3) * (ry2 - ry1);
 54             var ua = ((rx4 - rx3) * (ry1 - ry3) - (ry4 - ry3) * (rx1 - rx3)) / uc;
 55             var ub = ((rx2 - rx1) * (ry1 - ry3) - (ry2 - ry1) * (rx1 - rx3)) / uc;
 56             if (!z) z = 0.000000001;
 57             if (ua > 0 && ua < 1 && ub > 0 && ub < 1) {
 58                 return {
 59                     x: vars.cx + (rx1 + ua * (rx2 - rx1)) * vars.scale,
 60                     y: vars.cy + y / z * vars.scale,
 61                     d: (x * x + y * y + z * z)
 62                 };
 63             } else {
 64                 return { d: -1 };
 65             }
 66         }
 67 
 68 
 69         function elevation(x, y, z) {
 70 
 71             var dist = Math.sqrt(x * x + y * y + z * z);
 72             if (dist && z / dist >= -1 && z / dist <= 1) return Math.acos(z / dist);
 73             return 0.00000001;
 74         }
 75 
 76 
 77         function rgb(col) {
 78 
 79             col += 0.000001;
 80             var r = parseInt((0.5 + Math.sin(col) * 0.5) * 16);
 81             var g = parseInt((0.5 + Math.cos(col) * 0.5) * 16);
 82             var b = parseInt((0.5 - Math.sin(col) * 0.5) * 16);
 83             return "#" + r.toString(16) + g.toString(16) + b.toString(16);
 84         }
 85 
 86 
 87         function interpolateColors(RGB1, RGB2, degree) {
 88 
 89             var w2 = degree;
 90             var w1 = 1 - w2;
 91             return [w1 * RGB1[0] + w2 * RGB2[0], w1 * RGB1[1] + w2 * RGB2[1], w1 * RGB1[2] + w2 * RGB2[2]];
 92         }
 93 
 94 
 95         function rgbArray(col) {
 96 
 97             col += 0.000001;
 98             var r = parseInt((0.5 + Math.sin(col) * 0.5) * 256);
 99             var g = parseInt((0.5 + Math.cos(col) * 0.5) * 256);
100             var b = parseInt((0.5 - Math.sin(col) * 0.5) * 256);
101             return [r, g, b];
102         }
103 
104 
105         function colorString(arr) {
106 
107             var r = parseInt(arr[0]);
108             var g = parseInt(arr[1]);
109             var b = parseInt(arr[2]);
110             return "#" + ("0" + r.toString(16)).slice(-2) + ("0" + g.toString(16)).slice(-2) + ("0" + b.toString(16)).slice(-2);
111         }
112 
113 
114         function process(vars) {
115 
116 
117             if (vars.points.length < vars.initParticles) for (var i = 0; i < 5; ++i) spawnParticle(vars);
118             var p, d, t;
119 
120             p = Math.atan2(vars.camX, vars.camZ);
121             d = Math.sqrt(vars.camX * vars.camX + vars.camZ * vars.camZ);
122             d -= Math.sin(vars.frameNo / 80) / 25;
123             t = Math.cos(vars.frameNo / 300) / 165;
124             vars.camX = Math.sin(p + t) * d;
125             vars.camZ = Math.cos(p + t) * d;
126             vars.camY = -Math.sin(vars.frameNo / 220) * 15;
127             vars.yaw = Math.PI + p + t;
128             vars.pitch = elevation(vars.camX, vars.camZ, vars.camY) - Math.PI / 2;
129 
130             var t;
131             for (var i = 0; i < vars.points.length; ++i) {
132 
133                 x = vars.points[i].x;
134                 y = vars.points[i].y;
135                 z = vars.points[i].z;
136                 d = Math.sqrt(x * x + z * z) / 1.0075;
137                 t = .1 / (1 + d * d / 5);
138                 p = Math.atan2(x, z) + t;
139                 vars.points[i].x = Math.sin(p) * d;
140                 vars.points[i].z = Math.cos(p) * d;
141                 vars.points[i].y += vars.points[i].vy * t * ((Math.sqrt(vars.distributionRadius) - d) * 2);
142                 if (vars.points[i].y > vars.vortexHeight / 2 || d < .25) {
143                     vars.points.splice(i, 1);
144                     spawnParticle(vars);
145                 }
146             }
147         }
148 
149         function drawFloor(vars) {
150 
151             var x, y, z, d, point, a;
152             for (var i = -25; i <= 25; i += 1) {
153                 for (var j = -25; j <= 25; j += 1) {
154                     x = i * 2;
155                     z = j * 2;
156                     y = vars.floor;
157                     d = Math.sqrt(x * x + z * z);
158                     point = project3D(x, y - d * d / 85, z, vars);
159                     if (point.d != -1) {
160                         size = 1 + 15000 / (1 + point.d);
161                         a = 0.15 - Math.pow(d / 50, 4) * 0.15;
162                         if (a > 0) {
163                             vars.ctx.fillStyle = colorString(interpolateColors(rgbArray(d / 26 - vars.frameNo / 40), [0, 128, 32], .5 + Math.sin(d / 6 - vars.frameNo / 8) / 2));
164                             vars.ctx.globalAlpha = a;
165                             vars.ctx.fillRect(point.x - size / 2, point.y - size / 2, size, size);
166                         }
167                     }
168                 }
169             }
170             vars.ctx.fillStyle = "#82f";
171             for (var i = -25; i <= 25; i += 1) {
172                 for (var j = -25; j <= 25; j += 1) {
173                     x = i * 2;
174                     z = j * 2;
175                     y = -vars.floor;
176                     d = Math.sqrt(x * x + z * z);
177                     point = project3D(x, y + d * d / 85, z, vars);
178                     if (point.d != -1) {
179                         size = 1 + 15000 / (1 + point.d);
180                         a = 0.15 - Math.pow(d / 50, 4) * 0.15;
181                         if (a > 0) {
182                             vars.ctx.fillStyle = colorString(interpolateColors(rgbArray(-d / 26 - vars.frameNo / 40), [32, 0, 128], .5 + Math.sin(-d / 6 - vars.frameNo / 8) / 2));
183                             vars.ctx.globalAlpha = a;
184                             vars.ctx.fillRect(point.x - size / 2, point.y - size / 2, size, size);
185                         }
186                     }
187                 }
188             }
189         }
190 
191         function sortFunction(a, b) {
192             return b.dist - a.dist;
193         }
194 
195         function draw(vars) {
196 
197             vars.ctx.globalAlpha = .15;
198             vars.ctx.fillStyle = "#000";
199             vars.ctx.fillRect(0, 0, canvas.width, canvas.height);
200 
201             drawFloor(vars);
202 
203             var point, x, y, z, a;
204             for (var i = 0; i < vars.points.length; ++i) {
205                 x = vars.points[i].x;
206                 y = vars.points[i].y;
207                 z = vars.points[i].z;
208                 point = project3D(x, y, z, vars);
209                 if (point.d != -1) {
210                     vars.points[i].dist = point.d;
211                     size = 1 + vars.points[i].radius / (1 + point.d);
212                     d = Math.abs(vars.points[i].y);
213                     a = .8 - Math.pow(d / (vars.vortexHeight / 2), 1000) * .8;
214                     vars.ctx.globalAlpha = a >= 0 && a <= 1 ? a : 0;
215                     vars.ctx.fillStyle = rgb(vars.points[i].color);
216                     if (point.x > -1 && point.x < vars.canvas.width && point.y > -1 && point.y < vars.canvas.height) vars.ctx.fillRect(point.x - size / 2, point.y - size / 2, size, size);
217                 }
218             }
219             vars.points.sort(sortFunction);
220         }
221 
222 
223         function spawnParticle(vars) {
224 
225             var p, ls;
226             pt = {};
227             p = Math.PI * 2 * Math.random();
228             ls = Math.sqrt(Math.random() * vars.distributionRadius);
229             pt.x = Math.sin(p) * ls;
230             pt.y = -vars.vortexHeight / 2;
231             pt.vy = vars.initV / 20 + Math.random() * vars.initV;
232             pt.z = Math.cos(p) * ls;
233             pt.radius = 200 + 800 * Math.random();
234             pt.color = pt.radius / 1000 + vars.frameNo / 250;
235             vars.points.push(pt);
236         }
237 
238         function frame(vars) {
239 
240             if (vars === undefined) {
241                 var vars = {};
242                 vars.canvas = document.querySelector("canvas");
243                 vars.ctx = vars.canvas.getContext("2d");
244                 vars.canvas.width = document.body.clientWidth;
245                 vars.canvas.height = document.body.clientHeight;
246                 window.addEventListener("resize", function () {
247                     vars.canvas.width = document.body.clientWidth;
248                     vars.canvas.height = document.body.clientHeight;
249                     vars.cx = vars.canvas.width / 2;
250                     vars.cy = vars.canvas.height / 2;
251                 }, true);
252                 vars.frameNo = 0;
253 
254                 vars.camX = 0;
255                 vars.camY = 0;
256                 vars.camZ = -14;
257                 vars.pitch = elevation(vars.camX, vars.camZ, vars.camY) - Math.PI / 2;
258                 vars.yaw = 0;
259                 vars.cx = vars.canvas.width / 2;
260                 vars.cy = vars.canvas.height / 2;
261                 vars.bounding = 10;
262                 vars.scale = 500;
263                 vars.floor = 26.5;
264 
265                 vars.points = [];
266                 vars.initParticles = 2000;
267                 vars.initV = .01;
268                 vars.distributionRadius = 800;
269                 vars.vortexHeight = 25;
270             }
271 
272             vars.frameNo++;
273             requestAnimationFrame(function () {
274                 frame(vars);
275             });
276 
277             process(vars);
278             draw(vars);
279         }
280         frame();
281 
282     </script>
283 </BODY>
284 </HTML>
posted @ 2020-01-08 19:58  一斜星辰酱  阅读(346)  评论(0编辑  收藏  举报