shrinkgod/index.html
2026-08-30 22:19:14 +10:00

107 lines
4.6 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SHRINKGOD — local GLB optimizer</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🗜️</text></svg>" />
<link rel="stylesheet" href="/src/style.css" />
</head>
<body>
<header>
<div class="brand">🗜️ <b>SHRINKGOD</b><span class="sub">GLB optimizer</span></div>
<div class="local-badge" title="Everything runs in this browser tab. No uploads.">🔒 100% local — files never leave this machine</div>
</header>
<div id="layout">
<aside id="sidebar">
<section id="file-info" class="panel hidden">
<div id="file-name" class="mono"></div>
<div id="file-meta" class="dim"></div>
<div id="rig-badge" class="badge hidden">🦴 rig detected — bones &amp; skin weights protected</div>
</section>
<section class="panel">
<h3>Target</h3>
<div class="preset-row">
<button class="preset" data-preset="light">Light</button>
<button class="preset active" data-preset="balanced">Balanced</button>
<button class="preset" data-preset="crunch">Crunch</button>
</div>
<label class="slider-label">Geometry kept <span id="ratio-val" class="mono accent">25%</span>
<input id="ratio" type="range" min="2" max="100" value="25" />
</label>
<label class="slider-label">Error tolerance <span id="error-val" class="mono accent">1.0%</span>
<input id="error" type="range" min="1" max="100" value="32" />
</label>
</section>
<section class="panel">
<h3>Textures</h3>
<label class="row">Max size
<select id="max-tex">
<option value="99999">Original</option>
<option value="2048">2048</option>
<option value="1024" selected>1024</option>
<option value="512">512</option>
<option value="256">256</option>
</select>
</label>
<label class="row check"><input id="webp" type="checkbox" checked /> Convert color maps to WebP</label>
<label class="slider-label">Quality <span id="quality-val" class="mono accent">85</span>
<input id="quality" type="range" min="40" max="100" value="85" />
</label>
<div class="dim tiny">Normal / roughness maps stay lossless PNG.</div>
</section>
<section class="panel">
<h3>Structure</h3>
<label class="row check"><input id="join" type="checkbox" checked /> Join meshes <span class="dim tiny">(static only)</span></label>
<label class="row check"><input id="quantize" type="checkbox" checked /> Quantize vertex data</label>
<label class="row check"><input id="meshopt" type="checkbox" /> Meshopt compression <span class="dim tiny">(web loaders only — Blender can't read it)</span></label>
</section>
<button id="optimize" class="big-btn" disabled>Optimize</button>
<button id="export" class="big-btn secondary" disabled>Export GLB</button>
<div id="notes" class="panel hidden"></div>
</aside>
<main id="main">
<div id="dropzone">
<div class="dz-inner">
<div class="dz-icon">⬇︎</div>
<div>Drop a <b>.glb</b> here<br /><span class="dim">or</span></div>
<button id="browse">Choose file</button>
<input id="file-input" type="file" accept=".glb,model/gltf-binary" hidden />
</div>
</div>
<div id="viewer-ui" class="hidden">
<div id="toolbar">
<label class="row check"><input id="wireframe" type="checkbox" /> Wireframe</label>
<label class="row" id="anim-row" hidden>Clip
<select id="anim-select"></select>
<label class="row check"><input id="anim-play" type="checkbox" checked /> Play</label>
</label>
<div id="status" class="dim"></div>
</div>
<div id="viewers">
<div class="pane-wrap">
<div class="pane-label">ORIGINAL</div>
<div id="pane-left" class="pane"></div>
<div id="stats-left" class="stats"></div>
</div>
<div class="pane-wrap">
<div class="pane-label">OPTIMIZED</div>
<div id="pane-right" class="pane"><div id="right-empty" class="pane-empty">hit <b>Optimize</b></div></div>
<div id="stats-right" class="stats"></div>
</div>
</div>
</div>
</main>
</div>
<script type="module" src="/src/main.js"></script>
</body>
</html>