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>