Start porting ten-print header

This commit is contained in:
arne 2022-02-20 17:22:44 +01:00
commit cd96716515

73
src/_helpers/header.mjs Normal file
View file

@ -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