<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>🎨 AI 图片生成器 - 智能图像创作平台</title> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet"> <style> :root { --primary: #6a11cb; --secondary: #2575fc; --accent: #ff6f61; --light: rgba(255, 255, 255, 0.9); --dark-bg: #1a1a2e; --card-bg: rgba(255, 255, 255, 0.12); --shadow: 0 8px 32px rgba(0, 0, 0, 0.15); --transition: all 0.3s ease; --text: white; --border: rgba(255, 255, 255, 0.2); --success: #4caf50; --warning: #ff9800; } .theme-dark { --primary: #1a1a2e; --secondary: #16213e; --card-bg: rgba(30, 30, 40, 0.4); --border: rgba(255, 255, 255, 0.1); --text: #eee; } * { box-sizing: border-box; color-scheme: dark; } body { font-family: 'Noto Sans SC', 'Segoe UI', sans-serif; margin: 0; padding: 0; background: linear-gradient(135deg, var(--primary), var(--secondary)); color: var(--text); min-height: 100vh; position: relative; transition: background 0.5s; } body::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: url('https://particles.js.org/images/background.png'); opacity: 0.05; pointer-events: none; z-index: -1; } header { background: rgba(0, 0, 0, 0.4); padding: 1.2rem; text-align: center; box-shadow: 0 4px 12px rgba(0,0,0,0.2); backdrop-filter: blur(10px); } h1 { margin: 0; font-size: 2.4rem; font-weight: 700; text-shadow: 0 2px 8px rgba(0,0,0,0.3); } .tagline { font-size: 1.1rem; opacity: 0.9; margin: 0.5rem 0 0; } nav { margin-top: 1rem; } nav a { color: white; margin: 0 14px; text-decoration: none; font-weight: 500; font-size: 1rem; transition: var(--transition); } nav a:hover { text-decoration: underline; } button.theme-btn { float: right; background: none; border: 1px solid white; color: white; padding: 6px 12px; border-radius: 8px; cursor: pointer; font-size: 0.9rem; } main { display: grid; grid-template-columns: 1fr 380px; gap: 1.5rem; padding: 1rem; max-width: 1400px; margin: 0 auto; } @media (max-width: 900px) { main { grid-template-columns: 1fr; } } .left-panel { display: flex; flex-direction: column; gap: 1.5rem; } .container { background: var(--card-bg); border-radius: 16px; padding: 2rem; box-shadow: var(--shadow); backdrop-filter: blur(10px); border: 1px solid var(--border); transition: var(--transition); } h2 { font-size: 1.5rem; margin-top: 0; color: var(--text); text-shadow: 0 1px 4px rgba(0,0,0,0.3); } p.example { font-size: 0.95rem; opacity: 0.8; margin-bottom: 1.2rem; } label { display: block; margin-top: 1rem; font-size: 1.1rem; font-weight: 500; } input[type="text"], select, input[type="search"] { width: 100%; padding: 14px; margin: 0.5rem 0; border: none; border-radius: 8px; font-size: 1rem; background: rgba(255, 255, 255, 0.2); color: white; outline: none; transition: var(--transition); } input[type="text"]::placeholder, input[type="search"]::placeholder { color: rgba(255,255,255,0.6); } input[type="text"]:focus, input[type="search"]:focus { background: rgba(255, 255, 255, 0.3); transform: translateY(-2px); } button { margin-top: 1.5rem; padding: 14px 28px; background: var(--accent); color: white; border: none; border-radius: 8px; font-size: 1.1rem; cursor: pointer; transition: var(--transition); font-weight: 600; width: 100%; } button:hover { background: #e05a4f; transform: translateY(-2px); box-shadow: 0 6px 14px rgba(255,111,97,0.4); } button:active { transform: translateY(0); } .btn-small { width: auto !important; padding: 8px 16px; font-size: 0.9rem; margin-left: 8px; } .tag { display: inline-block; background: rgba(255,255,255,0.2); padding: 6px 12px; border-radius: 20px; font-size: 0.9rem; margin: 4px; cursor: pointer; transition: 0.3s; } .tag:hover { background: var(--accent); transform: scale(1.05); } #result { margin-top: 1.5rem; text-align: center; min-height: 200px; } #result.loading { color: rgba(255,255,255,0.8); font-style: italic; } #result img { max-width: 100%; max-height: 400px; border-radius: 12px; box-shadow: 0 8px 20px rgba(0,0,0,0.3); border: 4px solid var(--border); margin: 1rem auto; display: block; cursor: zoom-in; } .img-caption { margin-top: 0.5rem; font-size: 0.9rem; opacity: 0.9; } .action-buttons { margin-top: 1rem; display: flex; justify-content: center; gap: 10px; } .thumbnail-wall { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 10px; margin-top: 1.5rem; } .thumb-item { position: relative; height: 90px; border-radius: 10px; overflow: hidden; box-shadow: 0 4px 10px rgba(0,0,0,0.2); transition: var(--transition); cursor: zoom-in; } .thumb-item:hover::after { content: '❌'; position: absolute; top: 5px; right: 5px; width: 20px; height: 20px; background: rgba(255,0,0,0.7); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; color: white; z-index: 2; } .thumb-item img { width: 100%; height: 100%; object-fit: cover; } .clear-btn { background: #aaa !important; margin-top: 1rem !important; font-size: 0.9rem !important; } .clear-btn:hover { background: #888 !important; } .stat-item { display: flex; justify-content: space-between; margin: 0.6rem 0; font-size: 0.95rem; } .rank-item { padding: 8px 0; border-bottom: 1px dashed rgba(255,255,255,0.2); } .rank-item:last-child { border-bottom: none; } .notification-bar { background: var(--warning); color: #000; text-align: center; padding: 8px; font-weight: 500; border-radius: 8px; margin-bottom: 1rem; animation: pulse 2s infinite; } @keyframes pulse { 0% { opacity: 0.8; } 50% { opacity: 1; } 100% { opacity: 0.8; } } footer { text-align: center; padding: 1.5rem; margin-top: 3rem; color: rgba(255,255,255,0.6); font-size: 0.9rem; } /* === 全屏预览模态框 === */ .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); z-index: 1000; justify-content: center; align-items: center; flex-direction: column; animation: fadeIn 0.3s ease; } .modal.active { display: flex; } .modal-content { max-width: 90vw; max-height: 80vh; border-radius: 10px; box-shadow: 0 0 30px rgba(255, 255, 255, 0.2); overflow: hidden; position: relative; } .modal-content img { max-width: 100%; max-height: 80vh; display: block; } .modal-caption { margin-top: 1rem; font-size: 1rem; color: white; text-align: center; max-width: 90vw; } .close-modal { position: absolute; top: 15px; right: 20px; font-size: 2rem; color: white; background: none; border: none; cursor: pointer; opacity: 0.8; } .close-modal:hover { opacity: 1; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } /* === 加载动画 === */ .loader { border: 5px solid rgba(255,255,255,0.3); border-top: 5px solid #fff; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 20px auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style> </head> <body> <!-- 头部导航 --> <header> <h1>🎨 AI 图片生成器</h1> <p class="tagline">用文字描绘世界 · 让想象瞬间成像</p> <nav> <a href="index.html">首页</a> <a href="guide.html">教程</a> <a href="gallery.html">作品墙</a> <button onclick="toggleTheme()" class="theme-btn">🌙/☀️ 主题</button> </nav> </header> <main> <!-- 左侧主功能区 --> <section class="left-panel"> <!-- 提示输入区 --> <div class="container"> <h2>✨ 描述你的创意</h2> <p class="example">例如:一只穿宇航服的猫在火星上钓鱼,赛博朋克风格</p> <label for="prompt">文字提示 (Prompt)</label> <input type="text" id="prompt" placeholder="输入你想要的画面描述..." oninput="suggestPrompt(this.value)" /> <!-- AI 灵感助手 --> <div id="suggestion" style="font-size:0.9rem; opacity:0.7; margin-top:0.5rem;"></div> <label for="style">艺术风格</label> <select id="style"> <option value="">无特定风格</option> <option value="anime">动漫风格</option> <option value="realistic">写实风格</option> <option value="oil painting">油画风格</option> <option value="cyberpunk">赛博朋克</option> <option value="watercolor">水彩画</option> <option value="surrealism">超现实主义</option> </select> <button onclick="generateImage()">🚀 生成图片</button> <div id="result"> <!-- 生成结果将显示在这里 --> </div> </div> <!-- 使用示例 --> <div class="container"> <h2>💡 灵感示例</h2> <div class="examples"> <span class="tag" onclick="useExample('一只机械熊猫在竹林里打太极')">机械熊猫</span> <span class="tag" onclick="useExample('未来城市悬浮花园,阳光穿透云层')">悬浮花园</span> <span class="tag" onclick="useExample('深海发光水母群环绕沉船')">深海秘境</span> <span class="tag" onclick="useExample('蒸汽朋克火车站,齿轮飞转')">蒸汽车站</span> </div> </div> </section> <!-- 右侧信息面板 --> <section class="right-panel"> <!-- 消息通知 --> <div class="container"> <div class="notification-bar" id="notification"> 🎉 欢迎使用!试试输入“星空下的图书馆” </div> </div> <!-- 统计信息 --> <div class="container"> <h2>📊 使用统计</h2> <div class="stat-item"><strong>总生成数:</strong><span id="total-count">0</span></div> <div class="stat-item"><strong>今日生成:</strong><span id="today-count">0</span></div> <div class="stat-item"><strong>最近生成:</strong><span id="last-time">从未</span></div> </div> <!-- 风格推荐 --> <div class="container"> <h2>🎨 风格推荐</h2> <div> <span class="tag" onclick="setStyle('anime')">动漫</span> <span class="tag" onclick="setStyle('cyberpunk')">赛博朋克</span> <span class="tag" onclick="setStyle('oil painting')">油画风</span> <span class="tag" onclick="setStyle('realistic')">超写实</span> </div> </div> <!-- 排行榜 --> <div class="container"> <h2>🏆 热门创作</h2> <div class="rank-item">1. 宇宙鲸鱼穿越星云 —— 142 次生成</div> <div class="rank-item">2. 唐风赛博都市夜景 —— 98 次生成</div> <div class="rank-item">3. 会飞的鲸鱼书店 —— 87 次生成</div> </div> <!-- 历史记录 --> <div class="container"> <h2>🖼️ 生成历史</h2> <input type="search" id="search" placeholder="搜索历史..." oninput="searchHistory()"> <div class="thumbnail-wall" id="history"></div> <button class="clear-btn" onclick="clearHistory()">🗑️ 清除所有</button> </div> </section> </main> <footer> © 2025 AI Image Generator Tool | 使用 Unsplash 模拟数据 | 学习演示用途 </footer> <!-- === 全屏预览模态框 === --> <div id="imageModal" class="modal"> <button class="close-modal" onclick="closeModal()">×</button> <div class="modal-content"> <img id="modalImage" src="" alt="Preview"> </div> <div class="modal-caption" id="modalCaption"></div> </div> <script> let history = JSON.parse(localStorage.getItem('aiImageHistory')) || []; const modal = document.getElementById("imageModal"); const modalImg = document.getElementById("modalImage"); const modalCaption = document.getElementById("modalCaption"); // ======== 主题切换 ======== function toggleTheme() { document.body.classList.toggle("theme-dark"); localStorage.setItem("theme", document.body.classList.contains("theme-dark") ? "dark" : "light"); } window.onload = function () { const saved = localStorage.getItem("theme"); if (saved === "dark") document.body.classList.add("theme-dark"); updateStats(); updateHistory(); startNotificationCycle(); }; // ======== 模拟通知轮播 ======== const notifications = [ "🎉 新增赛博朋克风格模板!", "💡 小技巧:加入‘电影质感’让画面更高级", "🔥 热门趋势:‘东方幻想’主题正流行", "📌 试试‘发光生物+雨夜’组合" ]; let notifIndex = 0; function startNotificationCycle() { setInterval(() => { const bar = document.getElementById("notification"); bar.style.opacity = 0; setTimeout(() => { bar.textContent = notifications[notifIndex % notifications.length]; bar.style.opacity = 1; notifIndex++; }, 300); }, 4000); } // ======== 图片预览 ======== function viewImage(src, caption) { modalImg.src = src; modalCaption.textContent = caption || ""; modal.classList.add("active"); document.body.style.overflow = "hidden"; } function closeModal() { modal.classList.remove("active"); document.body.style.overflow = ""; } modal.onclick = e => e.target === modal && closeModal(); document.onkeydown = e => e.key === "Escape" && closeModal(); // ======== 下载与分享 ======== async function downloadImage(url) { try { const res = await fetch(url); const blob = await res.blob(); const blobUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = blobUrl; a.download = `AI-${Date.now()}.jpg`; a.click(); URL.revokeObjectURL(blobUrl); } catch (err) { alert("下载失败,请右键图片另存为。"); } } function copyPrompt(prompt) { navigator.clipboard.writeText(prompt).then(() => { alert("✅ 提示词已复制!"); }); } // ======== 删除历史 ======== function deleteHistory(index) { if (confirm("删除这条记录?")) { history.splice(index, 1); localStorage.setItem('aiImageHistory', JSON.stringify(history)); updateHistory(); updateStats(); } } // ======== 搜索历史 ======== function searchHistory() { const q = document.getElementById("search").value.trim().toLowerCase(); const filtered = q ? history.filter(h => h.prompt.toLowerCase().includes(q)) : history; renderHistory(filtered); } function renderHistory(list) { const container = document.getElementById('history'); container.innerHTML = ''; if (list.length === 0) { container.innerHTML = '<p style="opacity:0.6">暂无记录</p>'; return; } [...list].reverse().forEach((item, idx) => { const realIdx = history.indexOf(item); const div = document.createElement('div'); div.className = 'thumb-item'; div.onclick = () => viewImage(item.imageUrl, item.prompt); div.oncontextmenu = e => { e.preventDefault(); deleteHistory(realIdx); }; div.innerHTML = `<img src="${item.imageUrl}" alt="hist">`; container.appendChild(div); }); } function clearHistory() { if (confirm("清空所有历史?")) { history = []; localStorage.removeItem('aiImageHistory'); updateHistory(); updateStats(); alert("已清除"); } } // ======== 统计功能 ======== function updateStats() { const total = history.length; const today = history.filter(h => new Date(h.timestamp).toDateString() === new Date().toDateString()).length; const last = history.length ? history[history.length-1].timestamp : "从未"; document.getElementById("total-count").textContent = total; document.getElementById("today-count").textContent = today; document.getElementById("last-time").textContent = last; } // ======== 示例与推荐 ======== function useExample(text) { document.getElementById("prompt").value = text; } function setStyle(style) { document.getElementById("style").value = style; } function suggestPrompt(input) { const suggestions = { cat: "一只发光的猫在极光下跳舞", robot: "机器人在废弃城市种花", forest: "会说话的古树守护精灵村落", city: "空中漂浮的未来图书馆" }; const key = Object.keys(suggestions).find(k => input.toLowerCase().includes(k)); document.getElementById("suggestion").textContent = key ? "💡 灵感:" + suggestions[key] : ""; } // ======== 图片模拟池 ======== const imagePool = { default: ['abstract', 'art', 'creative'], anime: ['anime', 'manga', 'cartoon'], realistic: ['realistic', 'photo', 'highly detailed'], 'oil painting': ['oil painting', 'brush strokes', 'classic art'], cyberpunk: ['cyberpunk', 'neon', 'futuristic'], watercolor: ['watercolor', 'painting', 'soft colors'], surrealism: ['surreal', 'dreamlike', 'melting'] }; function getRandomImageUrl(prompt, style) { const tags = imagePool[style] || imagePool.default; const tag = tags[Math.floor(Math.random() * tags.length)]; return `https://source.unsplash.com/random/800x600/?${encodeURIComponent(tag)}&t=${Date.now()}`; } // ======== 生成图片 ======== function generateImage() { const promptInput = document.getElementById("prompt").value.trim(); const styleSelect = document.getElementById("style").value; const resultDiv = document.getElementById("result"); if (!promptInput) { alert("请输入描述!"); return; } resultDiv.className = "loading"; resultDiv.innerHTML = `<div class="loader"></div><p>🧠 正在创作...</p>`; setTimeout(() => { const imageUrl = getRandomImageUrl(promptInput, styleSelect); const displayStyle = document.getElementById("style").options[document.getElementById("style").selectedIndex].text; const fullPrompt = `${promptInput}${styleSelect ? `, ${displayStyle}风格` : ''}`; resultDiv.className = ""; resultDiv.innerHTML = ` <h3>✅ 生成成功!</h3> <img src="${imageUrl}" onclick="viewImage('${imageUrl}', '${fullPrompt}')"> <p class="img-caption"><strong>Prompt:</strong> ${promptInput}</p> ${styleSelect ? `<p class="img-caption"><strong>风格:</strong> ${displayStyle}</p>` : ''} <div class="action-buttons"> <button class="btn-small" onclick="downloadImage('${imageUrl}')">📥 下载</button> <button class="btn-small" onclick="copyPrompt('${fullPrompt}')">💬 分享</button> </div> `; const record = { prompt: promptInput, style: displayStyle, imageUrl, timestamp: new Date().toLocaleString() }; history.push(record); localStorage.setItem('aiImageHistory', JSON.stringify(history)); updateHistory(); updateStats(); }, 1800); } </script> </body> </html> 给作品墙制作一个二级网页
最新发布