feat: add reusable custom decor images

Issue: #51
User-Visible: yes
This commit is contained in:
Sergey Matyunin
2026-09-02 21:56:04 +00:00
committed by claude[bot]
parent 09accce808
commit dc95563d96
62 changed files with 3489 additions and 1120 deletions
+14
View File
@@ -411,6 +411,20 @@ export const CONFIG_FIELD_REGISTRY = Object.freeze([
migration: 'none',
compatibility: 'unknown symbols render as generic box; assets ship with the bundle',
},
{
id: "spaces[].decor[]<kind='image'>",
selector: { path: ['spaces', '*', 'decor', '*', 'kind'], equals: 'image' },
storage: 'House Plan server config + content-addressed houseplan/assets store',
type: 'decor item variant: asset_id + box (x, y, w, h, angle, opacity, flip_h, flip_v)',
default: 'n/a',
level: 'space',
ui: 'Background editor Image palette (#51)',
runtime: 'full/static decor projection through verified signed content',
introduced: 'v1.71.0',
status: 'current',
migration: 'none — additive record; file bytes are never embedded in config',
compatibility: 'capability-gated writes; missing bytes keep an editor repair placeholder',
},
{
id: "spaces[].openings[].host=partition",
selector: { path: ['spaces', '*', 'openings', '*', 'host', 'kind'], equals: 'partition' },
+5 -2
View File
@@ -1428,7 +1428,7 @@ const MUTANT_DEFINITIONS = [
+ 'decodes unwarned and kills the tablet tab (#39 AC1)',
patches: [{
file: 'src/backdrop-pick.ts',
find: " if (probe.kind === 'safe') return { kind: 'pass', ext };",
find: " if (probe.kind === 'safe' && file.size <= guardAboveBytes) return { kind: 'pass', ext };",
replace: " return { kind: 'pass', ext };",
}],
},
@@ -3244,13 +3244,16 @@ const MUTANT_DEFINITIONS = [
replace: ' spaceModels, roomCenter, defaultPositions, markerPos, labelPos, spaceFrame, iconCqw, NORM_W,',
}, {
file: 'src/space-render.ts',
find: ' ${passageGlowTunnels}\n ${glowPools}\n ${wallUnion',
find: ' ${passageGlowTunnels}\n'
+ ' <g class="decorlayer" pointer-events="none">${decorImages}</g>\n'
+ ' ${glowPools}\n ${wallUnion',
replace: ' ${passageGlowTunnels}\n'
+ ' ${!space.bg && !disp.showNames ? svg`<g class="room-svg-labels" pointer-events="none">${space.rooms.map((room) => {\n'
+ ' const center = roomCenter(room);\n'
+ ' return svg`<text class="rlabel" data-hp="room-label" data-id=${room.id || nothing}\n'
+ ' data-area=${room.area || nothing} x=${center[0]} y=${center[1]}>${room.name}</text>`;\n'
+ ' })}</g>` : nothing}\n'
+ ' <g class="decorlayer" pointer-events="none">${decorImages}</g>\n'
+ ' ${glowPools}\n'
+ ' ${wallUnion',
}],