Allow width and height to be dynamic
This commit is contained in:
parent
0e42f55324
commit
49ec5de609
1 changed files with 63 additions and 26 deletions
89
src/main.ts
89
src/main.ts
|
|
@ -2,32 +2,38 @@ import { line, type Line, group, translate, asSvg, svgDoc, scale, flip } from "@
|
|||
import { vec2, type Vec2 } from "@thi.ng/vectors"
|
||||
import { $canvas } from "@thi.ng/rdom-canvas";
|
||||
import { reactive, sync } from "@thi.ng/rstream";
|
||||
import { $compile, $input } from '@thi.ng/rdom'
|
||||
import { $compile, $input, $inputNum } from '@thi.ng/rdom'
|
||||
import { cycle, comp, range, iterator, map, mapcat, reverse, zip } from "@thi.ng/transducers"
|
||||
|
||||
const cellSize_ = "12"
|
||||
const xs_ = "101110100101100"
|
||||
const ys_ = "101001111001110000101"
|
||||
// initial settings
|
||||
|
||||
const parsePattern = (pattern: string) => pattern.split('').map(x => Number.parseInt(x, 10))
|
||||
// available size for a2: 420 * 594
|
||||
const width_ = 420
|
||||
const height_ = 594
|
||||
const cellSize_ = 12
|
||||
|
||||
const xSeeds = reactive(xs_).map((pattern) => parsePattern(pattern))
|
||||
const ySeeds = reactive(ys_).map((pattern) => parsePattern(pattern))
|
||||
const cellSize = reactive(cellSize_).map(num => {
|
||||
const next = Number.parseInt(num, 10)
|
||||
return Number.isNaN(next)|| next < 5 ? 5 : next
|
||||
})
|
||||
const xSeeds_ = "101110100101100"
|
||||
const ySeeds_ = "101001111001110000101"
|
||||
const unit_ = 'mm'
|
||||
|
||||
// turn these into reactive values to trigger re-rendering on change
|
||||
|
||||
const width = reactive(width_)
|
||||
const height = reactive(height_)
|
||||
const unit = reactive(unit_)
|
||||
const size = sync({ src: { width, height } }).map(({ width, height }) => [width, height])
|
||||
|
||||
const toNumber = (v: any) => typeof v === 'number' ? v : Number.parseInt(v, 10)
|
||||
const parsePattern = (pattern: string) => pattern.split('').map(toNumber)
|
||||
|
||||
const xSeeds = reactive(xSeeds_).map((pattern) => parsePattern(pattern))
|
||||
const ySeeds = reactive(ySeeds_).map((pattern) => parsePattern(pattern))
|
||||
const cellSize = reactive(cellSize_).map(num => Number.isNaN(num) || num < 5 ? 5 : num) // restrict cells to be at least 5 $unit
|
||||
|
||||
// const backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--background-color')
|
||||
const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color')
|
||||
const secondaryColor = getComputedStyle(document.documentElement).getPropertyValue('--secondary-color')
|
||||
|
||||
// available size for a2: 420 * 594
|
||||
const width = 420
|
||||
const height = 594
|
||||
|
||||
const size = [width, height]
|
||||
|
||||
// some explanation for what's happening below:
|
||||
//
|
||||
// - a coord is a position on a single axis
|
||||
|
|
@ -71,8 +77,19 @@ const generateLines = (maxCoordOnAxis: number, maxCoordPerpendicular: number, se
|
|||
// now we can put the functions above together based on the current settings and generate a scene to be drawn
|
||||
|
||||
const scene = sync({
|
||||
src: { cellSize, xSeeds, ySeeds, }
|
||||
}).map(({ cellSize, xSeeds, ySeeds }) => {
|
||||
src: {
|
||||
size,
|
||||
cellSize,
|
||||
xSeeds,
|
||||
ySeeds,
|
||||
}
|
||||
}).map(({
|
||||
size,
|
||||
cellSize,
|
||||
xSeeds,
|
||||
ySeeds,
|
||||
}) => {
|
||||
const [width, height] = size
|
||||
const minPadding = cellSize
|
||||
|
||||
// calculate available drawing area
|
||||
|
|
@ -85,15 +102,13 @@ const scene = sync({
|
|||
const xLines = [...map(l => scale(l, cellSize), generateLines(yCells, xCells, cycle(ySeeds), xLineGen))]
|
||||
const yLines = [...map(l => scale(l, cellSize), generateLines(xCells, yCells, cycle(xSeeds), yLineGen))]
|
||||
|
||||
const scene = translate(
|
||||
return translate(
|
||||
group(
|
||||
{ __background: primaryColor, stroke: secondaryColor },
|
||||
[...yLines, ...xLines]
|
||||
),
|
||||
[xPadding, yPadding]
|
||||
)
|
||||
|
||||
return scene
|
||||
})
|
||||
|
||||
const input = (label: string, attrs: any) =>
|
||||
|
|
@ -106,25 +121,47 @@ $compile(
|
|||
$canvas(scene, size)],
|
||||
["aside", {},
|
||||
["h2", {}, "Settings"],
|
||||
input("Canvas width:", {
|
||||
type: "number",
|
||||
min: "10",
|
||||
value: width.deref()!,
|
||||
oninput: $inputNum(width),
|
||||
}),
|
||||
input("Canvas height:", {
|
||||
type: "number",
|
||||
min: "10",
|
||||
value: height.deref()!,
|
||||
oninput: $inputNum(height),
|
||||
}),
|
||||
input("Grid size: ", {
|
||||
type: "number",
|
||||
min: "5",
|
||||
value: cellSize.deref()!,
|
||||
oninput: $input(cellSize)
|
||||
oninput: $inputNum(cellSize),
|
||||
}),
|
||||
input("X Pattern: ", {
|
||||
type: "text",
|
||||
value: xs_,
|
||||
value: xSeeds_,
|
||||
oninput: $input(xSeeds)
|
||||
}),
|
||||
input("Y Pattern: ", {
|
||||
type: "text",
|
||||
value: ys_,
|
||||
value: ySeeds_,
|
||||
oninput: $input(ySeeds)
|
||||
}),
|
||||
["h2", {}, "SVG Export"],
|
||||
["div", {}, ["textarea", {
|
||||
value: scene.map((scene) => asSvg(svgDoc({ viewBox: `0 0 ${size[0]} ${size[1]}` }, scene))),
|
||||
value: sync({
|
||||
src: {
|
||||
scene,
|
||||
size,
|
||||
unit,
|
||||
}
|
||||
}).map(({
|
||||
scene,
|
||||
size,
|
||||
unit
|
||||
}) => asSvg(svgDoc({ width: `${size[0]}${unit}`, height: `${size[1]}${unit}`, viewBox: `0 0 ${size[0]} ${size[1]}` }, scene))),
|
||||
cols: 80,
|
||||
rows: 20
|
||||
}]]]]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue