git ssb

0+

dinoworm ๐Ÿ› / solarpunk-icon



Tree: 3bbf848a52801dc212408be047c6d41ea59e312e

Files: 3bbf848a52801dc212408be047c6d41ea59e312e / index.js

4575 bytesRaw
1module.exports = solarpunkIcon
2
3function 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 ${plants({ size: 0.25, offsetRadius: 0.2 })}
11 ${gear({ offsetRadius: 0.15, toothLength: 0.3, toothWidth: 0.2 })}
12 ${moons({ moonRadius: 0.1, offsetRadius: 0.7 })}
13 </svg>
14 `
15}
16
17function gear ({ offsetRadius, toothLength, toothWidth }) {
18 return `
19 <style type="text/css">
20 .gear {
21 stroke: black;
22 stroke-width: ${toothLength / 20};
23 }
24 .gear-tooth {
25 fill: purple;
26 }
27 </style>
28 <g class="gear">
29 ${range({ start: 0, stop: 1, step: 1/8 })
30 .map(index => gearTooth({
31 angle: (1/16 + index) * 2 * Math.PI,
32 offset: offsetRadius,
33 length: toothLength,
34 width: toothWidth
35 }))
36 .join('\n')
37 }
38 </g>
39 `
40}
41
42function gearTooth ({ angle, offset, length, width }) {
43 return `
44 <g
45 class="gear-tooth"
46 transform="rotate(${angle * 180 / Math.PI})"
47 >
48 <rect x="${-width / 2}" y="${offset}" height="${length}" width="${width}" />
49 </g>
50 `
51}
52
53function plants ({ size, offsetRadius }) {
54 return `
55 <style type="text/css">
56 .plant {
57 stroke: black;
58 stroke-width: ${size / 20};
59 }
60 .plant-stem {
61 fill: none;
62 }
63 </style>
64 ${range({ start: 0, stop: 1, step: 1/8 })
65 .map(index => plant({
66 size,
67 angle: index * 2 * Math.PI,
68 offsetRadius
69 }))
70 .join('\n')
71 }
72 `
73}
74
75function plant ({ size, angle, offsetRadius }) {
76 return `
77 <g
78 class="plant"
79 transform="
80 rotate(${angle * 180 / Math.PI})
81 translate(0, ${offsetRadius})
82 "
83 >
84 <path class="plant-stem"
85 d="
86 M 0,0
87 L 0,${size}
88 "
89 />
90 <path class="plant-stem"
91 d="
92 M 0,${size * 0.9}
93 C 0,${size * 0.8} 0,${size * 1.2} ${size * 0.3},${size * 1.4}
94 "
95 />
96 <path class="plant-stem"
97 d="
98 M 0,${size * 0.9}
99 C 0,${size * 0.8} 0,${size * 1.2} ${size * -0.3},${size * 1.4}
100 "
101 />
102 </g>
103 `
104}
105
106function moons ({ moonRadius, offsetRadius }) {
107 return `
108 <style type="text/css">
109 .moon {
110 stroke: black;
111 stroke-width: ${moonRadius / 20};
112 }
113 .moon-front {
114 fill: white;
115 }
116 .moon-back {
117 fill: purple;
118 }
119 </style>
120 ${range({ start: 0, stop: 1, step: 1/8 })
121 .map(index => moon({
122 radius: moonRadius,
123 center: rotate({ angle: index * 2 * Math.PI, point: { x: 0, y: offsetRadius } }),
124 phase: index
125 }))
126 .join('\n')
127 }
128 `
129}
130
131// inspired by https://github.com/tingletech/moon-phase
132function moon ({ radius, center, phase }) {
133 var sweep = []
134 var mag
135
136 // the "sweep-flag" and the direction of movement change every quarter moon
137 // zero and one are both new moon; 0.50 is full moon
138 if (phase <= 0.25) {
139 sweep = [ 1, 0 ]
140 mag = 1 - phase * 4
141 } else if (phase <= 0.50) {
142 sweep = [ 0, 0 ]
143 mag = (phase - 0.25) * 4
144 } else if (phase <= 0.75) {
145 sweep = [ 1, 1 ]
146 mag = 1 - (phase - 0.50) * 4
147 } else if (phase <= 1) {
148 sweep = [ 0, 1 ]
149 mag = (phase - 0.75) * 4
150 } else {
151 throw new Error(`unexpected moon phase: ${phase}`)
152 }
153
154 // http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
155 // http://www.i-programmer.info/programming/graphics-and-imaging/3254-svg-javascript-and-the-dom.html
156
157 var r = radius / 5
158
159 return `
160 <g class="moon">
161 <path
162 class="moon-back"
163 d="M ${center.x},${center.y - radius / 2}
164 a ${r},${r} 0 1,1 0,${radius}
165 a ${r},${r} 0 1,1 0,-${radius}"
166 />
167 <path
168 class="moon-front"
169 d="M ${center.x},${center.y - radius / 2}
170 a ${mag * r},${r} 0 1,${sweep[0]} 0,${radius}
171 a ${r},${r} 0 1,${sweep[1]} 0,-${radius}"
172 />
173 </g>
174 `
175}
176
177function rotate ({ center = { x: 0, y: 0}, angle, point }) {
178 const a = Math.atan2(point.y - center.y, point.x - center.x)
179 const r = Math.sqrt(Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2))
180 return {
181 x: r * Math.cos(a + angle),
182 y: r * Math.sin(a + angle)
183 }
184}
185
186
187// https://stackoverflow.com/a/44957114
188function range ({ start = 0, stop, step = 1 }) {
189 return Array(Math.ceil((stop - start) / step))
190 .fill(start).map((x, y) => x + y * step)
191}
192

Built with git-ssb-web