Add FxNode render graph playground

Add persistent render graph loadouts, grouped node authoring, code-appending apply behavior, explicit playground lighting, and resilient worker startup.

Amp-Thread-ID: https://ampcode.com/threads/T-01a033d4-0e44-708e-af0e-6166283416ff
Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
Amp
2026-08-24 17:45:48 +00:00
co-authored by heaust
parent 951449db0b
commit 6153223fd5
27 changed files with 4672 additions and 207 deletions
+96 -11
View File
@@ -16,7 +16,8 @@
{
"imports": {
"@yawn/core": "/pkg/core.js",
"@yawn/handles": "/pkg/handles.js"
"@yawn/handles": "/pkg/handles.js",
"@yawn/fxnode-rg": "/pkg/fxnode-rg.js"
}
}
</script>
@@ -64,19 +65,22 @@
<div class="playground-tools">
<div class="tool-group">
<button id="snippets-button" type="button">
<button id="snippets-button" type="button" data-code-tool>
<span class="braces">{ }</span> Snippets
</button>
<button id="reset-button" type="button">
<button id="reset-button" type="button" data-code-tool>
<span aria-hidden="true">↶</span> Reset
</button>
<button id="format-button" type="button">
<button id="format-button" type="button" data-code-tool>
<span aria-hidden="true">≡</span> Format
</button>
<span class="graph-tool-hint" data-graph-tool hidden
><b>Right click</b> the graph to add a node</span
>
</div>
<div class="tool-context">
<span class="language-dot"></span>
<span>TypeScript</span>
<span id="workspace-language">TypeScript</span>
<span class="context-divider"></span>
<span id="type-status">Starting language service…</span>
</div>
@@ -95,19 +99,100 @@
</div>
<div class="workbench" id="workbench">
<section class="editor-pane" aria-label="TypeScript editor">
<div class="pane-tabs">
<button class="pane-tab active" type="button">
<section class="editor-pane" aria-label="Coding workspace">
<div class="pane-tabs" role="tablist" aria-label="Coding workspace">
<button
class="pane-tab active"
id="scene-tab"
type="button"
role="tab"
aria-selected="true"
aria-controls="editor"
data-editor-tab="scene"
>
<span class="ts-icon">TS</span> scene.ts <i id="tab-dirty"></i>
</button>
<button
class="pane-tab"
id="render-graph-tab"
type="button"
role="tab"
aria-selected="false"
aria-controls="render-graph-editor"
data-editor-tab="render-graph"
>
<span class="rg-tab-icon" aria-hidden="true">◇</span>
render graph
<i id="graph-tab-dirty"></i>
</button>
</div>
<div id="editor" class="editor">
<div
id="editor"
class="editor coding-panel active"
role="tabpanel"
aria-labelledby="scene-tab"
>
<div class="editor-loading">Loading TypeScript editor…</div>
</div>
<section
id="render-graph-editor"
class="render-graph-editor coding-panel"
role="tabpanel"
aria-labelledby="render-graph-tab"
hidden
>
<div class="render-graph-toolbar">
<label>
<span>Loadout</span>
<select
id="loadout-select"
aria-label="Render graph loadout"
></select>
</label>
<label class="loadout-name-field">
<span>Name</span>
<input
id="loadout-name"
maxlength="64"
placeholder="My loadout"
aria-label="Loadout name"
/>
</label>
<button
id="apply-loadout-button"
type="button"
title="Apply in memory; use the playground Save button to keep it"
>
<span aria-hidden="true">◇</span> Apply
</button>
<button
id="copy-loadout-code-button"
class="secondary"
type="button"
title="Copy this loadout's compiled S-expression as Scene code"
>
<span aria-hidden="true">⧉</span> Copy code
</button>
<output id="loadout-status" aria-live="polite"
><i></i> Standard active</output
>
</div>
<div class="render-graph-canvas-wrap">
<canvas
id="render-graph-canvas"
aria-label="Render graph node editor"
></canvas>
<div class="render-graph-empty-hint" id="render-graph-hint">
<span>+</span>
<strong>Add another pass</strong>
<small>Right click anywhere to browse the node catalog</small>
</div>
</div>
</section>
<footer class="editor-status">
<span id="cursor-status">Ln 1, Col 1</span>
<span>Spaces: 2</span>
<span>UTF-8</span>
<span id="editor-mode-status">Spaces: 2</span>
<span id="encoding-status">UTF-8</span>
<span class="status-spacer"></span>
<span id="editor-diagnostics"><i></i> No problems</span>
</footer>