Browse Source

basically implement clouds

Kyle Perik 11 months ago
parent
commit
ed360fdc85
1 changed files with 67 additions and 10 deletions
  1. 67 10
      index.js

+ 67 - 10
index.js

@@ -2,8 +2,12 @@
2 2
 
3 3
 var testing = false;
4 4
 
5
+function sum(n) {
6
+    return n.reduce((a, b) => a + b, 0);
7
+}
8
+
5 9
 function mean(n) {
6
-    return n.reduce((a, b) => a + b, 0) / n.length;
10
+    return sum(n) / n.length;
7 11
 }
8 12
 
9 13
 function getPixelCanvas(ctx, size) {
@@ -41,8 +45,9 @@ function getWeather(coords) {
41 45
     if (testing) {
42 46
         return new Promise((r) => {
43 47
             r({
44
-                wind: { speed: 5, deg: 1 },
45
-                clouds: { all: 80 }
48
+                wind: { speed: 10, deg: 1 },
49
+                clouds: { all: 50 },
50
+                rain: { '1h': 3 },
46 51
             });
47 52
         });
48 53
     }
@@ -172,6 +177,42 @@ function drawRain(particles, wind, isSnow, amount) {
172 177
     })));
173 178
 }
174 179
 
180
+function fillInClouds(canvasSize, x, amount) {
181
+    return Math.random() * 1000 < amount ? [{
182
+        x: x,
183
+        y: Math.random() * canvasSize.y,
184
+        z: 20,//Math.random() * 30 + 10,
185
+        size: (Math.random()) * 500 + 10,
186
+    }] : [];
187
+}
188
+
189
+function drawClouds(clouds, wind, amount, cloud_color) {
190
+    var canvasSize = getSize(pixelCanvas);
191
+    [...Array(canvasSize.x).keys()].map(
192
+        x => [...Array(canvasSize.y).keys()].map(y => {
193
+            var meta = Math.pow(sum(clouds.map(c => c.size / (Math.pow(x - c.x, 2) + Math.pow(y - c.y, 2)))), 2);
194
+            //if (meta < 0.8) return;
195
+            var color = cloud_color.slice().concat([Math.min(1, meta) * .75]);
196
+            drawRect(
197
+                x, y,
198
+                1, 1,
199
+                rgbatostr(color),
200
+                pixelCanvas
201
+            );
202
+        })
203
+    );
204
+    var averagePoint = {x: mean(clouds.map(c => c.x)), y: mean(clouds.map(c => c.y))};
205
+    return clouds.map(c => ({
206
+        ...c,
207
+        x: c.x + wind / 8,// - (c.x - averagePoint.x) / 1000,
208
+        y: c.y,// - (c.y - averagePoint.y) / 1000,
209
+        size: c.size + (Math.random() - .5) / 10,
210
+    })).concat(fillInClouds(
211
+        canvasSize, wind > 0 ? -90 : canvasSize.x + 90,
212
+        amount
213
+    )).filter(c => c.x > -100 && c.x < canvasSize.x + 100);
214
+}
215
+
175 216
 function draw(s) {
176 217
     if (testing) {
177 218
         var now = new Date();
@@ -192,15 +233,21 @@ function draw(s) {
192 233
             pixelCanvas
193 234
         ))
194 235
     );
195
-    var overcast_color = colorMix(
236
+    var light = Math.pow((percentday + 1) / 2, 4);
237
+    var raw_overcast_color = colorMix(
196 238
         colorMix(
197 239
             nightcolor,
198 240
             [20, 20, 40], .5
199 241
         ),
200 242
         [240, 240, 240],
201
-        Math.max(0, Math.min(1, (percentday) * 20))
202
-    ).concat([Math.pow(s.weather.clouds.all / 100, 2)]);
243
+        Math.max(0, Math.min(1, (light - 0.002) * 20))
244
+    );
245
+    var overcast_color = raw_overcast_color.concat([Math.pow(s.weather.clouds.all / 100, 2)]);
203 246
     drawRect(0, 0, canvasSize.x, canvasSize.y, rgbatostr(overcast_color), pixelCanvas);
247
+    var wind = state.weather.wind.speed / 4 * (
248
+        state.weather.wind.deg > 180 ? 1 : -1
249
+    );
250
+    state.clouds = drawClouds(state.clouds, wind, state.weather.clouds.all, raw_overcast_color);
204 251
     state.background = pixelCanvas.ctx.getImageData(
205 252
         0, 0,
206 253
         canvas.width,
@@ -221,7 +268,7 @@ var state = {
221 268
     weather: {},
222 269
     rain: [],
223 270
     clouds: [],
224
-    stars: []
271
+    stars: [],
225 272
 };
226 273
 
227 274
 getLatLong().then(
@@ -233,6 +280,14 @@ getLatLong().then(
233 280
     r => {
234 281
         state.weather = r;
235 282
         onresize();
283
+        var canvasSize = getSize(pixelCanvas);
284
+        state.clouds = (
285
+            'clouds' in state.weather
286
+            ? [].concat.apply([], range(canvasSize.x).map(
287
+                x => fillInClouds(canvasSize, x, state.weather.clouds.all)
288
+            ))
289
+            : []
290
+        )
236 291
         draw(state);
237 292
         pixelCanvas.ctx.save();
238 293
         setInterval(() => {
@@ -241,6 +296,10 @@ getLatLong().then(
241 296
         }, testing ? 1000 : 10000);
242 297
         setInterval(() => {
243 298
             pixelCanvas.ctx.putImageData(state.background, 0, 0);
299
+            var wind = state.weather.wind.speed / 4 * (
300
+                state.weather.wind.deg > 180 ? 1 : -1
301
+            );
302
+            //if ('clouds' in state.weather) state.clouds = drawClouds(state.clouds, wind, state.weather.clouds.all);
244 303
             if (!('rain' in state.weather || 'snow' in state.weather)) return;
245 304
             var size = getSize(pixelCanvas);
246 305
             var source = state.weather.rain || state.weather.snow;
@@ -251,9 +310,7 @@ getLatLong().then(
251 310
                 ) * size.x / 10
252 311
             );
253 312
             state.rain = drawRain(
254
-                state.rain, state.weather.wind.speed / 4 * (
255
-                    state.weather.wind.deg > 180 ? 1 : -1
256
-                ), 'snow' in state.weather,
313
+                state.rain, wind, 'snow' in state.weather,
257 314
                 rainAmount
258 315
             );
259 316
         }, 50);