Skip to content

Commit 5086a7f

Browse files
author
DavidQ
committed
feat(samples2tools): apply sample 1208 palette + paint/stroke in Vector Asset Studio
- read `vectorAssetEditorOptions` from sample preset payload - register preset-provided palette entries at load time - apply preset palette selection and default paint/stroke after SVG load - add `sample1208-parallax` palette (SVG-derived colors) to `vector-asset-studio-sample-1208.json
1 parent 95892c5 commit 5086a7f

35 files changed

Lines changed: 1376 additions & 74 deletions
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Samples2Tools Batch 1 Summary
2+
Generated: 2026-04-23T17:05:53.817Z
3+
Scope: non-Phase-20 sample->tool mappings via metadata toolHints
4+
5+
Mapped tools: 1
6+
Mapped sample links: 4
7+
8+
parallax-editor: 4 sample(s)
9+
10+
Mapped links:
11+
- parallax-editor <= Phase 03 Sample 0306 | Nes Style Zones Parallax | ./phase-03/0306/index.html
12+
- parallax-editor <= Phase 12 Sample 1204 | Tilemap Parallax Hero | ./phase-12/1204/index.html
13+
- parallax-editor <= Phase 12 Sample 1205 | Multi-System Demo | ./phase-12/1205/index.html
14+
- parallax-editor <= Phase 12 Sample 1208 | Tool Formatted Tiles Parallax | ./phase-12/1208/index.html
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Samples2Tools Batch 1 Validation
2+
Generated: 2026-04-23T17:05:53.818Z
3+
4+
[x] samples/index.render.js syntax check
5+
[x] tools/renderToolsIndex.js syntax check
6+
[x] samples index has Tool filter control
7+
[x] samples index supports ?tool=<toolId> preselect
8+
[x] tools cards can render Samples (x) links from metadata toolHints
9+
[x] workspace-manager excluded from tool return-path filter
10+
11+
Execution evidence:
12+
- mapped tools: 1
13+
- mapped sample links: 4
14+
- tool ids: parallax-editor
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"generatedAt": "2026-04-23T17:05:53.819Z",
3+
"scope": "non-phase-20",
4+
"links": [
5+
{
6+
"toolId": "parallax-editor",
7+
"sampleId": "0306",
8+
"phase": "03",
9+
"title": "Nes Style Zones Parallax",
10+
"href": "./phase-03/0306/index.html"
11+
},
12+
{
13+
"toolId": "parallax-editor",
14+
"sampleId": "1204",
15+
"phase": "12",
16+
"title": "Tilemap Parallax Hero",
17+
"href": "./phase-12/1204/index.html"
18+
},
19+
{
20+
"toolId": "parallax-editor",
21+
"sampleId": "1205",
22+
"phase": "12",
23+
"title": "Multi-System Demo",
24+
"href": "./phase-12/1205/index.html"
25+
},
26+
{
27+
"toolId": "parallax-editor",
28+
"sampleId": "1208",
29+
"phase": "12",
30+
"title": "Tool Formatted Tiles Parallax",
31+
"href": "./phase-12/1208/index.html"
32+
}
33+
]
34+
}

docs/dev/roadmaps/MASTER_ROADMAP_SAMPLES2TOOLS.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@
134134
- [ ] No regressions to direct tool launch without sample params.
135135

136136
## Reporting Outputs (per execution batch)
137-
- [ ] `docs/dev/reports/samples2tools_batch_<n>_summary.txt`
138-
- [ ] `docs/dev/reports/samples2tools_batch_<n>_validation.txt`
139-
- [ ] `docs/dev/reports/samples2tools_link_map_<n>.json`
137+
- [x] `docs/dev/reports/samples2tools_batch_<n>_summary.txt`
138+
- [x] `docs/dev/reports/samples2tools_batch_<n>_validation.txt`
139+
- [x] `docs/dev/reports/samples2tools_link_map_<n>.json`
140140

141141
## Current Snapshot (from tools_used.txt)
142-
- [x] Current tagged samples across active tools: `1` (excluding Phase 20)
142+
- [x] Current tagged samples across active tools: `4` (excluding Phase 20)
143143
- [x] Candidate coverage inventory exists for all active tools
144144
- [.] Convert candidates into curated, validated sample-to-tool links

samples/index.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,30 @@
6363
gap: 4px;
6464
}
6565

66+
.sample-tool-roundtrip {
67+
margin-top: 10px;
68+
}
69+
70+
.sample-tool-roundtrip h4,
71+
.sample-tool-roundtrip p,
72+
.sample-tool-roundtrip li,
73+
.sample-tool-roundtrip a {
74+
color: #ffffff;
75+
}
76+
77+
.sample-tool-roundtrip h4 {
78+
margin: 0 0 6px;
79+
}
80+
81+
.sample-tool-roundtrip p {
82+
margin: 0 0 6px;
83+
}
84+
85+
.sample-tool-roundtrip ul {
86+
margin: 0;
87+
padding-left: 18px;
88+
}
89+
6690
body.hub-page-samples .samples-phase-accordion {
6791
margin: 0 0 12px;
6892
border: 1px solid var(--line, rgba(221, 214, 254, 0.26));

samples/index.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,18 @@ <h2>Filter Samples</h2>
4747
<option value="">All classes</option>
4848
</select>
4949
</div>
50-
<div class="samples-filter-field">
51-
<label for="samples-filter-tool">Tool</label>
52-
<select id="samples-filter-tool">
53-
<option value="">All tools</option>
54-
</select>
55-
</div>
5650
<div class="samples-filter-field">
5751
<label for="samples-filter-tag">Tag</label>
5852
<select id="samples-filter-tag">
5953
<option value="">All tags</option>
6054
</select>
6155
</div>
56+
<div class="samples-filter-field">
57+
<label for="samples-filter-tool">Tool</label>
58+
<select id="samples-filter-tool">
59+
<option value="">All tools</option>
60+
</select>
61+
</div>
6262
<div class="samples-filter-field">
6363
<label for="samples-phase-filter-input">Search</label>
6464
<input id="samples-phase-filter-input" type="text" placeholder="Phase 17, rendering, runtime..." autocomplete="off" />

samples/index.render.js

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,61 @@ function escapeHtml(value) {
3232
.replaceAll("'", "&#39;");
3333
}
3434

35+
function toStandaloneToolHref(entryPoint) {
36+
const normalized = String(entryPoint || "").replace(/^\.?\/*/, "");
37+
return normalized ? `/tools/${encodeURI(normalized)}` : "";
38+
}
39+
40+
function shouldUsePresetRoundtrip(sample, toolId) {
41+
const sampleId = normalize(sample?.id);
42+
const samplePhase = normalize(sample?.phase);
43+
if (!sampleId || !samplePhase) {
44+
return false;
45+
}
46+
if (sampleId === "1208" && samplePhase === "12") {
47+
return toolId === "tile-map-editor"
48+
|| toolId === "parallax-editor"
49+
|| toolId === "vector-asset-studio";
50+
}
51+
if (toolId !== "parallax-editor") {
52+
return false;
53+
}
54+
return (sampleId === "0306" && samplePhase === "03")
55+
|| (sampleId === "1204" && samplePhase === "12")
56+
|| (sampleId === "1205" && samplePhase === "12");
57+
}
58+
59+
function buildRoundtripLinks(sample, toolRegistryMap) {
60+
const orderedToolHints = asArray(sample?.toolHints)
61+
.map((entry) => normalizeToken(entry))
62+
.filter(Boolean)
63+
.filter((toolId) => toolId !== "workspace-manager");
64+
const dedupedToolHints = [...new Set(orderedToolHints)];
65+
const links = [];
66+
67+
dedupedToolHints.forEach((toolId) => {
68+
const tool = toolRegistryMap.get(toolId);
69+
if (!tool) {
70+
return;
71+
}
72+
const baseHref = toStandaloneToolHref(tool.entryPoint);
73+
if (!baseHref) {
74+
return;
75+
}
76+
77+
let href = baseHref;
78+
let label = `Open ${normalize(tool.displayName) || normalize(tool.name) || toolId}`;
79+
if (shouldUsePresetRoundtrip(sample, toolId)) {
80+
const presetPath = `/samples/phase-${sample.phase}/${sample.id}/${toolId}-sample-${sample.id}.json`;
81+
href = `${baseHref}?sampleId=${encodeURIComponent(sample.id)}&samplePresetPath=${encodeURIComponent(presetPath)}`;
82+
}
83+
84+
links.push({ toolId, href, label });
85+
});
86+
87+
return links;
88+
}
89+
3590
function readPinnedSet() {
3691
try {
3792
const raw = window.localStorage.getItem(PINNED_KEY);
@@ -82,7 +137,7 @@ function buildToolTokens(toolHints, toolLabelMap) {
82137
.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
83138
}
84139

85-
function buildSampleRows(metadata, pinnedSet, toolLabelMap) {
140+
function buildSampleRows(metadata, pinnedSet, toolLabelMap, toolRegistryMap) {
86141
const phaseInfoMap = new Map(
87142
asArray(metadata?.phases)
88143
.map((phase) => {
@@ -116,6 +171,7 @@ function buildSampleRows(metadata, pinnedSet, toolLabelMap) {
116171
const tags = asArray(sample?.tags).map((tag) => normalizeTag(tag)).filter(Boolean);
117172
const classTokens = buildClassTokens(sample?.classValues, sample?.engineClassesUsed);
118173
const toolTokens = buildToolTokens(sample?.toolHints, toolLabelMap);
174+
const roundtripLinks = buildRoundtripLinks({ id, phase, toolHints: sample?.toolHints }, toolRegistryMap);
119175
const previewSrc = normalize(sample?.thumbnail) || normalize(sample?.preview) || "";
120176
return {
121177
id,
@@ -128,6 +184,7 @@ function buildSampleRows(metadata, pinnedSet, toolLabelMap) {
128184
tags,
129185
classTokens,
130186
toolTokens,
187+
roundtripLinks,
131188
previewSrc,
132189
pinned: pinnedSet.has(id)
133190
};
@@ -253,6 +310,18 @@ function buildSampleCard(sample) {
253310
card.appendChild(title);
254311
card.appendChild(previewWrap);
255312
card.appendChild(description);
313+
if (Array.isArray(sample.roundtripLinks) && sample.roundtripLinks.length > 0) {
314+
const roundtripSection = document.createElement("section");
315+
roundtripSection.className = "sample-tool-roundtrip";
316+
roundtripSection.innerHTML = `
317+
<h4>Tool Roundtrip Links</h4>
318+
<p>Use these to validate tool to sample and sample back to tool workflows.</p>
319+
<ul>
320+
${sample.roundtripLinks.map((entry) => `<li><a href="${escapeHtml(entry.href)}">${escapeHtml(entry.label)}</a></li>`).join("")}
321+
</ul>
322+
`;
323+
card.appendChild(roundtripSection);
324+
}
256325
return card;
257326
}
258327

@@ -339,14 +408,21 @@ export async function initSamplesIndex() {
339408
}
340409
const metadata = await response.json();
341410
let pinnedSet = readPinnedSet();
411+
const toolRegistry = getToolRegistry();
342412
const toolLabelMap = new Map(
343-
getToolRegistry()
413+
toolRegistry
344414
.filter((tool) => tool.id !== "workspace-manager")
345415
.map((tool) => [normalizeToken(tool.id), normalize(tool.displayName) || normalize(tool.name) || normalize(tool.id)])
346416
.filter((entry) => entry[0] && entry[1])
347417
);
418+
const toolRegistryMap = new Map(
419+
toolRegistry
420+
.filter((tool) => tool.id !== "workspace-manager")
421+
.map((tool) => [normalizeToken(tool.id), tool])
422+
.filter((entry) => entry[0] && entry[1])
423+
);
348424

349-
const model = buildSampleRows(metadata, pinnedSet, toolLabelMap);
425+
const model = buildSampleRows(metadata, pinnedSet, toolLabelMap, toolRegistryMap);
350426
setSelectOptions(phaseSelect, model.phaseOptions.map((entry) => entry.value), (value) => {
351427
const found = model.phaseOptions.find((entry) => entry.value === value);
352428
return found?.label || `Phase ${value}`;
@@ -366,7 +442,7 @@ export async function initSamplesIndex() {
366442
}
367443

368444
const render = () => {
369-
const nextModel = buildSampleRows(metadata, pinnedSet, toolLabelMap);
445+
const nextModel = buildSampleRows(metadata, pinnedSet, toolLabelMap, toolRegistryMap);
370446
const filterState = {
371447
phase: normalize(phaseSelect.value),
372448
className: normalize(classSelect.value),

samples/metadata/samples.index.metadata.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2358,6 +2358,9 @@
23582358
"engine/theme/index/ThemeTokens",
23592359
"engine/tilemap/index/renderTilemap",
23602360
"engine/tilemap/index/Tilemap"
2361+
],
2362+
"toolHints": [
2363+
"parallax-editor"
23612364
]
23622365
},
23632366
{
@@ -6200,6 +6203,9 @@
62006203
"engine/tilemap/index/resolveRectVsTilemap",
62016204
"engine/tilemap/index/Tilemap",
62026205
"engine/utils/index/clamp"
6206+
],
6207+
"toolHints": [
6208+
"parallax-editor"
62036209
]
62046210
},
62056211
{
@@ -6247,6 +6253,9 @@
62476253
"engine/tilemap/index/resolveRectVsTilemap",
62486254
"engine/tilemap/index/Tilemap",
62496255
"engine/utils/index/clamp"
6256+
],
6257+
"toolHints": [
6258+
"parallax-editor"
62506259
]
62516260
},
62526261
{
@@ -6384,7 +6393,9 @@
63846393
"engine/utils/index/clamp"
63856394
],
63866395
"toolHints": [
6387-
"parallax-editor"
6396+
"tile-map-editor",
6397+
"parallax-editor",
6398+
"vector-asset-studio"
63886399
]
63896400
},
63906401
{
Lines changed: 5 additions & 0 deletions
Loading
Lines changed: 5 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)