{"version":3,"sources":["door-looks.mjs"],"sourcesContent":["// THE DOORS' AND RUNGS' LOOKS (the owner's picks from the texture review, Oct 20: artifact 4SWjXzKVJ99knvkRBQ6Ccj). Each\n// face is drawn on a canvas in its material's colour, at the piece's own proportions, the way the review page drew it:\n//   a wooden door or leaf     louvred (angled slats in a frame)\n//   a metal door or leaf      riveted (a plate with a seam and rows of rivets)\n//   a Glass Door              clear Reinforced Glass in its metal frame (the pane is the glass bit's own look)\n//   a hatch                   planks (boards across it), of its wood or metal\n//   a shutter's slats         perforated (fine slats with rows of holes); its housing a plain box of its metal\n//   handles                   a knob on each half; the halves meet flush; panels half a kube thick (a bit)\n//   rungs                     a staple, close to the wall, in its metal's own look\n// An open door FOLDS LIKE AN ACCORDION (the owner, Oct 20): the face is squeezed across its folded width and creased\n// (system-view.js DOOR_FACE_GLSL draws the creases from the fold amount; this only paints the flat face).\n// An atlas of two tiles, side by side: the face, and the plain edge. Browser only (it draws on a canvas).\nimport { WOODS } from './doors.mjs';\n\nexport const DOOR_LOOKS = Object.freeze({ wood: 'louvred', metal: 'riveted', glass: 'clear', hatch: 'planks', shutter: 'perforated', housing: 'box', handle: 'knob', seam: 'flush', thick: 'half', rung: 'staple', rungFinish: 'plate' });\nexport const isWoodMaterial = (m) => WOODS.includes(m);\n// the face a panel wears, by its kind and material\nexport const faceLookOf = (kind, mat) => (kind === 'hatch' ? 'planks' : kind === 'shutter' ? 'perforated' : isWoodMaterial(mat) ? 'louvred' : 'riveted');\n// a face tile's size in pixels for its piece's proportions (u across, v up): a door's half, a leaf, a hatch half, a section\nexport const tileSizeOf = (kind) => (kind === 'door' || kind === 'glass' ? [64, 256] : kind === 'double' ? [128, 256] : kind === 'hatch' ? [128, 64] : [128, 128]);\n\nconst hexRgb = (h) => [1, 3, 5].map((i) => parseInt(String(h || '#888888').slice(i, i + 2), 16) || 0);\nconst tone = (h, k, a = 1) => { const c = hexRgb(h).map((v) => Math.max(0, Math.min(255, Math.round(v * k)))); return `rgba(${c[0]},${c[1]},${c[2]},${a})`; };\nconst rnd = (s) => { let x = s | 0 || 1; return () => { x ^= x << 13; x ^= x >>> 17; x ^= x << 5; return ((x >>> 0) % 10000) / 10000; }; };\nconst grain = (g, hx, w, h, seed) => { const r = rnd(seed); g.fillStyle = tone(hx, 1); g.fillRect(0, 0, w, h);\n  for (let i = 0; i < Math.round(h / 3); i++) { g.strokeStyle = tone(hx, 0.7 + r() * 0.2, 0.5); g.lineWidth = 1; const y = r() * h; g.beginPath(); for (let x = 0; x <= w; x += 4) g.lineTo(x, y + Math.sin(x / 9 + i) * 2); g.stroke(); } };\nconst plate = (g, hx, w, h, seed) => { const r = rnd(seed); g.fillStyle = tone(hx, 1); g.fillRect(0, 0, w, h);\n  for (let i = 0; i < w * h / 14; i++) { g.fillStyle = tone(hx, 0.85 + r() * 0.3, 0.35); g.fillRect(r() * w, r() * h, 1, 1); } };\nconst FACES = {\n  louvred: (g, hx, w, h) => { g.fillStyle = tone(hx, 0.5); g.fillRect(0, 0, w, h); const step = Math.max(6, Math.round(h / 36));\n    for (let y = 3; y < h - 3; y += step) { g.fillStyle = tone(hx, 1.05); g.fillRect(4, y, w - 8, step - 3); g.fillStyle = tone(hx, 0.75); g.fillRect(4, y + step - 3, w - 8, 1); }\n    g.strokeStyle = tone(hx, 0.8); g.lineWidth = 4; g.strokeRect(2, 2, w - 4, h - 4); },\n  riveted: (g, hx, w, h) => { plate(g, hx, w, h, 3); g.strokeStyle = tone(hx, 0.62); g.lineWidth = 2; g.strokeRect(1, 1, w - 2, h - 2);\n    g.fillStyle = tone(hx, 0.68); g.fillRect(0, h / 2 - 1, w, 2);\n    const rows = [5, h / 2 - 6, h / 2 + 6, h - 5];\n    for (const y of rows) for (let x = 6; x < w - 2; x += 10) { g.fillStyle = tone(hx, 1.3); g.beginPath(); g.arc(x, y, 1.8, 0, 7); g.fill(); g.fillStyle = tone(hx, 0.6); g.beginPath(); g.arc(x + 0.7, y + 0.7, 1, 0, 7); g.fill(); } },\n  planks: (g, hx, w, h) => { grain(g, hx, w, h, 7); const n = Math.max(3, Math.round(w / 24)); for (let k = 1; k < n; k++) { const x = Math.round(k * w / n); g.fillStyle = tone(hx, 0.45); g.fillRect(x - 1, 0, 2, h); } },\n  perforated: (g, hx, w, h) => { plate(g, hx, w, h, 5); for (let y = 0; y < h; y += 6) { g.fillStyle = tone(hx, 0.55); g.fillRect(0, y, w, 1); g.fillStyle = tone(hx, 1.2, 0.6); g.fillRect(0, y + 1, w, 1); }\n    for (let y = 3; y < h; y += 12) for (let x = 5; x < w; x += 9) { g.fillStyle = 'rgba(10,12,16,0.85)'; g.fillRect(x, y, 2, 2); } },\n};\n// THE ATLAS for one kind in one material: [face | edge], each tile tileSizeOf(kind). Returns a canvas.\nexport function doorFaceAtlas(kind, mat, hex, doc = globalThis.document) {\n  const [tw, th] = tileSizeOf(kind), c = doc.createElement('canvas'); c.width = tw * 2; c.height = th;\n  const g = c.getContext('2d');\n  (FACES[faceLookOf(kind, mat)] || FACES.riveted)(g, hex, tw, th);\n  g.save(); g.translate(tw, 0); (isWoodMaterial(mat) ? grain : plate)(g, hex, tw, th, 11); g.fillStyle = 'rgba(0,0,0,0.12)'; g.fillRect(0, 0, tw, th); g.restore();\n  return c;\n}\n// A RUNG'S SHAPE (the owner's pick: a staple), in its cell's frame: [lat0, lat1, h0, h1, out0, out1] boxes, out measured\n// from the wall's face, h about the rung's middle height.\nexport const RUNG_STAPLE = Object.freeze([[0.15, 0.85, -0.04, 0.04, 0.22, 0.3], [0.15, 0.22, -0.04, 0.04, 0, 0.22], [0.78, 0.85, -0.04, 0.04, 0, 0.22]]);\n"],"mappings":"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","names":[],"file":"door-looks.mjs"}