├── demo
├── public
│ ├── favicon.ico
│ └── index.html
├── babel.config.js
├── src
│ ├── main.js
│ └── App.vue
├── README.md
└── package.json
├── index.js
├── .gitignore
├── package.json
├── Skycon.vue
├── README.md
└── skycons.js
/demo/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timleland/vue-skycon/master/demo/public/favicon.ico
--------------------------------------------------------------------------------
/demo/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import SkyconComponent from './Skycon';
2 |
3 | export default {
4 | install: function(Vue) {
5 | Vue.component('skycon', SkyconComponent);
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/demo/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './App.vue';
3 | import VueSkycons from 'vue-skycon';
4 |
5 | Vue.use(VueSkycons);
6 |
7 | new Vue({
8 | render: (h) => h(App),
9 | }).$mount('#app');
10 |
--------------------------------------------------------------------------------
/demo/README.md:
--------------------------------------------------------------------------------
1 | # Vue Skycons Demo App
2 |
3 | Easily use [Skycons](https://github.com/darkskyapp/skycons) in your VueJs apps. Example use [WeatherTab](https://timleland.com/weathertab/)
4 |
5 | ## Demo Example
6 |
7 | ```
8 | npm i
9 | npm run serve
10 | browse to: http://localhost:8081/
11 | ```
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-skycon",
3 | "version": "1.0.4",
4 | "description": "Skycons weather icons in VueJS",
5 | "main": "index.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/timleland/vue-skycon.git"
9 | },
10 | "keywords": [
11 | "skycons",
12 | "skycon",
13 | "weather",
14 | "vue",
15 | "icons",
16 | "animated"
17 | ],
18 | "author": "Tim Leland",
19 | "license": "Apache v2.0",
20 | "bugs": {
21 | "url": "https://github.com/timleland/vue-skycon/issues"
22 | },
23 | "homepage": "https://github.com/timleland/vue-skycon#readme"
24 | }
25 |
--------------------------------------------------------------------------------
/demo/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-skycon",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "core-js": "^3.6.5",
12 | "vue": "^2.6.11",
13 | "vue-skycon": "^1.0.4"
14 | },
15 | "devDependencies": {
16 | "@vue/cli-plugin-babel": "~4.5.0",
17 | "@vue/cli-plugin-eslint": "~4.5.0",
18 | "@vue/cli-service": "~4.5.0",
19 | "babel-eslint": "^10.1.0",
20 | "eslint": "^6.7.2",
21 | "eslint-plugin-vue": "^6.2.2",
22 | "vue-template-compiler": "^2.6.11"
23 | },
24 | "eslintConfig": {
25 | "root": true,
26 | "env": {
27 | "node": true
28 | },
29 | "extends": [
30 | "plugin:vue/essential",
31 | "eslint:recommended"
32 | ],
33 | "parserOptions": {
34 | "parser": "babel-eslint"
35 | },
36 | "rules": {}
37 | },
38 | "browserslist": [
39 | "> 1%",
40 | "last 2 versions",
41 | "not dead"
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/demo/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
40 |
41 |
43 |
--------------------------------------------------------------------------------
/Skycon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vue Skycons
2 | Easily use [Skycons](https://t.ly/_ic0) in your VueJs apps. Example use [Weather Extension](https://weatherextension.com/) and [WeatherTab](https://timleland.com/weathertab/)
3 |
4 |
5 |
6 | ## Installation
7 | ### NPM
8 | ```
9 | npm i vue-skycon
10 | ```
11 |
12 | ### YARN
13 | ```
14 | yarn add vue-skycon
15 | ```
16 |
17 | ## Installation
18 | ```
19 | import Vue from 'vue'
20 | import VueSkycons from 'vue-skycon'
21 |
22 | Vue.use(VueSkycons)
23 |
24 | ```
25 |
26 | ## Usage
27 | ```
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | ```
44 |
45 | ## Props
46 | ```
47 | // Icon size
48 | width: {
49 | type: Number,
50 | default: 64
51 | },
52 |
53 | height: {
54 | type: Number,
55 | default: 64
56 | },
57 |
58 | color: {
59 | type: String,
60 | default: 'black'
61 | },
62 |
63 | // Weather condition
64 | condition: {
65 | type: String
66 | }
67 | ```
68 |
--------------------------------------------------------------------------------
/skycons.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /* Set up a RequestAnimationFrame shim so we can animate efficiently FOR
4 | * GREAT JUSTICE. */
5 | var requestInterval, cancelInterval;
6 |
7 | (function() {
8 | var global = window;
9 |
10 | var raf = global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || global.oRequestAnimationFrame || global.msRequestAnimationFrame,
11 | caf = global.cancelAnimationFrame || global.webkitCancelAnimationFrame || global.mozCancelAnimationFrame || global.oCancelAnimationFrame || global.msCancelAnimationFrame;
12 |
13 | if (raf && caf) {
14 | requestInterval = function(fn) {
15 | var handle = { value: null };
16 |
17 | function loop() {
18 | handle.value = raf(loop);
19 | fn();
20 | }
21 |
22 | loop();
23 | return handle;
24 | };
25 |
26 | cancelInterval = function(handle) {
27 | caf(handle.value);
28 | };
29 | } else {
30 | requestInterval = setInterval;
31 | cancelInterval = clearInterval;
32 | }
33 | })();
34 |
35 | /* Catmull-rom spline stuffs. */
36 | /*
37 | function upsample(n, spline) {
38 | var polyline = [],
39 | len = spline.length,
40 | bx = spline[0],
41 | by = spline[1],
42 | cx = spline[2],
43 | cy = spline[3],
44 | dx = spline[4],
45 | dy = spline[5],
46 | i, j, ax, ay, px, qx, rx, sx, py, qy, ry, sy, t;
47 |
48 | for(i = 6; i !== spline.length; i += 2) {
49 | ax = bx;
50 | bx = cx;
51 | cx = dx;
52 | dx = spline[i ];
53 | px = -0.5 * ax + 1.5 * bx - 1.5 * cx + 0.5 * dx;
54 | qx = ax - 2.5 * bx + 2.0 * cx - 0.5 * dx;
55 | rx = -0.5 * ax + 0.5 * cx ;
56 | sx = bx ;
57 |
58 | ay = by;
59 | by = cy;
60 | cy = dy;
61 | dy = spline[i + 1];
62 | py = -0.5 * ay + 1.5 * by - 1.5 * cy + 0.5 * dy;
63 | qy = ay - 2.5 * by + 2.0 * cy - 0.5 * dy;
64 | ry = -0.5 * ay + 0.5 * cy ;
65 | sy = by ;
66 |
67 | for(j = 0; j !== n; ++j) {
68 | t = j / n;
69 |
70 | polyline.push(
71 | ((px * t + qx) * t + rx) * t + sx,
72 | ((py * t + qy) * t + ry) * t + sy
73 | );
74 | }
75 | }
76 |
77 | polyline.push(
78 | px + qx + rx + sx,
79 | py + qy + ry + sy
80 | );
81 |
82 | return polyline;
83 | }
84 |
85 | function downsample(n, polyline) {
86 | var len = 0,
87 | i, dx, dy;
88 |
89 | for(i = 2; i !== polyline.length; i += 2) {
90 | dx = polyline[i ] - polyline[i - 2];
91 | dy = polyline[i + 1] - polyline[i - 1];
92 | len += Math.sqrt(dx * dx + dy * dy);
93 | }
94 |
95 | len /= n;
96 |
97 | var small = [],
98 | target = len,
99 | min = 0,
100 | max, t;
101 |
102 | small.push(polyline[0], polyline[1]);
103 |
104 | for(i = 2; i !== polyline.length; i += 2) {
105 | dx = polyline[i ] - polyline[i - 2];
106 | dy = polyline[i + 1] - polyline[i - 1];
107 | max = min + Math.sqrt(dx * dx + dy * dy);
108 |
109 | if(max > target) {
110 | t = (target - min) / (max - min);
111 |
112 | small.push(
113 | polyline[i - 2] + dx * t,
114 | polyline[i - 1] + dy * t
115 | );
116 |
117 | target += len;
118 | }
119 |
120 | min = max;
121 | }
122 |
123 | small.push(polyline[polyline.length - 2], polyline[polyline.length - 1]);
124 |
125 | return small;
126 | }
127 | */
128 |
129 | /* Define skycon things. */
130 | /* FIXME: I'm *really really* sorry that this code is so gross. Really, I am.
131 | * I'll try to clean it up eventually! Promise! */
132 | var KEYFRAME = 500,
133 | STROKE = 0.08,
134 | TAU = 2.0 * Math.PI,
135 | TWO_OVER_SQRT_2 = 2.0 / Math.sqrt(2);
136 |
137 | function circle(ctx, x, y, r) {
138 | ctx.beginPath();
139 | ctx.arc(x, y, r, 0, TAU, false);
140 | ctx.fill();
141 | }
142 |
143 | function line(ctx, ax, ay, bx, by) {
144 | ctx.beginPath();
145 | ctx.moveTo(ax, ay);
146 | ctx.lineTo(bx, by);
147 | ctx.stroke();
148 | }
149 |
150 | function puff(ctx, t, cx, cy, rx, ry, rmin, rmax) {
151 | var c = Math.cos(t * TAU),
152 | s = Math.sin(t * TAU);
153 |
154 | rmax -= rmin;
155 |
156 | circle(ctx, cx - s * rx, cy + c * ry + rmax * 0.5, rmin + (1 - c * 0.5) * rmax);
157 | }
158 |
159 | function puffs(ctx, t, cx, cy, rx, ry, rmin, rmax) {
160 | var i;
161 |
162 | for (i = 5; i--; ) puff(ctx, t + i / 5, cx, cy, rx, ry, rmin, rmax);
163 | }
164 |
165 | function cloud(ctx, t, cx, cy, cw, s, color) {
166 | t /= 30000;
167 |
168 | var a = cw * 0.21,
169 | b = cw * 0.12,
170 | c = cw * 0.24,
171 | d = cw * 0.28;
172 |
173 | ctx.fillStyle = color;
174 | puffs(ctx, t, cx, cy, a, b, c, d);
175 |
176 | ctx.globalCompositeOperation = 'destination-out';
177 | puffs(ctx, t, cx, cy, a, b, c - s, d - s);
178 | ctx.globalCompositeOperation = 'source-over';
179 | }
180 |
181 | function sun(ctx, t, cx, cy, cw, s, color) {
182 | t /= 120000;
183 |
184 | var a = cw * 0.25 - s * 0.5,
185 | b = cw * 0.32 + s * 0.5,
186 | c = cw * 0.5 - s * 0.5,
187 | i,
188 | p,
189 | cos,
190 | sin;
191 |
192 | ctx.strokeStyle = color;
193 | ctx.lineWidth = s;
194 | ctx.lineCap = 'round';
195 | ctx.lineJoin = 'round';
196 |
197 | ctx.beginPath();
198 | ctx.arc(cx, cy, a, 0, TAU, false);
199 | ctx.stroke();
200 |
201 | for (i = 8; i--; ) {
202 | p = (t + i / 8) * TAU;
203 | cos = Math.cos(p);
204 | sin = Math.sin(p);
205 | line(ctx, cx + cos * b, cy + sin * b, cx + cos * c, cy + sin * c);
206 | }
207 | }
208 |
209 | function moon(ctx, t, cx, cy, cw, s, color) {
210 | t /= 15000;
211 |
212 | var a = cw * 0.29 - s * 0.5,
213 | b = cw * 0.05,
214 | c = Math.cos(t * TAU),
215 | p = (c * TAU) / -16;
216 |
217 | ctx.strokeStyle = color;
218 | ctx.lineWidth = s;
219 | ctx.lineCap = 'round';
220 | ctx.lineJoin = 'round';
221 |
222 | cx += c * b;
223 |
224 | ctx.beginPath();
225 | ctx.arc(cx, cy, a, p + TAU / 8, p + (TAU * 7) / 8, false);
226 | ctx.arc(cx + Math.cos(p) * a * TWO_OVER_SQRT_2, cy + Math.sin(p) * a * TWO_OVER_SQRT_2, a, p + (TAU * 5) / 8, p + (TAU * 3) / 8, true);
227 | ctx.closePath();
228 | ctx.stroke();
229 | }
230 |
231 | function rain(ctx, t, cx, cy, cw, s, color) {
232 | t /= 1350;
233 |
234 | var a = cw * 0.16,
235 | b = (TAU * 11) / 12,
236 | c = (TAU * 7) / 12,
237 | i,
238 | p,
239 | x,
240 | y;
241 |
242 | ctx.fillStyle = color;
243 |
244 | for (i = 4; i--; ) {
245 | p = (t + i / 4) % 1;
246 | x = cx + ((i - 1.5) / 1.5) * (i === 1 || i === 2 ? -1 : 1) * a;
247 | y = cy + p * p * cw;
248 | ctx.beginPath();
249 | ctx.moveTo(x, y - s * 1.5);
250 | ctx.arc(x, y, s * 0.75, b, c, false);
251 | ctx.fill();
252 | }
253 | }
254 |
255 | function sleet(ctx, t, cx, cy, cw, s, color) {
256 | t /= 750;
257 |
258 | var a = cw * 0.1875,
259 | i,
260 | p,
261 | x,
262 | y;
263 |
264 | ctx.strokeStyle = color;
265 | ctx.lineWidth = s * 0.5;
266 | ctx.lineCap = 'round';
267 | ctx.lineJoin = 'round';
268 |
269 | for (i = 4; i--; ) {
270 | p = (t + i / 4) % 1;
271 | x = Math.floor(cx + ((i - 1.5) / 1.5) * (i === 1 || i === 2 ? -1 : 1) * a) + 0.5;
272 | y = cy + p * cw;
273 | line(ctx, x, y - s * 1.5, x, y + s * 1.5);
274 | }
275 | }
276 |
277 | function snow(ctx, t, cx, cy, cw, s, color) {
278 | t /= 3000;
279 |
280 | var a = cw * 0.16,
281 | b = s * 0.75,
282 | u = t * TAU * 0.7,
283 | ux = Math.cos(u) * b,
284 | uy = Math.sin(u) * b,
285 | v = u + TAU / 3,
286 | vx = Math.cos(v) * b,
287 | vy = Math.sin(v) * b,
288 | w = u + (TAU * 2) / 3,
289 | wx = Math.cos(w) * b,
290 | wy = Math.sin(w) * b,
291 | i,
292 | p,
293 | x,
294 | y;
295 |
296 | ctx.strokeStyle = color;
297 | ctx.lineWidth = s * 0.5;
298 | ctx.lineCap = 'round';
299 | ctx.lineJoin = 'round';
300 |
301 | for (i = 4; i--; ) {
302 | p = (t + i / 4) % 1;
303 | x = cx + Math.sin((p + i / 4) * TAU) * a;
304 | y = cy + p * cw;
305 |
306 | line(ctx, x - ux, y - uy, x + ux, y + uy);
307 | line(ctx, x - vx, y - vy, x + vx, y + vy);
308 | line(ctx, x - wx, y - wy, x + wx, y + wy);
309 | }
310 | }
311 |
312 | function fogbank(ctx, t, cx, cy, cw, s, color) {
313 | t /= 30000;
314 |
315 | var a = cw * 0.21,
316 | b = cw * 0.06,
317 | c = cw * 0.21,
318 | d = cw * 0.28;
319 |
320 | ctx.fillStyle = color;
321 | puffs(ctx, t, cx, cy, a, b, c, d);
322 |
323 | ctx.globalCompositeOperation = 'destination-out';
324 | puffs(ctx, t, cx, cy, a, b, c - s, d - s);
325 | ctx.globalCompositeOperation = 'source-over';
326 | }
327 |
328 | /*
329 | var WIND_PATHS = [
330 | downsample(63, upsample(8, [
331 | -1.00, -0.28,
332 | -0.75, -0.18,
333 | -0.50, 0.12,
334 | -0.20, 0.12,
335 | -0.04, -0.04,
336 | -0.07, -0.18,
337 | -0.19, -0.18,
338 | -0.23, -0.05,
339 | -0.12, 0.11,
340 | 0.02, 0.16,
341 | 0.20, 0.15,
342 | 0.50, 0.07,
343 | 0.75, 0.18,
344 | 1.00, 0.28
345 | ])),
346 | downsample(31, upsample(16, [
347 | -1.00, -0.10,
348 | -0.75, 0.00,
349 | -0.50, 0.10,
350 | -0.25, 0.14,
351 | 0.00, 0.10,
352 | 0.25, 0.00,
353 | 0.50, -0.10,
354 | 0.75, -0.14,
355 | 1.00, -0.10
356 | ]))
357 | ];
358 | */
359 |
360 | var WIND_PATHS = [
361 | [
362 | -0.75,
363 | -0.18,
364 | -0.7219,
365 | -0.1527,
366 | -0.6971,
367 | -0.1225,
368 | -0.6739,
369 | -0.091,
370 | -0.6516,
371 | -0.0588,
372 | -0.6298,
373 | -0.0262,
374 | -0.6083,
375 | 0.0065,
376 | -0.5868,
377 | 0.0396,
378 | -0.5643,
379 | 0.0731,
380 | -0.5372,
381 | 0.1041,
382 | -0.5033,
383 | 0.1259,
384 | -0.4662,
385 | 0.1406,
386 | -0.4275,
387 | 0.1493,
388 | -0.3881,
389 | 0.153,
390 | -0.3487,
391 | 0.1526,
392 | -0.3095,
393 | 0.1488,
394 | -0.2708,
395 | 0.1421,
396 | -0.2319,
397 | 0.1342,
398 | -0.1943,
399 | 0.1217,
400 | -0.16,
401 | 0.1025,
402 | -0.129,
403 | 0.0785,
404 | -0.1012,
405 | 0.0509,
406 | -0.0764,
407 | 0.0206,
408 | -0.0547,
409 | -0.012,
410 | -0.0378,
411 | -0.0472,
412 | -0.0324,
413 | -0.0857,
414 | -0.0389,
415 | -0.1241,
416 | -0.0546,
417 | -0.1599,
418 | -0.0814,
419 | -0.1876,
420 | -0.1193,
421 | -0.1964,
422 | -0.1582,
423 | -0.1935,
424 | -0.1931,
425 | -0.1769,
426 | -0.2157,
427 | -0.1453,
428 | -0.229,
429 | -0.1085,
430 | -0.2327,
431 | -0.0697,
432 | -0.224,
433 | -0.0317,
434 | -0.2064,
435 | 0.0033,
436 | -0.1853,
437 | 0.0362,
438 | -0.1613,
439 | 0.0672,
440 | -0.135,
441 | 0.0961,
442 | -0.1051,
443 | 0.1213,
444 | -0.0706,
445 | 0.1397,
446 | -0.0332,
447 | 0.1512,
448 | 0.0053,
449 | 0.158,
450 | 0.0442,
451 | 0.1624,
452 | 0.0833,
453 | 0.1636,
454 | 0.1224,
455 | 0.1615,
456 | 0.1613,
457 | 0.1565,
458 | 0.1999,
459 | 0.15,
460 | 0.2378,
461 | 0.1402,
462 | 0.2749,
463 | 0.1279,
464 | 0.3118,
465 | 0.1147,
466 | 0.3487,
467 | 0.1015,
468 | 0.3858,
469 | 0.0892,
470 | 0.4236,
471 | 0.0787,
472 | 0.4621,
473 | 0.0715,
474 | 0.5012,
475 | 0.0702,
476 | 0.5398,
477 | 0.0766,
478 | 0.5768,
479 | 0.089,
480 | 0.6123,
481 | 0.1055,
482 | 0.6466,
483 | 0.1244,
484 | 0.6805,
485 | 0.144,
486 | 0.7147,
487 | 0.163,
488 | 0.75,
489 | 0.18
490 | ],
491 | [
492 | -0.75,
493 | 0.0,
494 | -0.7033,
495 | 0.0195,
496 | -0.6569,
497 | 0.0399,
498 | -0.6104,
499 | 0.06,
500 | -0.5634,
501 | 0.0789,
502 | -0.5155,
503 | 0.0954,
504 | -0.4667,
505 | 0.1089,
506 | -0.4174,
507 | 0.1206,
508 | -0.3676,
509 | 0.1299,
510 | -0.3174,
511 | 0.1365,
512 | -0.2669,
513 | 0.1398,
514 | -0.2162,
515 | 0.1391,
516 | -0.1658,
517 | 0.1347,
518 | -0.1157,
519 | 0.1271,
520 | -0.0661,
521 | 0.1169,
522 | -0.017,
523 | 0.1046,
524 | 0.0316,
525 | 0.0903,
526 | 0.0791,
527 | 0.0728,
528 | 0.1259,
529 | 0.0534,
530 | 0.1723,
531 | 0.0331,
532 | 0.2188,
533 | 0.0129,
534 | 0.2656,
535 | -0.0064,
536 | 0.3122,
537 | -0.0263,
538 | 0.3586,
539 | -0.0466,
540 | 0.4052,
541 | -0.0665,
542 | 0.4525,
543 | -0.0847,
544 | 0.5007,
545 | -0.1002,
546 | 0.5497,
547 | -0.113,
548 | 0.5991,
549 | -0.124,
550 | 0.6491,
551 | -0.1325,
552 | 0.6994,
553 | -0.138,
554 | 0.75,
555 | -0.14
556 | ]
557 | ],
558 | WIND_OFFSETS = [{ start: 0.36, end: 0.11 }, { start: 0.56, end: 0.16 }];
559 |
560 | function leaf(ctx, t, x, y, cw, s, color) {
561 | var a = cw / 8,
562 | b = a / 3,
563 | c = 2 * b,
564 | d = (t % 1) * TAU,
565 | e = Math.cos(d),
566 | f = Math.sin(d);
567 |
568 | ctx.fillStyle = color;
569 | ctx.strokeStyle = color;
570 | ctx.lineWidth = s;
571 | ctx.lineCap = 'round';
572 | ctx.lineJoin = 'round';
573 |
574 | ctx.beginPath();
575 | ctx.arc(x, y, a, d, d + Math.PI, false);
576 | ctx.arc(x - b * e, y - b * f, c, d + Math.PI, d, false);
577 | ctx.arc(x + c * e, y + c * f, b, d + Math.PI, d, true);
578 | ctx.globalCompositeOperation = 'destination-out';
579 | ctx.fill();
580 | ctx.globalCompositeOperation = 'source-over';
581 | ctx.stroke();
582 | }
583 |
584 | function swoosh(ctx, t, cx, cy, cw, s, index, total, color) {
585 | t /= 2500;
586 |
587 | var path = WIND_PATHS[index],
588 | a = (t + index - WIND_OFFSETS[index].start) % total,
589 | c = (t + index - WIND_OFFSETS[index].end) % total,
590 | e = (t + index) % total,
591 | b,
592 | d,
593 | f,
594 | i;
595 |
596 | ctx.strokeStyle = color;
597 | ctx.lineWidth = s;
598 | ctx.lineCap = 'round';
599 | ctx.lineJoin = 'round';
600 |
601 | if (a < 1) {
602 | ctx.beginPath();
603 |
604 | a *= path.length / 2 - 1;
605 | b = Math.floor(a);
606 | a -= b;
607 | b *= 2;
608 | b += 2;
609 |
610 | ctx.moveTo(cx + (path[b - 2] * (1 - a) + path[b] * a) * cw, cy + (path[b - 1] * (1 - a) + path[b + 1] * a) * cw);
611 |
612 | if (c < 1) {
613 | c *= path.length / 2 - 1;
614 | d = Math.floor(c);
615 | c -= d;
616 | d *= 2;
617 | d += 2;
618 |
619 | for (i = b; i !== d; i += 2) ctx.lineTo(cx + path[i] * cw, cy + path[i + 1] * cw);
620 |
621 | ctx.lineTo(cx + (path[d - 2] * (1 - c) + path[d] * c) * cw, cy + (path[d - 1] * (1 - c) + path[d + 1] * c) * cw);
622 | } else for (i = b; i !== path.length; i += 2) ctx.lineTo(cx + path[i] * cw, cy + path[i + 1] * cw);
623 |
624 | ctx.stroke();
625 | } else if (c < 1) {
626 | ctx.beginPath();
627 |
628 | c *= path.length / 2 - 1;
629 | d = Math.floor(c);
630 | c -= d;
631 | d *= 2;
632 | d += 2;
633 |
634 | ctx.moveTo(cx + path[0] * cw, cy + path[1] * cw);
635 |
636 | for (i = 2; i !== d; i += 2) ctx.lineTo(cx + path[i] * cw, cy + path[i + 1] * cw);
637 |
638 | ctx.lineTo(cx + (path[d - 2] * (1 - c) + path[d] * c) * cw, cy + (path[d - 1] * (1 - c) + path[d + 1] * c) * cw);
639 |
640 | ctx.stroke();
641 | }
642 |
643 | if (e < 1) {
644 | e *= path.length / 2 - 1;
645 | f = Math.floor(e);
646 | e -= f;
647 | f *= 2;
648 | f += 2;
649 |
650 | leaf(ctx, t, cx + (path[f - 2] * (1 - e) + path[f] * e) * cw, cy + (path[f - 1] * (1 - e) + path[f + 1] * e) * cw, cw, s, color);
651 | }
652 | }
653 |
654 | var Skycons = function(opts) {
655 | this.list = [];
656 | this.interval = null;
657 | this.color = opts && opts.color ? opts.color : 'black';
658 | this.resizeClear = !!(opts && opts.resizeClear);
659 | };
660 |
661 | Skycons.CLEAR_DAY = function(ctx, t, color) {
662 | var w = ctx.canvas.width,
663 | h = ctx.canvas.height,
664 | s = Math.min(w, h);
665 |
666 | sun(ctx, t, w * 0.5, h * 0.5, s, s * STROKE, color);
667 | };
668 |
669 | Skycons.CLEAR_NIGHT = function(ctx, t, color) {
670 | var w = ctx.canvas.width,
671 | h = ctx.canvas.height,
672 | s = Math.min(w, h);
673 |
674 | moon(ctx, t, w * 0.5, h * 0.5, s, s * STROKE, color);
675 | };
676 |
677 | Skycons.PARTLY_CLOUDY_DAY = function(ctx, t, color) {
678 | var w = ctx.canvas.width,
679 | h = ctx.canvas.height,
680 | s = Math.min(w, h);
681 |
682 | sun(ctx, t, w * 0.625, h * 0.375, s * 0.75, s * STROKE, color);
683 | cloud(ctx, t, w * 0.375, h * 0.625, s * 0.75, s * STROKE, color);
684 | };
685 |
686 | Skycons.PARTLY_CLOUDY_NIGHT = function(ctx, t, color) {
687 | var w = ctx.canvas.width,
688 | h = ctx.canvas.height,
689 | s = Math.min(w, h);
690 |
691 | moon(ctx, t, w * 0.667, h * 0.375, s * 0.75, s * STROKE, color);
692 | cloud(ctx, t, w * 0.375, h * 0.625, s * 0.75, s * STROKE, color);
693 | };
694 |
695 | Skycons.CLOUDY = function(ctx, t, color) {
696 | var w = ctx.canvas.width,
697 | h = ctx.canvas.height,
698 | s = Math.min(w, h);
699 |
700 | cloud(ctx, t, w * 0.5, h * 0.5, s, s * STROKE, color);
701 | };
702 |
703 | Skycons.RAIN = function(ctx, t, color) {
704 | var w = ctx.canvas.width,
705 | h = ctx.canvas.height,
706 | s = Math.min(w, h);
707 |
708 | rain(ctx, t, w * 0.5, h * 0.37, s * 0.9, s * STROKE, color);
709 | cloud(ctx, t, w * 0.5, h * 0.37, s * 0.9, s * STROKE, color);
710 | };
711 |
712 | Skycons.SLEET = function(ctx, t, color) {
713 | var w = ctx.canvas.width,
714 | h = ctx.canvas.height,
715 | s = Math.min(w, h);
716 |
717 | sleet(ctx, t, w * 0.5, h * 0.37, s * 0.9, s * STROKE, color);
718 | cloud(ctx, t, w * 0.5, h * 0.37, s * 0.9, s * STROKE, color);
719 | };
720 |
721 | Skycons.SNOW = function(ctx, t, color) {
722 | var w = ctx.canvas.width,
723 | h = ctx.canvas.height,
724 | s = Math.min(w, h);
725 |
726 | snow(ctx, t, w * 0.5, h * 0.37, s * 0.9, s * STROKE, color);
727 | cloud(ctx, t, w * 0.5, h * 0.37, s * 0.9, s * STROKE, color);
728 | };
729 |
730 | Skycons.WIND = function(ctx, t, color) {
731 | var w = ctx.canvas.width,
732 | h = ctx.canvas.height,
733 | s = Math.min(w, h);
734 |
735 | swoosh(ctx, t, w * 0.5, h * 0.5, s, s * STROKE, 0, 2, color);
736 | swoosh(ctx, t, w * 0.5, h * 0.5, s, s * STROKE, 1, 2, color);
737 | };
738 |
739 | Skycons.FOG = function(ctx, t, color) {
740 | var w = ctx.canvas.width,
741 | h = ctx.canvas.height,
742 | s = Math.min(w, h),
743 | k = s * STROKE;
744 |
745 | fogbank(ctx, t, w * 0.5, h * 0.32, s * 0.75, k, color);
746 |
747 | t /= 5000;
748 |
749 | var a = Math.cos(t * TAU) * s * 0.02,
750 | b = Math.cos((t + 0.25) * TAU) * s * 0.02,
751 | c = Math.cos((t + 0.5) * TAU) * s * 0.02,
752 | d = Math.cos((t + 0.75) * TAU) * s * 0.02,
753 | n = h * 0.936,
754 | e = Math.floor(n - k * 0.5) + 0.5,
755 | f = Math.floor(n - k * 2.5) + 0.5;
756 |
757 | ctx.strokeStyle = color;
758 | ctx.lineWidth = k;
759 | ctx.lineCap = 'round';
760 | ctx.lineJoin = 'round';
761 |
762 | line(ctx, a + w * 0.2 + k * 0.5, e, b + w * 0.8 - k * 0.5, e);
763 | line(ctx, c + w * 0.2 + k * 0.5, f, d + w * 0.8 - k * 0.5, f);
764 | };
765 |
766 | Skycons.prototype = {
767 | _determineDrawingFunction: function(draw) {
768 | if (typeof draw === 'string') draw = Skycons[draw.toUpperCase().replace(/-/g, '_')] || null;
769 |
770 | return draw;
771 | },
772 | add: function(el, draw) {
773 | var obj;
774 |
775 | if (typeof el === 'string') el = document.getElementById(el);
776 |
777 | // Does nothing if canvas name doesn't exists
778 | if (el === null) return;
779 |
780 | draw = this._determineDrawingFunction(draw);
781 |
782 | // Does nothing if the draw function isn't actually a function
783 | if (typeof draw !== 'function') return;
784 |
785 | obj = {
786 | element: el,
787 | context: el.getContext('2d'),
788 | drawing: draw
789 | };
790 |
791 | this.list.push(obj);
792 | this.draw(obj, KEYFRAME);
793 | },
794 | set: function(el, draw) {
795 | var i;
796 |
797 | if (typeof el === 'string') el = document.getElementById(el);
798 |
799 | for (i = this.list.length; i--; )
800 | if (this.list[i].element === el) {
801 | this.list[i].drawing = this._determineDrawingFunction(draw);
802 | this.draw(this.list[i], KEYFRAME);
803 | return;
804 | }
805 |
806 | this.add(el, draw);
807 | },
808 | remove: function(el) {
809 | var i;
810 |
811 | if (typeof el === 'string') el = document.getElementById(el);
812 |
813 | for (i = this.list.length; i--; )
814 | if (this.list[i].element === el) {
815 | this.list.splice(i, 1);
816 | return;
817 | }
818 | },
819 | draw: function(obj, time) {
820 | var canvas = obj.context.canvas;
821 |
822 | if (this.resizeClear) canvas.width = canvas.width;
823 | else obj.context.clearRect(0, 0, canvas.width, canvas.height);
824 |
825 | obj.drawing(obj.context, time, this.color);
826 | },
827 | play: function() {
828 | var self = this;
829 |
830 | this.pause();
831 | this.interval = requestInterval(function() {
832 | var now = Date.now(),
833 | i;
834 |
835 | for (i = self.list.length; i--; ) self.draw(self.list[i], now);
836 | }, 1000 / 60);
837 | },
838 | pause: function() {
839 | if (this.interval) {
840 | cancelInterval(this.interval);
841 | this.interval = null;
842 | }
843 | }
844 | };
845 |
846 | export default Skycons;
847 |
--------------------------------------------------------------------------------