git ssb

0+

dinoworm ๐Ÿ› / solarpunk-icon



Tree: cb5a52b55aa645ec97e69005be26cc9ecb027e87

Files: cb5a52b55aa645ec97e69005be26cc9ecb027e87 / index.js

4921 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.2, 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 .plant-leaf {
64 fill: green;
65 }
66 </style>
67 ${range({ start: 0, stop: 1, step: 1 / 8 })
68 .map(index => plant({
69 size,
70 angle: index * 2 * Math.PI,
71 offsetRadius
72 }))
73 .join('\n')
74}
75 `
76}
77
78function plant ({ size, angle, offsetRadius }) {
79 return `
80 <g
81 class="plant"
82 transform="
83 rotate(${angle * 180 / Math.PI})
84 translate(0, ${offsetRadius})
85 "
86 >
87 <path class="plant-stem"
88 d="
89 M 0,0
90 L 0,${size}
91 "
92 />
93 ${plantStem({ size, direction: 1 })}
94 ${plantStem({ size, direction: -1 })}
95 ${plantLeaf({ size, direction: 1 })}
96 ${plantLeaf({ size, direction: -1 })}
97 </g>
98 `
99}
100
101function plantStem ({ size, direction }) {
102 return `
103 <path class="plant-stem"
104 d="
105 M 0,${size * 0.9}
106 C 0,${size * 0.8} 0,${size * 1.2} ${size * direction * 0.3},${size * 1.4}
107 "
108 />
109 `
110}
111
112function plantLeaf ({ size, direction }) {
113 return `
114 <path class="plant-leaf"
115 d="
116 M ${size * direction * 0.3},${size * 1.4}
117 a ${size},${size} -45 0,0 ${size * direction * 0.8},${size * 0.6}
118 A ${size},${size} -45 0,0 ${size * direction * 0.3},${size * 1.4}
119 "
120 />
121 `
122}
123
124function moons ({ moonRadius, offsetRadius }) {
125 return `
126 <style type="text/css">
127 .moon {
128 stroke: black;
129 stroke-width: ${moonRadius / 20};
130 }
131 .moon-front {
132 fill: white;
133 }
134 .moon-back {
135 fill: purple;
136 }
137 </style>
138 ${range({ start: 0, stop: 1, step: 1 / 8 })
139 .map(index => moon({
140 radius: moonRadius,
141 center: rotate({ angle: index * 2 * Math.PI, point: { x: 0, y: offsetRadius } }),
142 phase: index
143 }))
144 .join('\n')
145}
146 `
147}
148
149// inspired by https://github.com/tingletech/moon-phase
150function moon ({ radius, center, phase }) {
151 var sweep = []
152 var mag
153
154 // the "sweep-flag" and the direction of movement change every quarter moon
155 // zero and one are both new moon; 0.50 is full moon
156 if (phase <= 0.25) {
157 sweep = [ 1, 0 ]
158 mag = 1 - phase * 4
159 } else if (phase <= 0.50) {
160 sweep = [ 0, 0 ]
161 mag = (phase - 0.25) * 4
162 } else if (phase <= 0.75) {
163 sweep = [ 1, 1 ]
164 mag = 1 - (phase - 0.50) * 4
165 } else if (phase <= 1) {
166 sweep = [ 0, 1 ]
167 mag = (phase - 0.75) * 4
168 } else {
169 throw new Error(`unexpected moon phase: ${phase}`)
170 }
171
172 // http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
173 // http://www.i-programmer.info/programming/graphics-and-imaging/3254-svg-javascript-and-the-dom.html
174
175 var r = radius / 5
176
177 return `
178 <g class="moon">
179 <path
180 class="moon-back"
181 d="M ${center.x},${center.y - radius / 2}
182 a ${r},${r} 0 1,1 0,${radius}
183 a ${r},${r} 0 1,1 0,-${radius}"
184 />
185 <path
186 class="moon-front"
187 d="M ${center.x},${center.y - radius / 2}
188 a ${mag * r},${r} 0 1,${sweep[0]} 0,${radius}
189 a ${r},${r} 0 1,${sweep[1]} 0,-${radius}"
190 />
191 </g>
192 `
193}
194
195function rotate ({ center = { x: 0, y: 0 }, angle, point }) {
196 const a = Math.atan2(point.y - center.y, point.x - center.x)
197 const r = Math.sqrt(Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2))
198 return {
199 x: r * Math.cos(a + angle),
200 y: r * Math.sin(a + angle)
201 }
202}
203
204// https://stackoverflow.com/a/44957114
205function range ({ start = 0, stop, step = 1 }) {
206 return Array(Math.ceil((stop - start) / step))
207 .fill(start).map((x, y) => x + y * step)
208}
209

Built with git-ssb-web