diff --git a/src/_helpers/header.mjs b/src/_helpers/header.mjs new file mode 100644 index 0000000..0f45e8c --- /dev/null +++ b/src/_helpers/header.mjs @@ -0,0 +1,73 @@ +const crypto = require('crypto') +const seedrandom = require('seedrandom') +const { range } = require('lodash') +// const { serialize } = require('@thi.ng/hiccup') + +/** + * Given a pair of coordinates representing the center, returns the cartesian + * coordinate for a straight line drawn at radian angle `alpha` with + * length `len`. + * + * @param cx number + * @param cy number + * @param radius number + * @param alpha number + * @return number[] + */ +const polarToCartesian = (cx, cy, radius, alpha) => + [cx + (radius * Math.cos(alpha)), + cy + (radius * Math.cos(alpha))] + +/** + * Draws an svg arc with the given radius with a center at `c-x` and `c-y`. Note + * that `start` and `end` have to be given in radians. Due to limitations in SVG + * angles at exactly (* 2 math/pi) are not possible. + * + * @param cx number + * @param cy number + * @param radius number + * @param alpha number + * @return hiccup + */ +const arc = (cx, cy, radius, start, end) => { + const isLargeArc = end - start <= Math.PI + const [ x1, y1 ] = polarToCartesian(cx, cy, radius, end) + const [ x2, y2 ] = polarToCartesian(cx, cy, radius, start) + const f = n => n.toFixed(2) + return ["path", {"d": `M ${f(x1)} ${f(y1)} A ${radius} ${radius} 0 ${isLargeArc ? '0' : '1'} 0 ${f(x2)} ${f(y2)}`}] +} + +const numTiles = 10 +const width = 500 +const height = 500 +const halfPi = Math.PI / 2 + +/** + * Generates a unique SVG pattern for some given content. + * + * @param content string + * @return string + */ +const tenPrint = content => { + const hash = crypto.createHash('sha256').update(content).digest('hex') + const seed = Number.parseInt(hash, 16) + const random = seedrandom(seed) + const radius = width / numTiles / 2 + const xs = range(numTiles + 1).map(x => width * (x / numTiles)) + const ys = range(numTiles + 1).map(y => width * (y / numTiles)) + + return ["svg.ten-print", + {"viewBox": `${-radius} ${-radius} ${width + 2*radius} ${height + 2*radius}`, + "xmlns": "http://www.w3.org/2000/svg", + "style": "overflow: visible"} + ["style", "path { fill: none; stroke: none; }"] // avoid flash of unstyled content + ["g", {"transform": "translate(0.5, 0.5"}, + ys.map(y => + xs.map(x => { + const startAngle = random() < 0.5 ? halfPi : 0 + return arc(x, y, radius, startAngle, startAngle + 3 * halfPi) + }) + )]] +} + +module.exports = content => content