Engine core: Timeline (fixed dt, audio-mastered in realtime), seeded Rng, Renderer, Layer/ShaderLayer/SceneLayer, Compositor with blend modes, feedback and post chain. Shader scenes are compiled against a fixed uniform contract and define only `vec4 scene(vec2 uv, vec2 p)`, so adding a scene costs a shader plus a params block. Deep Nebula ported from party-stage as the first one. Gate passes, 7/7 in checks.html: - 300 frames rendered twice are bit-identical - a fresh Engine reproduces the same frames - simulated dropped frames change nothing (proves dt is fixed) - seek matches sequential playback - 320x180 vs 1280x720 agree within 0.010 (limit 0.06) - seeded rng reproducible, forked streams independent - compositor reset clears feedback history Static gates: no wall-clock or unseeded randomness in deterministic directories; scene schemas and shader sources agree in both directions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
74 lines
3.1 KiB
HTML
74 lines
3.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>flow-state</title>
|
|
<link rel="stylesheet" href="/src/ui/style.css">
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<div id="stage">
|
|
<canvas id="canvas"></canvas>
|
|
<div id="overlay">
|
|
<div id="dropzone">
|
|
<div class="dz-inner">
|
|
<div class="dz-title">flow-state</div>
|
|
<div class="dz-sub">drop an audio file, or click to choose</div>
|
|
<div class="dz-hint">mp3 · flac · wav · ogg</div>
|
|
</div>
|
|
</div>
|
|
<div id="analysing" hidden>
|
|
<div class="an-title">analysing</div>
|
|
<div class="an-step">—</div>
|
|
<div class="an-bar"><div class="an-fill"></div></div>
|
|
</div>
|
|
</div>
|
|
<div id="hud" hidden></div>
|
|
</div>
|
|
|
|
<div id="transport">
|
|
<div id="timeline">
|
|
<canvas id="timeline-canvas"></canvas>
|
|
</div>
|
|
<div id="controls">
|
|
<button id="btn-play" title="Play / pause (space)">▶</button>
|
|
<button id="btn-prev-section" title="Previous section (←)">⇤</button>
|
|
<button id="btn-next-section" title="Next section (→)">⇥</button>
|
|
<button id="btn-loop" title="Loop current section (L)">↻</button>
|
|
<span id="time-display">0:00 / 0:00</span>
|
|
<span class="spacer"></span>
|
|
<span id="section-display"></span>
|
|
<span class="spacer"></span>
|
|
<label class="ctl">quality
|
|
<select id="sel-quality">
|
|
<option value="draft">draft</option>
|
|
<option value="full" selected>full</option>
|
|
</select>
|
|
</label>
|
|
<button id="btn-reroll" title="New seed for the whole track">reroll</button>
|
|
<button id="btn-reroll-section" title="New scene for this section only">reroll section</button>
|
|
<button id="btn-lock" title="Lock this section against rerolls">lock</button>
|
|
<button id="btn-hud" title="Toggle debug HUD (D)">hud</button>
|
|
<button id="btn-segment" title="Render 20s around the playhead at export quality">test render</button>
|
|
<button id="btn-export" class="primary" title="Export the full video">export</button>
|
|
</div>
|
|
</div>
|
|
|
|
<aside id="panel">
|
|
<div id="panel-tabs">
|
|
<button data-tab="look" class="active">look</button>
|
|
<button data-tab="scene">scene</button>
|
|
<button data-tab="post">post</button>
|
|
<button data-tab="export">export</button>
|
|
</div>
|
|
<div id="panel-body"></div>
|
|
</aside>
|
|
</div>
|
|
|
|
<input type="file" id="file-input" accept="audio/*" hidden>
|
|
<audio id="audio" hidden></audio>
|
|
<script type="module" src="/src/main.js"></script>
|
|
</body>
|
|
</html>
|