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