Basic hitomezashi pattern

This commit is contained in:
arne 2024-07-18 21:39:48 +02:00
commit b797f66721
12 changed files with 2345 additions and 0 deletions

76
src/main.ts Normal file
View file

@ -0,0 +1,76 @@
import { line, group, translate, asSvg, svgDoc } from "@thi.ng/geom";
import { $canvas } from "@thi.ng/rdom-canvas";
import { reactive } from "@thi.ng/rstream";
import { cycle, takeWhile, comp, mapIndexed, transduce, push, map } from "@thi.ng/transducers"
const xs = cycle([0,1,0,1,0,1])
const ys = cycle([1,0,1,1,0,1])
const cellSize = 25
// available size for a2: 420 * 594
const width = 420
const height = 594
const minPadding = cellSize
// calculate available drawing area
const xCells = Math.floor((width - 2 * minPadding) / cellSize)
const xPadding = (width - (xCells * cellSize)) / 2
const yCells = Math.floor((height - 2 * minPadding) / cellSize)
const yPadding = (height - (yCells * cellSize)) / 2
const size = [width, height]
// build a list of start positions
const startPoints = (pattern: Iterable<number>, maxCoord: number) =>
transduce(
comp(
mapIndexed((cell, val) => [cell * cellSize, val] as const),
takeWhile(([coord, _]) => coord <= maxCoord),
),
push(),
pattern
)
const xStarts = startPoints(xs, width - 2 * xPadding)
const yStarts = startPoints(ys, height - 2 * yPadding)
const yLines = xStarts.flatMap(
([xCoord, val]: [number, number]) =>
Array
.from({ length: yCells })
.map((_, cell) => (cell + val) % 2 === 0 // start at the beginning or skip it
? line([xCoord, cell * cellSize], [xCoord, (cell + 1) * cellSize])
: null)
.filter(v => v != null)
)
console.log({ xStarts, yStarts })
const xLines = yStarts.flatMap(
([yCoord, val]: [number, number]) =>
Array
.from({ length: xCells })
.map((_, cell) => (cell + val) % 2 === 0 // start at the beginning or skip it
? line([cell * cellSize, yCoord], [(cell + 1) * cellSize, yCoord])
: null)
.filter(v => v != null)
)
const scene = reactive(
translate(
group(
{__background: '#eee', stroke: '#222' },
[...yLines, ...xLines]
),
[xPadding, yPadding]
)
)
$canvas(scene, size).mount(document.body)
// console.log(asSvg(svgDoc({ viewBox: `0 0 ${size[0]} ${size[1]}` }, scene.deref())))

1
src/vite-env.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="vite/client" />