Get occasional updates about new fonts, designs and other interesting things.
import * as random from "/scratchpad/_lib/random.asset.mjs"
import posterize from "/scratchpad/posterize/posterize.asset.mjs"
const repeat = (length, fn) => {
  Array.from({ length }).forEach((t, i) => {
    fn(i, length)
  })
}
const shape = (ctx, r, dir = 1) => {
  const x = random.wobble(4)
  const y = random.wobble(4)
  let r1 = r * random.number(1, 1.2)
  let r2 = r * random.number(0.7, 1)
  let variance = Math.abs(r2 / r1)
  variance = Math.min(variance, 1 / variance)
  if (variance < 0.2) {
    ctx.arc(0, 0, Math.abs(r2), 0, Math.PI * 2, dir < 0)
  } else {
    let points = random.integer(8, 19)
    for (let i = 0; i < points; i++) {
      const angle =
        random.number(Math.PI) +
        ((i * 2 * Math.PI) / (points % 2 == 0 ? points : points - 1)) * dir
      r = i % 2 === 0 ? r1 : r2
      ctx[i === 0 ? "moveTo" : "lineTo"](
        x + r * Math.cos(angle),
        y + r * Math.sin(angle)
      )
    }
  }
}
const palette = () => ({
  white: "white",
  yolk: [random.integer(220, 225), random.integer(128, 158), 0].reduce(
    (m, d) => m + ("0" + d.toString(16)).slice(-2),
    "#"
  ),
})
export default (ctx, dimensions, smooth = true) => {
  const { x, y, width, height } = dimensions
  const size = Math.min(width, height)
  const colors = palette()
  ctx.save()
  ctx.translate(x + width / 2, y + height / 2)
  ctx.beginPath()
  repeat(random.integer(50, 70), (i, length) => {
    const r = (size * 0.4 * (i + 1)) / length
    shape(ctx, r, i % 2 ? 1 : -1)
  })
  ctx.fillStyle = colors.white
  ctx.fill()
  ctx.beginPath()
  repeat(random.integer(20, 50), (i, length) => {
    const r = ((size / 2) * 0.4 * (i + 1)) / length
    shape(ctx, r, i % 2 ? 1 : -1)
  })
  ctx.fillStyle = colors.yolk
  ctx.fill()
  if (smooth) {
    posterize({
      ctx,
      radius: size * 0.04,
      iterations: 3,
      ramp: 300,
      colors: [colors.yolk, colors.white],
      overshoot: 1,
      x,
      y,
      width,
      height,
    })
  }
  ctx.restore()
  return { colors }
}