Merge Examples/RL tabs into single unified toolbar across all four UIs. Users can now freely mix supervised learning (Add Example + Train) with RL feedback (thumbs up/down) without switching modes. Param bar dragging is always enabled. Add Web MIDI input module (js/synth/midi-input.js) for external MIDI controllers — routes note on/off to C15 synth, CC 1/2 to joystick. Add gamepad module (js/ui/gamepad.js) with auto-detection, deadzone, and axis normalization across all UIs. Fix synth parameter sync: routeOutputs() now called after trainModel() in onThumbsUp and loadState to prevent stale params on first joystick move. Add separate Clear Examples button (dataset only, keeps weights).
191 lines
8.1 KiB
HTML
191 lines
8.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="mobile-web-app-capable" content="yes">
|
|
<title>NISPS Journey</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="css/c-journey.css">
|
|
</head>
|
|
<body>
|
|
<div id="app" class="app phase-explore" data-phase="explore">
|
|
|
|
<!-- Back button -->
|
|
<a href="designs.html" class="back-btn" title="Back">
|
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M10 2L4 8l6 6"/></svg>
|
|
</a>
|
|
|
|
<!-- Flow field canvas — always present -->
|
|
<canvas id="vis-canvas"></canvas>
|
|
<!-- Synth visualizer canvas (shown in synth mode) -->
|
|
<canvas id="synth-vis-canvas" class="synth-vis hidden"></canvas>
|
|
|
|
<!-- Phase indicator (3 dots, top-center) -->
|
|
<div class="phase-dots" id="phase-dots">
|
|
<button class="phase-dot active" data-phase="explore" title="Explore"></button>
|
|
<button class="phase-dot" data-phase="teach" title="Teach"></button>
|
|
<button class="phase-dot" data-phase="perform" title="Perform"></button>
|
|
</div>
|
|
|
|
<!-- Heatmap strip (top) -->
|
|
<div class="heatmap-strip" id="heatmap-strip">
|
|
<div class="heatmap-cells" id="heatmap-cells"></div>
|
|
<span class="heatmap-count" id="heatmap-count">20</span>
|
|
<div class="heatmap-tooltip" id="heatmap-tooltip"></div>
|
|
</div>
|
|
|
|
<!-- Output mode toggle (top-left pill) -->
|
|
<div class="mode-pill" id="mode-pill">
|
|
<button class="mode-opt active" data-mode="visual">Visual</button>
|
|
<button class="mode-opt" data-mode="synth">Synth</button>
|
|
</div>
|
|
|
|
<!-- Explore phase prompts -->
|
|
<div class="explore-prompt" id="explore-prompt">
|
|
<p class="prompt-text" id="prompt-text">Move the joystick to explore</p>
|
|
</div>
|
|
|
|
<div class="explore-ctas hidden" id="explore-ctas">
|
|
<button class="cta-pill" id="cta-preset">Try a preset</button>
|
|
<button class="cta-pill primary" id="cta-teach">Teach it yourself</button>
|
|
</div>
|
|
|
|
<!-- Joystick -->
|
|
<div class="joystick-area" id="joystick-area">
|
|
<canvas class="joystick-canvas" id="joystick-canvas" width="300" height="300"></canvas>
|
|
<!-- Noise ring overlay for RL mode -->
|
|
<div class="noise-ring" id="noise-ring"></div>
|
|
<!-- Follow mode indicator -->
|
|
<div class="follow-indicator hidden" id="follow-indicator">FOLLOW</div>
|
|
<!-- Follow mode toggle pill -->
|
|
<button class="follow-pill" id="follow-pill" title="Toggle follow mode (double-click joystick)">Follow</button>
|
|
<!-- Gamepad status -->
|
|
<div id="gamepad-status" style="color: #ff6a00; font-size: 0.65rem; text-align: center; margin-top: 4px; min-height: 1em;"></div>
|
|
</div>
|
|
|
|
<!-- Teach phase panel -->
|
|
<div class="teach-panel" id="teach-panel">
|
|
|
|
<!-- Unified teaching controls -->
|
|
<div class="teach-content" id="teach-unified">
|
|
<div class="teach-layout">
|
|
<!-- RL feedback buttons -->
|
|
<div class="rl-buttons">
|
|
<button class="rl-btn down" id="btn-thumbs-down" title="Explore more"><span class="rl-icon">👎</span><span class="key-hint">1</span></button>
|
|
<button class="rl-btn up" id="btn-thumbs-up" title="Keep this"><span class="rl-icon">👍</span><span class="key-hint">2</span></button>
|
|
</div>
|
|
|
|
<!-- Preset grid -->
|
|
<div class="preset-grid" id="preset-grid">
|
|
<button class="preset-thumb" data-preset="0">
|
|
<canvas class="preset-canvas" width="60" height="60"></canvas>
|
|
<span>Calm</span>
|
|
</button>
|
|
<button class="preset-thumb" data-preset="1">
|
|
<canvas class="preset-canvas" width="60" height="60"></canvas>
|
|
<span>Storm</span>
|
|
</button>
|
|
<button class="preset-thumb" data-preset="2">
|
|
<canvas class="preset-canvas" width="60" height="60"></canvas>
|
|
<span>Spiral</span>
|
|
</button>
|
|
<button class="preset-thumb" data-preset="3">
|
|
<canvas class="preset-canvas" width="60" height="60"></canvas>
|
|
<span>Pulse</span>
|
|
</button>
|
|
<button class="preset-thumb" data-preset="4">
|
|
<canvas class="preset-canvas" width="60" height="60"></canvas>
|
|
<span>Drift</span>
|
|
</button>
|
|
<button class="preset-thumb" data-preset="5">
|
|
<canvas class="preset-canvas" width="60" height="60"></canvas>
|
|
<span>Swarm</span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="teach-actions">
|
|
<button class="action-btn primary" id="btn-add-example">Add Example</button>
|
|
<button class="action-btn accent" id="btn-train">Train</button>
|
|
</div>
|
|
|
|
<!-- Training minimap -->
|
|
<canvas class="minimap" id="minimap" width="120" height="120"></canvas>
|
|
|
|
<!-- Collapsible fine-tune -->
|
|
<details class="fine-tune" id="fine-tune">
|
|
<summary>Fine-tune parameters</summary>
|
|
<div class="param-sliders" id="param-sliders"></div>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Synth controls section (shown when synth mode active) -->
|
|
<div class="synth-section hidden" id="synth-section">
|
|
<div class="synth-row">
|
|
<button class="action-btn accent" id="synth-start">Start Audio</button>
|
|
<span class="synth-status" id="synth-status">Stopped</span>
|
|
</div>
|
|
<div class="synth-row">
|
|
<label>Volume</label>
|
|
<input type="range" id="synth-volume" min="0" max="1" step="0.01" value="0.5">
|
|
</div>
|
|
<div class="synth-row">
|
|
<label>Arpeggiator</label>
|
|
<button class="action-btn" id="arp-toggle">Play</button>
|
|
</div>
|
|
<div class="synth-row">
|
|
<label>Progression</label>
|
|
<select id="arp-progression">
|
|
<option value="I-vi-IV-V">I-vi-IV-V</option>
|
|
<option value="I-IV-vi-V">I-IV-vi-V</option>
|
|
<option value="i-VI-III-VII">i-VI-III-VII</option>
|
|
<option value="I-V-vi-IV">I-V-vi-IV</option>
|
|
</select>
|
|
</div>
|
|
<div class="synth-row">
|
|
<label>Tempo <span id="tempo-val">120</span></label>
|
|
<input type="range" id="arp-tempo" min="40" max="240" step="1" value="120">
|
|
</div>
|
|
<div class="synth-row" id="midi-row" style="display:none">
|
|
<label>MIDI Input</label>
|
|
<button class="action-btn" id="midi-toggle">Enable</button>
|
|
<select id="midi-select" style="flex:1;min-width:0"></select>
|
|
</div>
|
|
<div class="synth-row" id="midi-status-row" style="display:none">
|
|
<span class="synth-status" id="midi-status"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Status bar -->
|
|
<div class="teach-status" id="teach-status">
|
|
<span id="status-text">0 examples</span>
|
|
<button class="action-btn dim small" id="btn-randomize">Randomize</button>
|
|
<button class="action-btn dim small" id="btn-clear-examples">Clear Examples</button>
|
|
<button class="action-btn dim small" id="btn-clear">Clear All</button>
|
|
</div>
|
|
|
|
<!-- Done button -->
|
|
<button class="done-btn" id="btn-done">Done teaching</button>
|
|
</div>
|
|
|
|
<!-- Perform phase: Edit pill -->
|
|
<div class="edit-pill-wrap" id="edit-pill-wrap">
|
|
<button class="edit-pill" id="btn-edit">Edit</button>
|
|
</div>
|
|
|
|
<!-- Perform phase: floating audio control -->
|
|
<div class="audio-control hidden" id="audio-control">
|
|
<button class="audio-btn" id="audio-toggle">▶</button>
|
|
<input type="range" class="audio-vol" id="audio-vol" min="0" max="1" step="0.01" value="0.5">
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script type="module" src="js/c-app.js"></script>
|
|
</body>
|
|
</html>
|