module.exports = solarpunkIcon function solarpunkIcon () { return ` ${plants({ size: 0.25, offsetRadius: 0.2 })} ${gear({ offsetRadius: 0.15, toothLength: 0.3, toothWidth: 0.2 })} ${moons({ moonRadius: 0.2, offsetRadius: 0.7 })} ` } function gear ({ offsetRadius, toothLength, toothWidth }) { return ` ${range({ start: 0, stop: 1, step: 1 / 8 }) .map(index => gearTooth({ angle: (1 / 16 + index) * 2 * Math.PI, offset: offsetRadius, length: toothLength, width: toothWidth })) .join('\n') } ` } function gearTooth ({ angle, offset, length, width }) { return ` ` } function plants ({ size, offsetRadius }) { return ` ${range({ start: 0, stop: 1, step: 1 / 8 }) .map(index => plant({ size, angle: index * 2 * Math.PI, offsetRadius })) .join('\n') } ` } function plant ({ size, angle, offsetRadius }) { return ` ${plantStem({ size, direction: 1 })} ${plantStem({ size, direction: -1 })} ${plantLeaf({ size, direction: 1 })} ${plantLeaf({ size, direction: -1 })} ` } function plantStem ({ size, direction }) { return ` ` } function plantLeaf ({ size, direction }) { return ` ` } function moons ({ moonRadius, offsetRadius }) { return ` ${range({ start: 0, stop: 1, step: 1 / 8 }) .map(index => moon({ radius: moonRadius, center: rotate({ angle: index * 2 * Math.PI, point: { x: 0, y: offsetRadius } }), phase: index })) .join('\n') } ` } // inspired by https://github.com/tingletech/moon-phase function moon ({ radius, center, phase }) { var sweep = [] var mag // the "sweep-flag" and the direction of movement change every quarter moon // zero and one are both new moon; 0.50 is full moon if (phase <= 0.25) { sweep = [ 1, 0 ] mag = 1 - phase * 4 } else if (phase <= 0.50) { sweep = [ 0, 0 ] mag = (phase - 0.25) * 4 } else if (phase <= 0.75) { sweep = [ 1, 1 ] mag = 1 - (phase - 0.50) * 4 } else if (phase <= 1) { sweep = [ 0, 1 ] mag = (phase - 0.75) * 4 } else { throw new Error(`unexpected moon phase: ${phase}`) } // http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands // http://www.i-programmer.info/programming/graphics-and-imaging/3254-svg-javascript-and-the-dom.html var r = radius / 5 return ` ` } function rotate ({ center = { x: 0, y: 0 }, angle, point }) { const a = Math.atan2(point.y - center.y, point.x - center.x) const r = Math.sqrt(Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2)) return { x: r * Math.cos(a + angle), y: r * Math.sin(a + angle) } } // https://stackoverflow.com/a/44957114 function range ({ start = 0, stop, step = 1 }) { return Array(Math.ceil((stop - start) / step)) .fill(start).map((x, y) => x + y * step) }