Spaces:
Running
Running
| // Model data with descriptions and specs | |
| const modelData = { | |
| 'stable-diffusion-xl': { | |
| name: 'Stable Diffusion XL', | |
| version: 'SDXL 1.0', | |
| description: 'Open-source latent diffusion model capable of generating photo-realistic images given any text input. Features enhanced composition and improved face generation with a native 1024×1024 resolution.', | |
| resolution: '1024×1024', | |
| speed: 'Medium', | |
| style: 'Versatile', | |
| license: 'Open Source', | |
| tags: ['Open Source', 'Customizable', 'Local Run', 'Community'] | |
| }, | |
| 'dall-e-3': { | |
| name: 'DALL-E 3', | |
| version: 'Latest', | |
| description: 'OpenAI\'s most advanced image generation model with exceptional prompt understanding and text rendering capabilities. Produces highly detailed, accurate images that closely follow complex prompts.', | |
| resolution: '1024×1024', | |
| speed: 'Fast', | |
| style: 'Photorealistic', | |
| license: 'Commercial', | |
| tags: ['OpenAI', 'Text Rendering', 'API', 'Enterprise'] | |
| }, | |
| 'midjourney-v6': { | |
| name: 'Midjourney V6', | |
| version: 'Alpha', | |
| description: 'Latest iteration with unprecedented realism, coherent text generation, and improved prompt accuracy. Known for stunning artistic quality and aesthetic appeal in generated imagery.', | |
| resolution: 'Up to 2048×2048', | |
| speed: 'Medium', | |
| style: 'Artistic', | |
| license: 'Commercial', | |
| tags: ['Discord', 'Artistic', 'High Quality', 'Trending'] | |
| }, | |
| 'imagen-3': { | |
| name: 'Imagen 3', | |
| version: 'v3.0', | |
| description: 'Google DeepMind\'s highest quality text-to-image model with exceptional detail, lighting, and fewer distracting artifacts. Excels at rendering text and following complex prompts.', | |
| resolution: '1024×1024', | |
| speed: 'Fast', | |
| style: 'Photorealistic', | |
| license: 'Commercial', | |
| tags: ['Google', 'Safe', 'Reliable', 'Enterprise'] | |
| }, | |
| 'firefly-3': { | |
| name: 'Adobe Firefly 3', | |
| version: 'v3.0', | |
| description: 'Adobe\'s creative generative AI designed for safe commercial use. Integrated with Creative Cloud, featuring structure reference and style reference for precise control.', | |
| resolution: '1024×1024', | |
| speed: 'Fast', | |
| style: 'Commercial', | |
| license: 'Commercial Safe', | |
| tags: ['Adobe', 'Creative Cloud', 'Safe', 'Designers'] | |
| }, | |
| 'leonardo-phoenix': { | |
| name: 'Leonardo Phoenix', | |
| version: 'Phoenix', | |
| description: 'Leonardo.ai\'s flagship model with exceptional coherence, prompt adherence, and native 1536×1536 resolution. Features Alchemy for premium quality enhancement.', | |
| resolution: '1536×1536', | |
| speed: 'Medium', | |
| style: 'Game Assets', | |
| license: 'Commercial', | |
| tags: ['Gaming', 'Assets', 'Fine-tune', 'Community'] | |
| } | |
| }; | |
| // DOM Elements | |
| const dropdownTrigger = document.getElementById('dropdownTrigger'); | |
| const dropdownMenu = document.getElementById('dropdownMenu'); | |
| const dropdownArrow = document.getElementById('dropdownArrow'); | |
| const dropdownSelectedText = document.getElementById('dropdownSelectedText'); | |
| const customDropdown = document.getElementById('customDropdown'); | |
| const modal = document.getElementById('modelModal'); | |
| const modalBackdrop = document.getElementById('modalBackdrop'); | |
| const modalContent = document.getElementById('modalContent'); | |
| const closeModal = document.getElementById('closeModal'); | |
| const floatingLabel = document.getElementById('floatingLabel'); | |
| const selectedDisplay = document.getElementById('selectedDisplay'); | |
| const selectedModelName = document.getElementById('selectedModelName'); | |
| const themeToggle = document.getElementById('themeToggle'); | |
| // Modal content elements | |
| const modalTitle = document.getElementById('modalTitle'); | |
| const modalVersion = document.getElementById('modalVersion'); | |
| const modalDescription = document.getElementById('modalDescription'); | |
| const modalResolution = document.getElementById('modalResolution'); | |
| const modalSpeed = document.getElementById('modalSpeed'); | |
| const modalStyle = document.getElementById('modalStyle'); | |
| const modalLicense = document.getElementById('modalLicense'); | |
| const modalTags = document.getElementById('modalTags'); | |
| // State | |
| let currentModel = null; | |
| let isDropdownOpen = false; | |
| // Initialize | |
| document.addEventListener('DOMContentLoaded', () => { | |
| feather.replace(); | |
| initTheme(); | |
| initDropdown(); | |
| }); | |
| // Theme handling | |
| function initTheme() { | |
| const savedTheme = localStorage.getItem('theme') || 'light'; | |
| if (savedTheme === 'dark') { | |
| document.documentElement.classList.add('dark'); | |
| } | |
| } | |
| themeToggle.addEventListener('click', () => { | |
| document.documentElement.classList.toggle('dark'); | |
| const isDark = document.documentElement.classList.contains('dark'); | |
| localStorage.setItem('theme', isDark ? 'dark' : 'light'); | |
| feather.replace(); | |
| }); | |
| // Dropdown functions | |
| function initDropdown() { | |
| // Toggle dropdown on trigger click | |
| dropdownTrigger.addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| toggleDropdown(); | |
| }); | |
| // Handle dropdown item clicks | |
| document.querySelectorAll('.dropdown-item').forEach(item => { | |
| item.addEventListener('click', (e) => { | |
| // Don't select if info button was clicked | |
| if (e.target.closest('.info-btn')) { | |
| e.stopPropagation(); | |
| return; | |
| } | |
| const value = item.dataset.value; | |
| selectModel(value); | |
| closeDropdown(); | |
| }); | |
| }); | |
| // Handle info button clicks | |
| document.querySelectorAll('.info-btn').forEach(btn => { | |
| btn.addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| const modelKey = btn.dataset.model; | |
| showModelInfo(modelKey); | |
| }); | |
| }); | |
| // Close dropdown when clicking outside | |
| document.addEventListener('click', (e) => { | |
| if (isDropdownOpen && !customDropdown.contains(e.target)) { | |
| closeDropdown(); | |
| } | |
| }); | |
| // Close dropdown on escape key | |
| document.addEventListener('keydown', (e) => { | |
| if (e.key === 'Escape' && isDropdownOpen) { | |
| closeDropdown(); | |
| } | |
| }); | |
| } | |
| function toggleDropdown() { | |
| if (isDropdownOpen) { | |
| closeDropdown(); | |
| } else { | |
| openDropdown(); | |
| } | |
| } | |
| function openDropdown() { | |
| isDropdownOpen = true; | |
| dropdownMenu.classList.remove('opacity-0', 'invisible', 'scale-95'); | |
| dropdownMenu.classList.add('opacity-100', 'visible', 'scale-100'); | |
| dropdownArrow.classList.add('rotate-180'); | |
| dropdownTrigger.classList.add('ring-2', 'ring-primary-500', 'border-transparent'); | |
| } | |
| function closeDropdown() { | |
| isDropdownOpen = false; | |
| dropdownMenu.classList.add('opacity-0', 'invisible', 'scale-95'); | |
| dropdownMenu.classList.remove('opacity-100', 'visible', 'scale-100'); | |
| dropdownArrow.classList.remove('rotate-180'); | |
| dropdownTrigger.classList.remove('ring-2', 'ring-primary-500', 'border-transparent'); | |
| } | |
| function selectModel(value) { | |
| currentModel = value; | |
| if (value) { | |
| // Show floating label | |
| floatingLabel.classList.add('show-label'); | |
| // Update trigger text | |
| const model = modelData[value]; | |
| dropdownSelectedText.textContent = model.name; | |
| dropdownSelectedText.classList.add('text-gray-800', 'dark:text-white'); | |
| // Show selected display | |
| selectedModelName.textContent = model.name; | |
| selectedDisplay.classList.remove('hidden'); | |
| selectedDisplay.classList.add('selected-show'); | |
| // Add focus ring animation | |
| dropdownTrigger.classList.add('focus-ring-animate'); | |
| setTimeout(() => { | |
| dropdownTrigger.classList.remove('focus-ring-animate'); | |
| }, 300); | |
| } | |
| } | |
| function showModelInfo(modelKey) { | |
| const model = modelData[modelKey]; | |
| if (!model) return; | |
| // Populate modal | |
| modalTitle.textContent = model.name; | |
| modalVersion.textContent = model.version; | |
| modalDescription.textContent = model.description; | |
| modalResolution.textContent = model.resolution; | |
| modalSpeed.textContent = model.speed; | |
| modalStyle.textContent = model.style; | |
| modalLicense.textContent = model.license; | |
| // Populate tags | |
| modalTags.innerHTML = model.tags.map((tag, i) => ` | |
| <span class="px-3 py-1 text-xs font-medium rounded-full bg-gradient-to-r from-primary-100 to-secondary-100 dark:from-primary-900/50 dark:to-secondary-900/50 text-primary-700 dark:text-primary-300 border border-primary-200 dark:border-primary-800 tag-pop" style="animation-delay: ${i * 50}ms"> | |
| ${tag} | |
| </span> | |
| `).join(''); | |
| // Show modal | |
| openModal(); | |
| } | |
| // Modal functions | |
| function openModal() { | |
| modal.classList.remove('hidden'); | |
| // Trigger reflow | |
| void modal.offsetWidth; | |
| modalBackdrop.classList.remove('opacity-0'); | |
| modalContent.classList.remove('scale-95', 'opacity-0'); | |
| modalContent.classList.add('scale-100', 'opacity-100'); | |
| } | |
| function closeModalFunc() { | |
| modalBackdrop.classList.add('opacity-0'); | |
| modalContent.classList.remove('scale-100', 'opacity-100'); | |
| modalContent.classList.add('scale-95', 'opacity-0'); | |
| setTimeout(() => { | |
| modal.classList.add('hidden'); | |
| }, 300); | |
| } | |
| // Close modal handlers | |
| closeModal.addEventListener('click', closeModalFunc); | |
| modalBackdrop.addEventListener('click', closeModalFunc); | |
| // Close on escape key | |
| document.addEventListener('keydown', (e) => { | |
| if (e.key === 'Escape' && !modal.classList.contains('hidden')) { | |
| closeModalFunc(); | |
| } | |
| }); | |
| // Use model button | |
| document.getElementById('useModelBtn').addEventListener('click', () => { | |
| closeModalFunc(); | |
| // Add a subtle confirmation animation | |
| modelSelect.parentElement.classList.add('focus-ring-animate'); | |
| setTimeout(() => { | |
| modelSelect.parentElement.classList.remove('focus-ring-animate'); | |
| }, 300); | |
| }); | |
| // Docs button | |
| document.getElementById('docsBtn').addEventListener('click', () => { | |
| const urls = { | |
| 'stable-diffusion-xl': 'https://stability.ai/stable-diffusion', | |
| 'dall-e-3': 'https://openai.com/dall-e-3', | |
| 'midjourney-v6': 'https://www.midjourney.com', | |
| 'imagen-3': 'https://deepmind.google/technologies/imagen-3/', | |
| 'firefly-3': 'https://www.adobe.com/products/firefly.html', | |
| 'leonardo-phoenix': 'https://leonardo.ai' | |
| }; | |
| if (currentModel && urls[currentModel]) { | |
| window.open(urls[currentModel], '_blank'); | |
| } | |
| }); | |