SHOW:
|
|
- or go back to the newest paste.
1 | var canvas = document.getElementsByTagName('canvas')[0]; | |
2 | var context = canvas.getContext('2d'); | |
3 | ||
4 | document.body.bgColor = X = Y = H = I = J = E = Q = U = V = 0; | |
5 | T = [l = 1]; | |
6 | C = (canvas.width = canvas.height = innerHeight) / 2; | |
7 | ||
8 | setInterval(function() { | |
9 | for (i = H; i < X + 1400; H = ++i) { | |
10 | s = i % 800; | |
11 | if (!s) { | |
12 | /* Will run every once in a while to change direction and environment */ | |
13 | changeCounter = i / 800; | |
14 | inclineAmount = changeCounter & 1 && -Q + (Q = Math.random() > 0.5); // Centered around 0. | |
15 | turnAmount = !inclineAmount && changeCounter && (turnAmount + 2 + (Math.random() > 0.5)) % 3 - 1; //Centered around 0. | |
16 | inStalCave = !inclineAmount && changeCounter > 9 && !inStalCave && Math.random() > 0.7; //Boolean. | |
17 | W = 1.8 * Math.random() - 1; | |
18 | } | |
19 | ||
20 | F = (s < 160) - (s > 639); | |
21 | E += F; | |
22 | ||
23 | T[i % 1400] = [I += J, J += turnAmount, U += V, V = inclineAmount * E, !inclineAmount && Math.exp(-(L = i % 400 - 200) * L / 3000) / 1.5, i % 400, Math.random() > 0.95]; | |
24 | rectData = T[i % 1400]; | |
25 | ||
26 | if (!(i % 10)) { | |
27 | Z = 9.8 + inStalCave * E / 15; | |
28 | y = Z | |
29 | z = W * inStalCave * E / 15; | |
30 | ||
31 | ||
32 | /* | |
33 | Rect info is stored in array rectData in the following order and repeated as many times as needed: | |
34 | - X position (relative to centre) | |
35 | - Init color (from white to black) | |
36 | - Width from x | |
37 | - Y position (relative to centre) | |
38 | - Height from y | |
39 | */ | |
40 | ||
41 | ||
42 | /* Cave (literally just a circle) */ | |
43 | for (g = Math.random() / 6; g < 6.3; g += 2 / Z) { | |
44 | if (inclineAmount || inStalCave) { | |
45 | if (Math.random() > 0.4) { | |
46 | rectData.push(1.1 * Z * Math.cos(g + 11)); | |
47 | rectData.push(7 + inStalCave * 16, 4 - F); | |
48 | rectData.push(Z * Math.cos(g) + 2 + z); | |
49 | rectData.push(4 - F); | |
50 | } | |
51 | } else { | |
52 | if (Math.random() > (Math.cos(g) > 0.5)) { | |
53 | rectData.push(1.1 * Z * Math.cos(g + 11)); | |
54 | rectData.push(7 + inStalCave * 16); | |
55 | rectData.push(4 - F, Z * Math.cos(g) + 2 + z); | |
56 | rectData.push(4 - F); | |
57 | } | |
58 | } | |
59 | } | |
60 | ||
61 | t = 2 * Z * Math.random() - Z; | |
62 | w = t * t * Math.random() / 6; | |
63 | ||
64 | /* Stalactites and Stalagmites */ | |
65 | while (inStalCave * w > 0.2) { | |
66 | rectData.push(t); | |
67 | rectData.push(7 + inStalCave * 16); | |
68 | rectData.push(w); | |
69 | rectData.push(--y + z); | |
70 | rectData.push(1.1); | |
71 | ||
72 | rectData.push(t); | |
73 | rectData.push(7 + inStalCave * 16); | |
74 | rectData.push(w *= 0.8); | |
75 | rectData.push(-y + z); | |
76 | rectData.push(1.1); | |
77 | } | |
78 | ||
79 | /* I have no clue what this is */ | |
80 | if (!Q && (inStalCave * W > 0.6)) { | |
81 | rectData.push(2 * Z * Math.random() - Z); | |
82 | rectData.push(12); | |
83 | rectData.push(0.2); | |
84 | rectData.push(Z * Math.random() - Z / 2 + z); | |
85 | rectData.push(1 + Math.random()); | |
86 | } | |
87 | ||
88 | /* */ | |
89 | if (inStalCave && i % 20) { | |
90 | rectData.push(-2); | |
91 | rectData.push(22); | |
92 | rectData.push(0.5); | |
93 | rectData.push(-7); | |
94 | rectData.push(Z - 8 - z); | |
95 | ||
96 | rectData.push(2); | |
97 | rectData.push(22); | |
98 | rectData.push(0.5); | |
99 | rectData.push(-7); | |
100 | rectData.push(Z - 8 - z); | |
101 | } | |
102 | ||
103 | /* Horizontal bars on tracks */ | |
104 | if (!(i % 20)) { | |
105 | rectData.push(0); | |
106 | rectData.push(6); | |
107 | rectData.push(6); | |
108 | rectData.push(-6.8); | |
109 | rectData.push(0.8); | |
110 | } | |
111 | ||
112 | /* Lamps */ | |
113 | if (!L) { | |
114 | rectData.push(0); | |
115 | rectData.push(7 + inStalCave * 16); | |
116 | rectData.push(0.2); | |
117 | rectData.push(Z + z); | |
118 | rectData.push(Z + z - 5); | |
119 | ||
120 | rectData.push(0); | |
121 | rectData.push(7); | |
122 | rectData.push(0.6); | |
123 | rectData.push(5); | |
124 | rectData.push(0.6); | |
125 | } | |
126 | ||
127 | /* Doorway thing */ | |
128 | if (!inclineAmount && !inStalCave) { | |
129 | if (!(i % 40)) { | |
130 | rectData.push(-6); | |
131 | rectData.push(6); | |
132 | rectData.push(1.5); | |
133 | rectData.push(5); | |
134 | rectData.push(14); | |
135 | ||
136 | rectData.push(6); | |
137 | rectData.push(6); | |
138 | rectData.push(1.5); | |
139 | rectData.push(5); | |
140 | rectData.push(14); | |
141 | } | |
142 | if (!(i % 20)) { | |
143 | rectData.push(0); | |
144 | rectData.push(6); | |
145 | rectData.push(17); | |
146 | rectData.push(8); | |
147 | rectData.push(3); | |
148 | } | |
149 | } | |
150 | } | |
151 | ||
152 | /* Train track (the metal part) */ | |
153 | if (!(i % 5)) { | |
154 | /* Left */ | |
155 | rectData.push(-2); | |
156 | rectData.push(6); | |
157 | rectData.push(0.5); | |
158 | rectData.push(-6.5); | |
159 | rectData.push(0.6); | |
160 | ||
161 | /* Right */ | |
162 | rectData.push(2); | |
163 | rectData.push(6); | |
164 | rectData.push(0.5); | |
165 | rectData.push(-6.5); | |
166 | rectData.push(0.6); | |
167 | } | |
168 | } | |
169 | q = T[X % 1400]; | |
170 | while (true) { | |
171 | d = --i - X; | |
172 | if (!d) | |
173 | break; | |
174 | rectData = T[i % 1400]; | |
175 | f = C / (d / 10 + 3); | |
176 | v = g = 0; | |
177 | t = C + f * (rectData[g] - q[g++] - d * q[g++]) / 3000; | |
178 | u = C + f * (rectData[g] - q[g++] - d * q[g++]) / 3000; | |
179 | ||
180 | /* Light flicker. */ | |
181 | x = rectData[g++]; | |
182 | if (rectData[g++]) | |
183 | l = g++ && l; | |
184 | else if (rectData[g++]) | |
185 | l = Math.random() > 0.3; | |
186 | else | |
187 | l = 1; | |
188 | x *= l; | |
189 | ||
190 | y = d / 1800; | |
191 | while (true) { | |
192 | z = f * rectData[g++]; | |
193 | w = rectData[g++]; | |
194 | if (!w) | |
195 | break; | |
196 | ||
197 | v != w && (v = w, context.fillStyle = 'hsl(0,0%,' + 16 * (w & 7) * (w & 8 || y + x * (w < 16)) + '%)'); | |
198 | ||
199 | var rectX = t + z - (z = f * rectData[g++]) / 2; | |
200 | var rectY = u - f * rectData[g++] + (w == 12 && f * 6 * Math.cos(g + X / 400)); | |
201 | var rectW = z; | |
202 | var rectH = f * rectData[g++]; | |
203 | ||
204 | context.fillRect(rectX, rectY, rectW, rectH); | |
205 | } | |
206 | } | |
207 | Y += 4 - 3 * Math.exp(-X / 400) + q[2] / 30000; | |
208 | X = 0 | Y; | |
209 | }, 35); |