107 lines
4.6 KiB
HTML
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 & 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>
|