Commit 833c11d6f60087413d4aef03eba96ff9cb0e516d
in the beginning, the moon phases
Michael Williams committed on 2/6/2019, 7:59:42 AMFiles changed
.gitignore | added |
.travis.yml | added |
README.md | added |
example.js | added |
icon.svg | added |
index.js | added |
package.json | added |
test/index.js | added |
.travis.yml | ||
---|---|---|
@@ -1,0 +1,6 @@ | ||
1 … | +language: node_js | |
2 … | +sudo: false | |
3 … | +script: "npm run test:coverage && npm run test:coverage:report" | |
4 … | +after_script: "npm i -g codecov.io && cat ./coverage/lcov.info | codecov" | |
5 … | +notifications: | |
6 … | + email: false |
README.md | ||
---|---|---|
@@ -1,0 +1,29 @@ | ||
1 … | +# solarpunk-icon | |
2 … | + | |
3 … | +a solarpunk icon generated from JavaScript code | |
4 … | + | |
5 … | +```shell | |
6 … | +npm install --save solarpunk-icon | |
7 … | +``` | |
8 … | + | |
9 … | +## usage | |
10 … | + | |
11 … | +### `solarpunkIcon = require('solarpunk-icon')` | |
12 … | + | |
13 … | +## license | |
14 … | + | |
15 … | +The Apache License | |
16 … | + | |
17 … | +Copyright © 2019 Michael Williams | |
18 … | + | |
19 … | +Licensed under the Apache License, Version 2.0 (the "License"); | |
20 … | +you may not use this file except in compliance with the License. | |
21 … | +You may obtain a copy of the License at | |
22 … | + | |
23 … | + http://www.apache.org/licenses/LICENSE-2.0 | |
24 … | + | |
25 … | +Unless required by applicable law or agreed to in writing, software | |
26 … | +distributed under the License is distributed on an "AS IS" BASIS, | |
27 … | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
28 … | +See the License for the specific language governing permissions and | |
29 … | +limitations under the License. |
example.js | ||
---|---|---|
@@ -1,0 +1,3 @@ | ||
1 … | +const solarpunkIcon = require('./') | |
2 … | + | |
3 … | +console.log(solarpunkIcon()) |
icon.svg |
---|
index.js | ||
---|---|---|
@@ -1,0 +1,110 @@ | ||
1 … | +module.exports = solarpunkIcon | |
2 … | + | |
3 … | +function solarpunkIcon () { | |
4 … | + return ` | |
5 … | +<svg | |
6 … | + xmlns="http://www.w3.org/2000/svg" | |
7 … | + xmlns:xlink="http://www.w3.org/1999/xlink" | |
8 … | + viewBox="-1 -1 2 2" | |
9 … | +> | |
10 … | + ${moon.style} | |
11 … | + ${range({ start: 0, stop: 1, step: 1/8 }) | |
12 … | + .map(index => moon({ | |
13 … | + radius: 0.1, | |
14 … | + center: rotate({ angle: index * 2 * Math.PI, point: { x: 0, y: 0.5 } }), | |
15 … | + phase: index | |
16 … | + })) | |
17 … | + .join('\n') | |
18 … | + } | |
19 … | +</svg> | |
20 … | +` | |
21 … | +} | |
22 … | + | |
23 … | +function gear ({ center, numThreads, threadLength, centerLength }) { | |
24 … | + return ` | |
25 … | +<g> | |
26 … | + | |
27 … | +</g> | |
28 … | +` | |
29 … | +} | |
30 … | + | |
31 … | +function rotate ({ center = { x: 0, y: 0}, angle, point }) { | |
32 … | + const a = Math.atan2(point.y - center.y, point.x - center.x) | |
33 … | + const r = Math.sqrt(Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2)) | |
34 … | + return { | |
35 … | + x: r * Math.cos(a + angle), | |
36 … | + y: r * Math.sin(a + angle) | |
37 … | + } | |
38 … | +} | |
39 … | + | |
40 … | +// inspired by https://github.com/tingletech/moon-phase | |
41 … | +function moon ({ radius, center, phase }) { | |
42 … | + var sweep = [] | |
43 … | + var mag | |
44 … | + | |
45 … | + // the "sweep-flag" and the direction of movement change every quarter moon | |
46 … | + // zero and one are both new moon; 0.50 is full moon | |
47 … | + if (phase <= 0.25) { | |
48 … | + sweep = [ 1, 0 ] | |
49 … | + mag = 1 - phase * 4 | |
50 … | + } else if (phase <= 0.50) { | |
51 … | + sweep = [ 0, 0 ] | |
52 … | + mag = (phase - 0.25) * 4 | |
53 … | + } else if (phase <= 0.75) { | |
54 … | + sweep = [ 1, 1 ] | |
55 … | + mag = 1 - (phase - 0.50) * 4 | |
56 … | + } else if (phase <= 1) { | |
57 … | + sweep = [ 0, 1 ] | |
58 … | + mag = (phase - 0.75) * 4 | |
59 … | + } else { | |
60 … | + throw new Error(`unexpected moon phase: ${phase}`) | |
61 … | + } | |
62 … | + | |
63 … | + // http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands | |
64 … | + // http://www.i-programmer.info/programming/graphics-and-imaging/3254-svg-javascript-and-the-dom.html | |
65 … | + | |
66 … | + /* | |
67 … | + var d = "m100,0 "; | |
68 … | + d = d + "a" + mag + ",20 0 1," + sweep[0] + " 0,150 "; | |
69 … | + d = d + "a20,20 0 1," + sweep[1] + " 0,-150"; | |
70 … | + */ | |
71 … | + | |
72 … | + var r = radius / 5 | |
73 … | + | |
74 … | + return ` | |
75 … | + <style type="text/css"> | |
76 … | + .moon { | |
77 … | + stroke: black; | |
78 … | + stroke-width: ${radius / 20}; | |
79 … | + } | |
80 … | + .moon-front { | |
81 … | + fill: white; | |
82 … | + } | |
83 … | + .moon-back { | |
84 … | + fill: purple; | |
85 … | + } | |
86 … | + </style> | |
87 … | + <g class="moon"> | |
88 … | + <path | |
89 … | + class="moon-back" | |
90 … | + d="M ${center.x},${center.y - radius / 2} | |
91 … | + a ${r},${r} 0 1,1 0,${radius} | |
92 … | + a ${r},${r} 0 1,1 0,-${radius}" | |
93 … | + /> | |
94 … | + <path | |
95 … | + class="moon-front" | |
96 … | + d="M ${center.x},${center.y - radius / 2} | |
97 … | + a ${mag * r},${r} 0 1,${sweep[0]} 0,${radius} | |
98 … | + a ${r},${r} 0 1,${sweep[1]} 0,-${radius}" | |
99 … | + /> | |
100 … | + </g> | |
101 … | + ` | |
102 … | + | |
103 … | + // d="m100,0 a20,20 0 1,1 0,150 a20,20 0 1,1 0,-150" | |
104 … | +} | |
105 … | + | |
106 … | +// https://stackoverflow.com/a/44957114 | |
107 … | +function range ({ start = 0, stop, step = 1 }) { | |
108 … | + return Array(Math.ceil((stop - start) / step)) | |
109 … | + .fill(start).map((x, y) => x + y * step) | |
110 … | +} |
package.json | ||
---|---|---|
@@ -1,0 +1,64 @@ | ||
1 … | +{ | |
2 … | + "name": "solarpunk-icon", | |
3 … | + "version": "0.0.0", | |
4 … | + "description": "a solarpunk icon generated from JavaScript code", | |
5 … | + "main": "index.js", | |
6 … | + "scripts": { | |
7 … | + "start": "node-dev example", | |
8 … | + "style:format": "prettier-standard '**/*.js' '**/*.md'", | |
9 … | + "style:lint": "standard", | |
10 … | + "style": "npm-run-all -s style:format style:lint", | |
11 … | + "test:deps": "dependency-check . && dependency-check . --extra --no-dev -i es2040", | |
12 … | + "test:node": "ava", | |
13 … | + "test:coverage": "nyc npm run test:node", | |
14 … | + "test:coverage:report": "nyc report --reporter=lcov npm run test:node", | |
15 … | + "test": "npm-run-all -s test:node style:lint test:deps" | |
16 … | + }, | |
17 … | + "browserify": { | |
18 … | + "transform": [ | |
19 … | + "es2040" | |
20 … | + ] | |
21 … | + }, | |
22 … | + "lint-staged": { | |
23 … | + "linters": { | |
24 … | + "*.js": [ | |
25 … | + "prettier-standard", | |
26 … | + "standard", | |
27 … | + "git add" | |
28 … | + ], | |
29 … | + "*.md": [ | |
30 … | + "prettier-standard", | |
31 … | + "git add" | |
32 … | + ] | |
33 … | + } | |
34 … | + }, | |
35 … | + "standard": { | |
36 … | + "globals": [ | |
37 … | + ] | |
38 … | + }, | |
39 … | + "repository": { | |
40 … | + "type": "git", | |
41 … | + "url": "git+https://github.com/ahdinosaur/solarpunk-icon.git" | |
42 … | + }, | |
43 … | + "keywords": [], | |
44 … | + "author": "Mikey <michael.williams@enspiral.com> (https://dinosaur.is)", | |
45 … | + "license": "Apache-2.0", | |
46 … | + "bugs": { | |
47 … | + "url": "https://github.com/ahdinosaur/solarpunk-icon/issues" | |
48 … | + }, | |
49 … | + "homepage": "https://github.com/ahdinosaur/solarpunk-icon#readme", | |
50 … | + "devDependencies": { | |
51 … | + "ava": "^0.25.0", | |
52 … | + "dependency-check": "^3.1.0", | |
53 … | + "husky": "^0.14.3", | |
54 … | + "lint-staged": "^7.0.5", | |
55 … | + "node-dev": "^3.1.3", | |
56 … | + "npm-run-all": "^4.0.1", | |
57 … | + "nyc": "^11.7.1", | |
58 … | + "prettier-standard": "^8.0.1", | |
59 … | + "standard": "^11.0.1" | |
60 … | + }, | |
61 … | + "dependencies": { | |
62 … | + "es2040": "^1.2.3" | |
63 … | + } | |
64 … | +} |
Built with git-ssb-web