Spaces:
Running
Running
| <html> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>Stable Diffusion - Demo UI</title> | |
| <link rel="stylesheet" href="style.css" /> | |
| </head> | |
| <body> | |
| <div class="hf-app"> | |
| <header class="hf-header"> | |
| <div class="logo" aria-hidden="true"> | |
| <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |
| <defs> | |
| <linearGradient id="g" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse"> | |
| <stop stop-color="#ff8a00" /> | |
| <stop offset="1" stop-color="#ff4d4d" /> | |
| </linearGradient> | |
| </defs> | |
| <rect x="2" y="2" width="20" height="20" rx="5" fill="url(#g)" /> | |
| <path d="M8 8.5h8M8 12h6M8 15.5h8" stroke="white" stroke-width="1.8" stroke-linecap="round"/> | |
| </svg> | |
| </div> | |
| <div class="titles"> | |
| <h1>Stable Diffusion 图片生成器</h1> | |
| <p class="subtitle">Hugging Face 风格的纯前端演示界面(仅 UI,无后端)。</p> | |
| </div> | |
| </header> | |
| <main class="hf-main"> | |
| <section class="panel controls"> | |
| <div class="group"> | |
| <label for="prompt">Prompt</label> | |
| <textarea id="prompt" rows="4" placeholder="例如:a cozy room with a sleeping orange cat, soft light, ultra-detailed, 8k"></textarea> | |
| </div> | |
| <div class="group"> | |
| <label for="neg">Negative Prompt</label> | |
| <textarea id="neg" rows="3" placeholder="例如:lowres, blurry, artifacts, extra fingers"></textarea> | |
| </div> | |
| <div class="row"> | |
| <div class="field"> | |
| <label for="width">宽度</label> | |
| <select id="width"> | |
| <option>512</option> | |
| <option selected>768</option> | |
| <option>896</option> | |
| <option>1024</option> | |
| </select> | |
| </div> | |
| <div class="field"> | |
| <label for="height">高度</label> | |
| <select id="height"> | |
| <option>512</option> | |
| <option selected>768</option> | |
| <option>896</option> | |
| <option>1024</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div class="field"> | |
| <label for="steps">Steps <span class="value" id="stepsVal">30</span></label> | |
| <input id="steps" type="range" min="1" max="100" value="30" /> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div class="field"> | |
| <label for="cfg">Guidance Scale <span class="value" id="cfgVal">7.0</span></label> | |
| <input id="cfg" type="range" min="1" max="20" step="0.5" value="7" /> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div class="field"> | |
| <label for="sampler">采样器</label> | |
| <select id="sampler"> | |
| <option>Euler</option> | |
| <option>DPM++ 2M</option> | |
| <option>Heun</option> | |
| <option>Euler a</option> | |
| </select> | |
| </div> | |
| <div class="field"> | |
| <label for="seed">Seed</label> | |
| <input id="seed" type="text" placeholder="随机" /> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div class="field"> | |
| <label for="batch">每批数量</label> | |
| <select id="batch"> | |
| <option selected>1</option> | |
| <option>2</option> | |
| <option>4</option> | |
| <option>8</option> | |
| </select> | |
| </div> | |
| <div class="field"> | |
| <label> </label> | |
| <button id="generateBtn" class="primary">生成</button> | |
| </div> | |
| </div> | |
| <p class="disclaimer">此页面仅为演示 UI,不会调用任何模型或上传图像。</p> | |
| </section> | |
| <section class="panel output"> | |
| <div class="toolbar"> | |
| <div class="tag">SD 1.5</div> | |
| <div class="tag secondary">无 API(演示)</div> | |
| </div> | |
| <div id="gallery" class="gallery"> | |
| <div class="tile skeleton"></div> | |
| <div class="tile skeleton"></div> | |
| <div class="tile skeleton"></div> | |
| <div class="tile skeleton"></div> | |
| </div> | |
| </section> | |
| </main> | |
| <footer class="hf-footer"> | |
| <p>Made with ❤️ — 静态页面示例</p> | |
| </footer> | |
| </div> | |
| <script> | |
| const steps = document.getElementById('steps'); | |
| const stepsVal = document.getElementById('stepsVal'); | |
| const cfg = document.getElementById('cfg'); | |
| const cfgVal = document.getElementById('cfgVal'); | |
| const generateBtn = document.getElementById('generateBtn'); | |
| const gallery = document.getElementById('gallery'); | |
| const batch = document.getElementById('batch'); | |
| function updateOutput(el, outEl, factor = 1) { | |
| outEl.textContent = (el.value * factor).toFixed(factor === 1 ? 0 : 1); | |
| } | |
| steps.addEventListener('input', () => updateOutput(steps, stepsVal)); | |
| cfg.addEventListener('input', () => updateOutput(cfg, cfgVal, 1)); | |
| function skeleton(n) { | |
| gallery.innerHTML = ''; | |
| for (let i = 0; i < n; i++) { | |
| const d = document.createElement('div'); | |
| d.className = 'tile skeleton'; | |
| gallery.appendChild(d); | |
| } | |
| } | |
| function fakeGenerate() { | |
| const n = parseInt(batch.value || '1', 10); | |
| skeleton(Math.min(Math.max(n, 1), 8)); | |
| generateBtn.disabled = true; | |
| generateBtn.textContent = '生成中...'; | |
| const seeds = Array.from({ length: n }, (_, i) => `${Date.now()}-${i}`); | |
| setTimeout(() => { | |
| gallery.innerHTML = ''; | |
| seeds.forEach((s) => { | |
| const tile = document.createElement('div'); | |
| tile.className = 'tile'; | |
| const img = document.createElement('img'); | |
| img.alt = 'sample'; | |
| img.loading = 'lazy'; | |
| img.src = `https://picsum.photos/seed/${encodeURIComponent(s)}/768/768`; | |
| tile.appendChild(img); | |
| gallery.appendChild(tile); | |
| }); | |
| generateBtn.disabled = false; | |
| generateBtn.textContent = '生成'; | |
| }, 900 + n * 150); | |
| } | |
| generateBtn.addEventListener('click', () => { | |
| window.open('https://seedance10.com', '_blank', 'noopener,noreferrer'); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |