Aplood / img.html
Hosdroid's picture
Create img.html
c25ecda verified
Raw
History Blame Contribute Delete
36.3 kB
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>کوکب تک | تصویرساز هوشمند</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/vazirmatn@5.0.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/vazirmatn@5.0.0/700.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Vazirmatn', sans-serif; }
:root {
--bg-0: #05060f;
--bg-1: #0a0b1e;
--bg-2: #12142d;
--accent-1: #8b5cf6;
--accent-2: #ec4899;
--accent-3: #06b6d4;
--success: #10b981;
--danger: #ef4444;
--text: #e8eaf6;
--text-dim: #9ca3af;
--text-muted: #6b7280;
--glass: rgba(255, 255, 255, 0.03);
--glass-border: rgba(255, 255, 255, 0.08);
--glass-strong: rgba(255, 255, 255, 0.07);
}
html, body { height: 100%; overflow: hidden; }
body {
background: var(--bg-0);
color: var(--text);
background-image:
radial-gradient(circle at 10% 15%, rgba(139, 92, 246, 0.15) 0%, transparent 40%),
radial-gradient(circle at 90% 85%, rgba(236, 72, 153, 0.12) 0%, transparent 40%);
}
.app { display: flex; height: 100vh; }
/* Sidebar */
.sidebar {
width: 360px;
background: rgba(10, 11, 30, 0.7);
backdrop-filter: blur(30px);
border-left: 1px solid var(--glass-border);
display: flex;
flex-direction: column;
overflow: hidden;
}
.sidebar-header {
padding: 18px 20px;
border-bottom: 1px solid var(--glass-border);
display: flex;
align-items: center;
gap: 12px;
background: rgba(5, 6, 15, 0.5);
}
.logo-icon {
width: 44px; height: 44px;
background: linear-gradient(135deg, var(--accent-1), var(--accent-2));
border-radius: 12px;
display: flex; align-items: center; justify-content: center;
font-size: 20px;
box-shadow: 0 6px 20px rgba(139, 92, 246, 0.4);
}
.logo-text h1 { font-size: 16px; font-weight: 700; background: linear-gradient(135deg, #fff, #c4b5fd); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.logo-text p { font-size: 11px; color: var(--text-dim); }
.sidebar-body {
flex: 1;
overflow-y: auto;
padding: 20px;
}
.sidebar-footer {
padding: 14px 20px;
border-top: 1px solid var(--glass-border);
background: rgba(5, 6, 15, 0.5);
font-size: 11px;
color: var(--text-dim);
display: flex;
justify-content: space-between;
align-items: center;
}
.api-status { display: flex; align-items: center; gap: 6px; }
.api-status .dot { width: 8px; height: 8px; background: var(--success); border-radius: 50%; box-shadow: 0 0 10px var(--success); animation: pulse 2s infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
/* Section */
.section { margin-bottom: 20px; }
.section-title {
font-size: 12px;
color: var(--text);
font-weight: 700;
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 8px;
}
.section-title i { color: var(--accent-1); }
/* Prompt Box */
.prompt-box {
position: relative;
background: rgba(0, 0, 0, 0.3);
border: 1px solid var(--glass-border);
border-radius: 14px;
transition: all 0.25s;
}
.prompt-box:focus-within { border-color: var(--accent-1); box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.12); }
.prompt-box textarea {
width: 100%;
background: transparent;
border: none;
padding: 14px;
color: var(--text);
font-size: 14px;
outline: none;
resize: none;
min-height: 120px;
line-height: 1.7;
font-family: inherit;
}
.prompt-box textarea::placeholder { color: var(--text-muted); }
.prompt-actions {
position: absolute;
bottom: 10px;
left: 10px;
display: flex;
gap: 6px;
}
.prompt-btn {
width: 32px; height: 32px;
background: var(--glass-strong);
border: 1px solid var(--glass-border);
border-radius: 8px;
color: var(--text-dim);
cursor: pointer;
font-size: 12px;
transition: all 0.2s;
display: flex; align-items: center; justify-content: center;
}
.prompt-btn:hover { background: var(--accent-1); color: white; border-color: var(--accent-1); }
.prompt-btn.ai { background: linear-gradient(135deg, var(--accent-1), var(--accent-2)); color: white; border: none; padding: 0 12px; width: auto; font-size: 11px; font-weight: 700; gap: 5px; }
/* Chip Grid */
.chip-grid { display: grid; gap: 8px; }
.chip-grid.cols-2 { grid-template-columns: 1fr 1fr; }
.chip-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.chip-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
.chip {
padding: 10px 8px;
background: rgba(0, 0, 0, 0.25);
border: 1px solid var(--glass-border);
border-radius: 10px;
cursor: pointer;
font-size: 12px;
text-align: center;
transition: all 0.2s;
color: var(--text-dim);
}
.chip:hover { border-color: var(--accent-1); color: var(--text); }
.chip.active {
background: linear-gradient(135deg, rgba(139, 92, 246, 0.3), rgba(236, 72, 153, 0.2));
border-color: var(--accent-1);
color: var(--text);
box-shadow: 0 4px 12px rgba(139, 92, 246, 0.25);
}
.chip .chip-name { font-weight: 700; font-size: 12px; display: block; }
.chip .chip-desc { font-size: 10px; opacity: 0.7; margin-top: 2px; }
/* Collapsible */
.collapsible {
background: rgba(0, 0, 0, 0.2);
border: 1px solid var(--glass-border);
border-radius: 12px;
overflow: hidden;
}
.collapsible-header {
padding: 12px 14px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12px;
color: var(--text-dim);
transition: all 0.2s;
}
.collapsible-header:hover { background: rgba(0, 0, 0, 0.1); color: var(--text); }
.collapsible-header i { transition: transform 0.3s; }
.collapsible.open .collapsible-header i { transform: rotate(180deg); }
.collapsible-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.collapsible.open .collapsible-content { max-height: 500px; }
.collapsible-body { padding: 14px; }
/* Checkbox */
.checkbox-row {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
background: rgba(0, 0, 0, 0.2);
border-radius: 8px;
cursor: pointer;
font-size: 12px;
color: var(--text-dim);
transition: all 0.2s;
margin-bottom: 6px;
}
.checkbox-row:hover { background: rgba(0, 0, 0, 0.3); color: var(--text); }
.checkbox-row input { accent-color: var(--accent-1); cursor: pointer; }
/* Form Input */
.form-input {
width: 100%;
background: rgba(0, 0, 0, 0.3);
border: 1px solid var(--glass-border);
border-radius: 9px;
padding: 10px 12px;
color: var(--text);
font-size: 12px;
outline: none;
transition: all 0.2s;
font-family: inherit;
}
.form-input:focus { border-color: var(--accent-1); }
/* Generate Button */
.generate-btn {
width: 100%;
padding: 16px;
background: linear-gradient(135deg, var(--accent-1), var(--accent-2));
border: none;
border-radius: 14px;
color: white;
font-size: 15px;
font-weight: 700;
cursor: pointer;
transition: all 0.25s;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
box-shadow: 0 8px 24px rgba(139, 92, 246, 0.4);
position: relative;
overflow: hidden;
margin-top: 8px;
}
.generate-btn::before {
content: '';
position: absolute;
top: 0; left: -100%;
width: 100%; height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: left 0.6s;
}
.generate-btn:hover::before { left: 100%; }
.generate-btn:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(139, 92, 246, 0.5); }
.generate-btn:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }
.secondary-btn {
width: 100%;
padding: 12px;
background: var(--glass);
border: 1px solid var(--glass-border);
border-radius: 12px;
color: var(--text);
cursor: pointer;
font-size: 13px;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
margin-top: 10px;
}
.secondary-btn:hover { background: var(--glass-strong); border-color: var(--accent-1); }
/* Main */
.main {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
background: rgba(5, 6, 15, 0.3);
}
.main-tabs {
display: flex;
gap: 2px;
padding: 12px 24px 0;
border-bottom: 1px solid var(--glass-border);
background: rgba(10, 11, 30, 0.5);
backdrop-filter: blur(20px);
}
.main-tab {
padding: 12px 18px;
background: transparent;
border: none;
color: var(--text-dim);
cursor: pointer;
font-size: 13px;
border-bottom: 2px solid transparent;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 8px;
font-family: inherit;
}
.main-tab:hover { color: var(--text); }
.main-tab.active { color: var(--text); border-bottom-color: var(--accent-1); }
.main-tab .count { background: var(--glass-strong); padding: 2px 8px; border-radius: 8px; font-size: 11px; }
.main-content { flex: 1; overflow: hidden; position: relative; }
.tab-pane { display: none; height: 100%; }
.tab-pane.active { display: flex; flex-direction: column; animation: fadeIn 0.3s; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
/* Preview */
.preview-stage {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 30px;
overflow: hidden;
position: relative;
background:
linear-gradient(45deg, rgba(255,255,255,0.015) 25%, transparent 25%),
linear-gradient(-45deg, rgba(255,255,255,0.015) 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.015) 75%),
linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.015) 75%);
background-size: 24px 24px;
background-position: 0 0, 0 12px, 12px -12px, -12px 0;
}
.preview-empty {
text-align: center;
color: var(--text-dim);
padding: 40px;
max-width: 500px;
}
.preview-empty .big-icon {
width: 140px; height: 140px;
background: linear-gradient(135deg, rgba(139, 92, 246, 0.15), rgba(236, 72, 153, 0.1));
border: 1px dashed rgba(139, 92, 246, 0.3);
border-radius: 28px;
display: flex;
align-items: center;
justify-content: center;
font-size: 56px;
margin: 0 auto 24px;
color: var(--accent-1);
}
.preview-empty h2 { font-size: 24px; color: var(--text); margin-bottom: 12px; font-weight: 700; }
.preview-empty p { font-size: 14px; line-height: 2; margin-bottom: 20px; }
.quick-prompts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.quick-prompt {
padding: 8px 14px;
background: var(--glass);
border: 1px solid var(--glass-border);
border-radius: 20px;
color: var(--text-dim);
cursor: pointer;
font-size: 12px;
transition: all 0.2s;
}
.quick-prompt:hover { background: var(--glass-strong); color: var(--text); border-color: var(--accent-1); }
.preview-image-wrap {
position: relative;
max-width: 100%;
max-height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.preview-image-wrap img {
max-width: 100%;
max-height: calc(100vh - 220px);
object-fit: contain;
border-radius: 16px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
animation: zoomIn 0.4s ease;
cursor: zoom-in;
}
@keyframes zoomIn { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: scale(1); } }
.preview-image-info {
position: absolute;
bottom: 14px;
right: 14px;
background: rgba(0,0,0,0.7);
backdrop-filter: blur(10px);
padding: 8px 14px;
border-radius: 10px;
font-size: 11px;
color: var(--text-dim);
display: flex;
gap: 12px;
}
.preview-image-info span { display: flex; align-items: center; gap: 5px; }
/* Loading */
.loader {
width: 50px; height: 50px;
border: 3px solid var(--glass-border);
border-top-color: var(--accent-1);
border-right-color: var(--accent-2);
border-radius: 50%;
animation: spin 0.9s linear infinite;
}
.loader.sm { width: 24px; height: 24px; border-width: 2px; }
@keyframes spin { to { transform: rotate(360deg); } }
.loading-wrap { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.loading-wrap p { color: var(--text-dim); font-size: 14px; }
/* Toolbar */
.preview-toolbar {
padding: 14px 24px;
border-top: 1px solid var(--glass-border);
display: flex;
gap: 10px;
background: rgba(10, 11, 30, 0.7);
backdrop-filter: blur(20px);
flex-wrap: wrap;
}
.toolbar-btn {
padding: 10px 16px;
background: var(--glass);
border: 1px solid var(--glass-border);
border-radius: 10px;
color: var(--text);
cursor: pointer;
font-size: 13px;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 8px;
font-family: inherit;
}
.toolbar-btn:hover { background: var(--glass-strong); border-color: var(--accent-1); transform: translateY(-1px); }
.toolbar-btn.primary { background: linear-gradient(135deg, var(--accent-1), var(--accent-2)); border: none; color: white; }
.toolbar-btn.primary:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(139, 92, 246, 0.4); }
.toolbar-spacer { flex: 1; }
/* Gallery */
.gallery-pane { padding: 24px; overflow-y: auto; }
.gallery-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
.gallery-header h3 { font-size: 18px; display: flex; align-items: center; gap: 10px; }
.gallery-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 16px;
}
.gallery-item {
position: relative;
aspect-ratio: 1;
border-radius: 14px;
overflow: hidden;
cursor: pointer;
background: var(--glass);
border: 1px solid var(--glass-border);
transition: all 0.25s;
}
.gallery-item:hover { transform: translateY(-4px); border-color: var(--accent-1); box-shadow: 0 10px 30px rgba(139, 92, 246, 0.25); }
.gallery-item img { width: 100%; height: 100%; object-fit: cover; }
.gallery-item .overlay {
position: absolute;
inset: 0;
background: linear-gradient(to top, rgba(0,0,0,0.9), transparent 60%);
opacity: 0;
transition: opacity 0.25s;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 12px;
}
.gallery-item:hover .overlay { opacity: 1; }
.gallery-item .overlay p { font-size: 12px; color: white; line-height: 1.6; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.gallery-item .overlay-actions { display: flex; gap: 6px; margin-top: 10px; }
.gallery-item .overlay-actions button {
flex: 1;
padding: 6px;
background: rgba(255,255,255,0.15);
border: none;
border-radius: 8px;
color: white;
cursor: pointer;
font-size: 12px;
backdrop-filter: blur(10px);
transition: all 0.2s;
}
.gallery-item .overlay-actions button:hover { background: rgba(255,255,255,0.3); }
.gallery-empty { text-align: center; padding: 80px 20px; color: var(--text-dim); }
.gallery-empty i { font-size: 60px; margin-bottom: 16px; opacity: 0.25; display: block; }
.gallery-empty h3 { font-size: 18px; color: var(--text); margin-bottom: 8px; }
/* Modal */
.modal {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.92);
backdrop-filter: blur(20px);
display: none;
align-items: center;
justify-content: center;
z-index: 2000;
padding: 20px;
}
.modal.show { display: flex; animation: fadeIn 0.2s; }
.modal-content {
max-width: 95vw;
max-height: 95vh;
position: relative;
}
.modal-content img { max-width: 100%; max-height: 90vh; border-radius: 16px; box-shadow: 0 30px 80px rgba(0,0,0,0.8); }
.modal-close {
position: absolute;
top: -16px;
left: -16px;
width: 44px; height: 44px;
background: white;
color: black;
border: none;
border-radius: 50%;
cursor: pointer;
font-size: 16px;
box-shadow: 0 4px 16px rgba(0,0,0,0.4);
z-index: 10;
}
/* Toast */
.toast {
position: fixed;
bottom: 24px;
left: 50%;
transform: translateX(-50%) translateY(100px);
padding: 14px 24px;
border-radius: 12px;
color: white;
font-size: 14px;
box-shadow: 0 10px 30px rgba(0,0,0,0.4);
transition: transform 0.3s;
z-index: 3000;
display: flex;
align-items: center;
gap: 10px;
backdrop-filter: blur(20px);
}
.toast.show { transform: translateX(-50%) translateY(0); }
.toast.info { background: linear-gradient(135deg, var(--accent-1), var(--accent-2)); }
.toast.success { background: linear-gradient(135deg, var(--success), #059669); }
.toast.error { background: linear-gradient(135deg, var(--danger), #b91c1c); }
/* Scrollbar */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.25); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgba(139, 92, 246, 0.45); }
/* Mobile */
@media (max-width: 900px) {
.sidebar { width: 100%; position: fixed; right: -100%; top: 0; bottom: 0; z-index: 50; transition: right 0.3s; }
.sidebar.open { right: 0; }
}
</style>
</head>
<body>
<div class="app">
<aside class="sidebar" id="sidebar">
<div class="sidebar-header">
<div class="logo-icon"><i class="fas fa-star"></i></div>
<div class="logo-text">
<h1>کوکب تک</h1>
<p>تصویرساز هوشمند</p>
</div>
</div>
<div class="sidebar-body">
<!-- Prompt -->
<div class="section">
<div class="section-title"><i class="fas fa-pen-fancy"></i> توضیح تصویر</div>
<div class="prompt-box">
<textarea id="imgPrompt" placeholder="تصویری که می‌خواهید بسازید را توصیف کنید...&#10;&#10;مثال: یک قلعه باستانی روی قله کوه در غروب"></textarea>
<div class="prompt-actions">
<button class="prompt-btn ai" onclick="enhancePrompt()"><i class="fas fa-wand-magic-sparkles"></i> بهبود</button>
<button class="prompt-btn" onclick="randomPrompt()" title="تصادفی"><i class="fas fa-dice"></i></button>
<button class="prompt-btn" onclick="document.getElementById('imgPrompt').value=''" title="پاک کردن"><i class="fas fa-eraser"></i></button>
</div>
</div>
</div>
<!-- Model -->
<div class="section">
<div class="section-title"><i class="fas fa-microchip"></i> مدل</div>
<div class="chip-grid cols-3" id="modelGrid">
<div class="chip active" data-model="flux">
<span class="chip-name">Flux</span>
<span class="chip-desc">عمومی</span>
</div>
<div class="chip" data-model="flux-realism">
<span class="chip-name">Realism</span>
<span class="chip-desc">واقع‌گرا</span>
</div>
<div class="chip" data-model="flux-anime">
<span class="chip-name">Anime</span>
<span class="chip-desc">انیمه</span>
</div>
<div class="chip" data-model="flux-3d">
<span class="chip-name">3D</span>
<span class="chip-desc">سه‌بعدی</span>
</div>
<div class="chip" data-model="flux-pro">
<span class="chip-name">Pro</span>
<span class="chip-desc">حرفه‌ای</span>
</div>
<div class="chip" data-model="turbo">
<span class="chip-name">Turbo</span>
<span class="chip-desc">سریع</span>
</div>
</div>
</div>
<!-- Ratio -->
<div class="section">
<div class="section-title"><i class="fas fa-crop-simple"></i> نسبت تصویر</div>
<div class="chip-grid cols-4" id="ratioGrid">
<div class="chip active" data-w="1024" data-h="1024">1:1</div>
<div class="chip" data-w="1280" data-h="720">16:9</div>
<div class="chip" data-w="720" data-h="1280">9:16</div>
<div class="chip" data-w="1024" data-h="768">4:3</div>
</div>
</div>
<!-- Style -->
<div class="section">
<div class="section-title"><i class="fas fa-palette"></i> سبک</div>
<div class="chip-grid cols-3" id="styleGrid">
<div class="chip active" data-style="">طبیعی</div>
<div class="chip" data-style=", digital art, detailed">دیجیتال</div>
<div class="chip" data-style=", oil painting, classical">نقاشی</div>
<div class="chip" data-style=", anime, manga">انیمه</div>
<div class="chip" data-style=", 3d render, octane">3D</div>
<div class="chip" data-style=", cinematic, dramatic">سینمایی</div>
<div class="chip" data-style=", photorealistic, 8k">واقع‌گرا</div>
<div class="chip" data-style=", cyberpunk, neon">سایبرپانک</div>
<div class="chip" data-style=", fantasy, magical">فانتزی</div>
</div>
</div>
<!-- Advanced (Collapsible) -->
<div class="section">
<div class="collapsible" id="advancedCollapsible">
<div class="collapsible-header" onclick="this.parentElement.classList.toggle('open')">
<span><i class="fas fa-sliders"></i> تنظیمات پیشرفته</span>
<i class="fas fa-chevron-down"></i>
</div>
<div class="collapsible-content">
<div class="collapsible-body">
<div style="margin-bottom: 12px;">
<label style="font-size: 11px; color: var(--text-dim); margin-bottom: 6px; display: block;">Negative Prompt (اختیاری)</label>
<textarea class="form-input" id="imgNegative" rows="2" placeholder="چیزهایی که نمی‌خواهید...">blurry, low quality, distorted</textarea>
</div>
<label class="checkbox-row">
<input type="checkbox" id="imgEnhance" checked>
<span>بهبود خودکار Prompt</span>
</label>
<label class="checkbox-row">
<input type="checkbox" id="imgNoLogo" checked>
<span>حذف واترمارک</span>
</label>
<div style="margin-top: 12px;">
<label style="font-size: 11px; color: var(--text-dim); margin-bottom: 6px; display: block;">Seed (اختیاری)</label>
<input type="number" class="form-input" id="imgSeed" value="-1" min="-1" placeholder="-1 = تصادفی">
</div>
</div>
</div>
</div>
</div>
<!-- Generate -->
<button class="generate-btn" id="generateBtn" onclick="generateImage()">
<i class="fas fa-wand-magic-sparkles"></i>
<span>ساخت تصویر</span>
</button>
<button class="secondary-btn" onclick="surpriseMe()">
<i class="fas fa-surprise"></i>
سورپرایز کن!
</button>
</div>
<div class="sidebar-footer">
<div class="api-status">
<span class="dot"></span>
<span>متصل به API</span>
</div>
<span>Qwen + Pollinations</span>
</div>
</aside>
<main class="main">
<div class="main-tabs">
<button class="main-tab active" data-tab="preview">
<i class="fas fa-eye"></i> پیش‌نمایش
</button>
<button class="main-tab" data-tab="gallery">
<i class="fas fa-images"></i> گالری
<span class="count" id="galleryCount">0</span>
</button>
</div>
<div class="main-content">
<div class="tab-pane active" id="tab-preview">
<div class="preview-stage" id="previewStage">
<div class="preview-empty" id="previewEmpty">
<div class="big-icon"><i class="fas fa-wand-magic-sparkles"></i></div>
<h2>تصویرساز هوشمند کوکب تک</h2>
<p>توضیح تصویر خود را بنویسید و روی «ساخت تصویر» کلیک کنید</p>
<div class="quick-prompts">
<div class="quick-prompt" onclick="setPrompt('A majestic dragon on crystal mountain, epic fantasy')">🐉 اژدها</div>
<div class="quick-prompt" onclick="setPrompt('Cyberpunk city at night, neon lights, rain')">🌃 سایبرپانک</div>
<div class="quick-prompt" onclick="setPrompt('Astronaut in space with Earth background')">👨‍🚀 فضانورد</div>
<div class="quick-prompt" onclick="setPrompt('Japanese temple in cherry blossom season')">🏯 معبد ژاپنی</div>
</div>
</div>
<div class="preview-image-wrap" id="previewWrap" style="display:none"></div>
<div class="loading-wrap" id="previewLoading" style="display:none">
<div class="loader"></div>
<p>در حال ساخت تصویر...</p>
</div>
</div>
<div class="preview-toolbar" id="previewToolbar" style="display:none">
<button class="toolbar-btn primary" onclick="downloadImage()"><i class="fas fa-download"></i> دانلود</button>
<button class="toolbar-btn" onclick="openFullscreen()"><i class="fas fa-expand"></i> تمام‌صفحه</button>
<button class="toolbar-btn" onclick="regenerateImage()"><i class="fas fa-rotate"></i> تولید مجدد</button>
<div class="toolbar-spacer"></div>
<button class="toolbar-btn" onclick="copyImageUrl()"><i class="fas fa-link"></i></button>
<button class="toolbar-btn" onclick="shareImage()"><i class="fas fa-share-nodes"></i></button>
</div>
</div>
<div class="tab-pane" id="tab-gallery">
<div class="gallery-pane">
<div class="gallery-header">
<h3><i class="fas fa-images" style="color:var(--accent-1)"></i> گالری تصاویر</h3>
<button class="toolbar-btn" onclick="clearGallery()"><i class="fas fa-trash"></i> پاک کردن</button>
</div>
<div id="galleryGrid" class="gallery-grid"></div>
<div id="galleryEmpty" class="gallery-empty">
<i class="fas fa-images"></i>
<h3>گالری خالی است</h3>
<p>اولین تصویر خود را بسازید</p>
</div>
</div>
</div>
</div>
</main>
</div>
<div class="modal" id="modal" onclick="closeModal(event)">
<div class="modal-content" onclick="event.stopPropagation()">
<button class="modal-close" onclick="document.getElementById('modal').classList.remove('show')"><i class="fas fa-times"></i></button>
<img id="modalImg" src="">
</div>
</div>
<div class="toast" id="toast"></div>
<script>
let currentModel = 'flux';
let currentWidth = 1024;
let currentHeight = 1024;
let currentStyle = '';
let currentImageUrl = '';
let gallery = JSON.parse(localStorage.getItem('kawkab_gallery_v3') || '[]');
function showToast(msg, type = 'info') {
const t = document.getElementById('toast');
t.className = 'toast ' + type;
const icon = type === 'error' ? 'circle-exclamation' : type === 'success' ? 'circle-check' : 'circle-info';
t.innerHTML = `<i class="fas fa-${icon}"></i> ${msg}`;
t.classList.add('show');
setTimeout(() => t.classList.remove('show'), 2800);
}
function setupChipGrid(gridId, callback) {
document.querySelectorAll(`#${gridId} .chip`).forEach(chip => {
chip.addEventListener('click', () => {
document.querySelectorAll(`#${gridId} .chip`).forEach(c => c.classList.remove('active'));
chip.classList.add('active');
callback(chip);
});
});
}
setupChipGrid('modelGrid', chip => currentModel = chip.dataset.model);
setupChipGrid('ratioGrid', chip => {
currentWidth = parseInt(chip.dataset.w);
currentHeight = parseInt(chip.dataset.h);
});
setupChipGrid('styleGrid', chip => currentStyle = chip.dataset.style);
document.querySelectorAll('.main-tab').forEach(tab => {
tab.addEventListener('click', () => {
document.querySelectorAll('.main-tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.tab-pane').forEach(p => p.classList.remove('active'));
tab.classList.add('active');
document.getElementById('tab-' + tab.dataset.tab).classList.add('active');
});
});
function setPrompt(text) {
document.getElementById('imgPrompt').value = text;
showToast('Prompt تنظیم شد', 'success');
}
async function enhancePrompt() {
const prompt = document.getElementById('imgPrompt').value.trim();
if (!prompt) { showToast('ابتدا توضیح بنویسید', 'error'); return; }
showToast('در حال بهبود...', 'info');
try {
const res = await fetch('https://text.pollinations.ai/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
messages: [
{ role: 'system', content: 'Enhance this image prompt to English with details about lighting, style, quality. Output only the prompt.' },
{ role: 'user', content: prompt }
],
model: 'openai'
})
});
const enhanced = await res.text();
document.getElementById('imgPrompt').value = enhanced.trim().replace(/^["']|["']$/g, '');
showToast('بهبود یافت ✨', 'success');
} catch (err) {
showToast('خطا در بهبود', 'error');
}
}
const randomPrompts = [
'A majestic dragon on crystal mountain at sunset, epic fantasy',
'Cyberpunk city street at night, neon lights, rain',
'Astronaut floating in space with Earth background',
'Japanese temple in cherry blossom season, peaceful',
'Underwater coral reef with tropical fish, vibrant',
'Cozy cabin in snowy forest, northern lights',
'Magical forest with glowing mushrooms, fantasy',
'Futuristic robot in laboratory, detailed'
];
function randomPrompt() {
const p = randomPrompts[Math.floor(Math.random() * randomPrompts.length)];
document.getElementById('imgPrompt').value = p;
showToast('Prompt تصادفی', 'success');
}
async function surpriseMe() {
randomPrompt();
const styles = document.querySelectorAll('#styleGrid .chip');
styles[Math.floor(Math.random() * styles.length)].click();
setTimeout(() => generateImage(), 300);
}
function buildImageUrl(prompt, width, height, seed, model) {
const negative = document.getElementById('imgNegative').value.trim();
const noLogo = document.getElementById('imgNoLogo').checked;
const enhance = document.getElementById('imgEnhance').checked;
const params = new URLSearchParams({ width, height, seed, model, nologo: noLogo });
if (negative) params.append('negative_prompt', negative);
if (enhance) params.append('enhance', 'true');
return `https://image.pollinations.ai/prompt/${encodeURIComponent(prompt)}?${params}`;
}
async function generateImage() {
const prompt = document.getElementById('imgPrompt').value.trim();
if (!prompt) { showToast('توضیح را وارد کنید', 'error'); return; }
const btn = document.getElementById('generateBtn');
const previewWrap = document.getElementById('previewWrap');
const previewEmpty = document.getElementById('previewEmpty');
const previewLoading = document.getElementById('previewLoading');
const toolbar = document.getElementById('previewToolbar');
btn.disabled = true;
btn.innerHTML = '<div class="loader sm"></div> در حال ساخت...';
previewEmpty.style.display = 'none';
previewWrap.style.display = 'none';
previewLoading.style.display = 'flex';
toolbar.style.display = 'none';
let fullPrompt = prompt + currentStyle;
if (document.getElementById('imgEnhance').checked) fullPrompt += ', high quality, detailed';
let seed = parseInt(document.getElementById('imgSeed').value);
if (seed === -1 || isNaN(seed)) seed = Math.floor(Math.random() * 999999);
const url = buildImageUrl(fullPrompt, currentWidth, currentHeight, seed, currentModel);
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
previewLoading.style.display = 'none';
previewWrap.style.display = 'flex';
previewWrap.innerHTML = '';
previewWrap.appendChild(img);
const info = document.createElement('div');
info.className = 'preview-image-info';
info.innerHTML = `<span><i class="fas fa-microchip"></i> ${currentModel}</span><span><i class="fas fa-ruler"></i> ${currentWidth}×${currentHeight}</span>`;
previewWrap.appendChild(info);
currentImageUrl = url;
toolbar.style.display = 'flex';
btn.disabled = false;
btn.innerHTML = '<i class="fas fa-wand-magic-sparkles"></i><span>ساخت تصویر</span>';
showToast('تصویر ساخته شد ✨', 'success');
addToGallery({ url, prompt, fullPrompt, model: currentModel, width: currentWidth, height: currentHeight, seed, timestamp: Date.now() });
};
img.onerror = () => {
previewLoading.style.display = 'none';
previewEmpty.style.display = 'block';
btn.disabled = false;
btn.innerHTML = '<i class="fas fa-wand-magic-sparkles"></i><span>ساخت تصویر</span>';
showToast('خطا در ساخت', 'error');
};
img.src = url;
}
function regenerateImage() {
document.getElementById('imgSeed').value = Math.floor(Math.random() * 999999);
generateImage();
}
function downloadImage() {
if (!currentImageUrl) return;
const a = document.createElement('a');
a.href = currentImageUrl;
a.download = `kawkab-${Date.now()}.jpg`;
a.target = '_blank';
a.click();
showToast('دانلود شروع شد', 'success');
}
function openFullscreen() {
if (!currentImageUrl) return;
document.getElementById('modalImg').src = currentImageUrl;
document.getElementById('modal').classList.add('show');
}
function closeModal(e) {
if (e.target.id === 'modal') document.getElementById('modal').classList.remove('show');
}
function copyImageUrl() {
if (!currentImageUrl) return;
navigator.clipboard.writeText(currentImageUrl);
showToast('لینک کپی شد', 'success');
}
function shareImage() {
if (navigator.share && currentImageUrl) {
navigator.share({ title: 'کوکب تک', url: currentImageUrl }).catch(() => {});
} else {
copyImageUrl();
}
}
function addToGallery(item) {
gallery.unshift(item);
if (gallery.length > 100) gallery = gallery.slice(0, 100);
localStorage.setItem('kawkab_gallery_v3', JSON.stringify(gallery));
renderGallery();
}
function renderGallery() {
const grid = document.getElementById('galleryGrid');
const empty = document.getElementById('galleryEmpty');
const count = document.getElementById('galleryCount');
count.textContent = gallery.length;
if (gallery.length === 0) {
grid.style.display = 'none';
empty.style.display = 'block';
return;
}
grid.style.display = 'grid';
empty.style.display = 'none';
grid.innerHTML = gallery.map((item, idx) => `
<div class="gallery-item" onclick="openGalleryImage(${idx})">
<img src="${item.url}" loading="lazy">
<div class="overlay">
<p>${item.prompt}</p>
<div class="overlay-actions">
<button onclick="event.stopPropagation();downloadGalleryImage(${idx})"><i class="fas fa-download"></i></button>
<button onclick="event.stopPropagation();deleteGalleryImage(${idx})"><i class="fas fa-trash"></i></button>
</div>
</div>
</div>
`).join('');
}
function openGalleryImage(idx) {
currentImageUrl = gallery[idx].url;
document.getElementById('modalImg').src = gallery[idx].url;
document.getElementById('modal').classList.add('show');
}
function downloadGalleryImage(idx) {
const a = document.createElement('a');
a.href = gallery[idx].url;
a.download = `kawkab-${gallery[idx].seed}.jpg`;
a.target = '_blank';
a.click();
}
function deleteGalleryImage(idx) {
if (confirm('حذف این تصویر؟')) {
gallery.splice(idx, 1);
localStorage.setItem('kawkab_gallery_v3', JSON.stringify(gallery));
renderGallery();
showToast('حذف شد', 'success');
}
}
function clearGallery() {
if (confirm('حذف همه تصاویر؟')) {
gallery = [];
localStorage.setItem('kawkab_gallery_v3', JSON.stringify(gallery));
renderGallery();
showToast('گالری پاک شد', 'success');
}
}
document.addEventListener('keydown', e => {
if (e.key === 'Escape') document.getElementById('modal').classList.remove('show');
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { e.preventDefault(); generateImage(); }
});
renderGallery();
</script>
</body>
</html>