- applyU now maps u to a shared global frame index uGlobal in [0, maxT-1]; each panel clamps to its own (T-1), so a shorter timeline pads its last frame while the longer one finishes — both advance at the same wall-clock tempo instead of rescaling their timelines. - tick() keeps u as a float closure variable; reading it back from the integer-step scrubber was quantizing du to 0 at slow tempo + high T (1600ms/frame, T=24: du ≈ 4e-4 → round to 0 on scrub), stalling playback after one frame.
117 lines
4.2 KiB
HTML
117 lines
4.2 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
<title>embedding notebook · compare</title>
|
|
<link rel="stylesheet" href="/static/style.css?v=25" />
|
|
<script type="importmap">
|
|
{
|
|
"imports": {
|
|
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
|
|
"three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/"
|
|
}
|
|
}
|
|
</script>
|
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3' fill='%231f4e5f'/%3E%3C/svg%3E" />
|
|
<script>
|
|
(function(){try{
|
|
var t=localStorage.getItem('theme');
|
|
if(!t)t=matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';
|
|
document.documentElement.setAttribute('data-theme',t);
|
|
}catch(e){}})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
|
|
<header class="masthead">
|
|
<div>
|
|
<h1 class="title">embedding notebook <em>— compare</em></h1>
|
|
</div>
|
|
<div class="meta">
|
|
<a href="/" class="masthead-link">← runs</a>
|
|
<button type="button" class="theme-toggle" id="theme-toggle" aria-label="toggle theme">◐</button>
|
|
</div>
|
|
</header>
|
|
|
|
<section class="compare-layout" id="compare-layout"
|
|
data-stem-a="{{ stem_a }}" data-stem-b="{{ stem_b }}">
|
|
|
|
<div class="compare-controls" id="compare-controls">
|
|
<button type="button" class="cc-play" id="cc-play" aria-label="play / pause">▶</button>
|
|
|
|
<input class="cc-scrub" id="cc-scrub" type="range"
|
|
min="0" max="1000" step="1" value="0" aria-label="time scrubber" />
|
|
|
|
<div class="cc-time" id="cc-time">
|
|
<span class="cc-time-a" data-role="time-a">—</span>
|
|
<span class="cc-time-sep">/</span>
|
|
<span class="cc-time-b" data-role="time-b">—</span>
|
|
</div>
|
|
|
|
<label class="cc-speed-wrap">
|
|
<span class="cc-lbl">speed</span>
|
|
<select class="cc-speed" id="cc-speed">
|
|
<option value="0.5">0.5×</option>
|
|
<option value="1" selected>1×</option>
|
|
<option value="2">2×</option>
|
|
<option value="4">4×</option>
|
|
</select>
|
|
</label>
|
|
|
|
<label class="cc-motion-wrap">
|
|
<span class="cc-lbl">motion</span>
|
|
<select class="cc-motion" id="cc-motion">
|
|
<option value="smooth" selected>smooth</option>
|
|
<option value="step">step</option>
|
|
</select>
|
|
</label>
|
|
|
|
<label class="cc-sync-wrap">
|
|
<span class="cc-lbl">axes</span>
|
|
<select class="cc-sync" id="cc-sync">
|
|
<option value="independent" selected>independent</option>
|
|
<option value="locked">locked</option>
|
|
</select>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="compare-grid">
|
|
<article class="compare-panel" data-slot="a">
|
|
<header class="compare-panel-head">
|
|
<span class="panel-tag" data-role="label">A</span>
|
|
<span class="panel-embedder" data-role="embedder">…</span>
|
|
<span class="panel-sep">·</span>
|
|
<span class="panel-generator" data-role="generator">…</span>
|
|
<a class="panel-stem" data-role="stem-link"
|
|
href="/api/runs/{{ stem_a }}/frames.json" target="_blank">↗</a>
|
|
<span class="panel-params" data-role="params">loading…</span>
|
|
</header>
|
|
<div class="compare-canvas" data-role="canvas">
|
|
<div class="compare-status" data-role="status">loading…</div>
|
|
</div>
|
|
</article>
|
|
|
|
<article class="compare-panel" data-slot="b">
|
|
<header class="compare-panel-head">
|
|
<span class="panel-tag" data-role="label">B</span>
|
|
<span class="panel-embedder" data-role="embedder">…</span>
|
|
<span class="panel-sep">·</span>
|
|
<span class="panel-generator" data-role="generator">…</span>
|
|
<a class="panel-stem" data-role="stem-link"
|
|
href="/api/runs/{{ stem_b }}/frames.json" target="_blank">↗</a>
|
|
<span class="panel-params" data-role="params">loading…</span>
|
|
</header>
|
|
<div class="compare-canvas" data-role="canvas">
|
|
<div class="compare-status" data-role="status">loading…</div>
|
|
</div>
|
|
</article>
|
|
</div>
|
|
|
|
</section>
|
|
|
|
<script src="/static/theme.js?v=11"></script>
|
|
<script type="module" src="/static/compare.js?v=7"></script>
|
|
</body>
|
|
</html>
|