Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>ArtFlow - Creative Image & Video Generator</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
.gradient-bg { | |
background: linear-gradient(135deg, #6e8efb, #a777e3); | |
} | |
.generation-card { | |
transition: all 0.3s ease; | |
box-shadow: 0 10px 20px rgba(0,0,0,0.1); | |
} | |
.generation-card:hover { | |
transform: translateY(-5px); | |
box-shadow: 0 15px 30px rgba(0,0,0,0.2); | |
} | |
.progress-bar { | |
height: 6px; | |
transition: width 0.3s ease; | |
} | |
.video-preview { | |
aspect-ratio: 16/9; | |
} | |
.drawer { | |
transition: transform 0.3s ease; | |
} | |
.drawer.closed { | |
transform: translateX(100%); | |
} | |
#imageGrid { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); | |
gap: 1rem; | |
} | |
@media (max-width: 768px) { | |
#imageGrid { | |
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); | |
} | |
} | |
/* Custom animation for generated images */ | |
@keyframes fadeIn { | |
from { opacity: 0; transform: scale(0.95); } | |
to { opacity: 1; transform: scale(1); } | |
} | |
.generated-image { | |
animation: fadeIn 0.5s ease-out forwards; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-50 min-h-screen"> | |
<!-- Navigation --> | |
<nav class="bg-white shadow-sm"> | |
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | |
<div class="flex justify-between h-16"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 flex items-center"> | |
<i class="fas fa-magic text-purple-600 text-2xl mr-2"></i> | |
<span class="text-xl font-bold text-gray-900">ArtFlow</span> | |
</div> | |
</div> | |
<div class="hidden md:ml-6 md:flex md:items-center md:space-x-8"> | |
<a href="#" class="text-purple-600 border-b-2 border-purple-600 px-3 py-2 text-sm font-medium">Generate</a> | |
<a href="#" class="text-gray-500 hover:text-gray-700 px-3 py-2 text-sm font-medium">My Creations</a> | |
<a href="#" class="text-gray-500 hover:text-gray-700 px-3 py-2 text-sm font-medium">Pricing</a> | |
<a href="#" class="text-gray-500 hover:text-gray-700 px-3 py-2 text-sm font-medium">Community</a> | |
</div> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 flex items-center"> | |
<span class="mr-4 text-sm font-medium text-gray-500">Credits: <span id="creditsCounter" class="text-purple-600 font-bold">100</span>/100</span> | |
<button class="px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"> | |
Upgrade | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</nav> | |
<!-- Main Content --> | |
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> | |
<div class="flex flex-col lg:flex-row gap-8"> | |
<!-- Left Sidebar - Generation Controls --> | |
<div class="w-full lg:w-1/3 space-y-6"> | |
<div class="bg-white rounded-lg shadow-sm p-6 generation-card"> | |
<h2 class="text-lg font-medium text-gray-900 mb-4">Create Magic</h2> | |
<div class="space-y-4"> | |
<div> | |
<label for="prompt" class="block text-sm font-medium text-gray-700 mb-1">Describe your vision</label> | |
<textarea id="prompt" rows="3" class="shadow-sm focus:ring-purple-500 focus:border-purple-500 block w-full sm:text-sm border border-gray-300 rounded-md p-3" placeholder="A futuristic city with flying cars, neon lights, cyberpunk style...">human man holding an alien baby</textarea> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Content Type</label> | |
<div class="flex space-x-4"> | |
<button id="imageBtn" class="flex-1 py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"> | |
Image | |
</button> | |
<button id="videoBtn" class="flex-1 py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"> | |
Video | |
</button> | |
</div> | |
</div> | |
<div id="imageOptions"> | |
<div class="grid grid-cols-2 gap-4"> | |
<div> | |
<label for="style" class="block text-sm font-medium text-gray-700 mb-1">Style</label> | |
<select id="style" class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-purple-500 focus:border-purple-500 sm:text-sm rounded-md"> | |
<option>Realistic</option> | |
<option>Anime</option> | |
<option>Painting</option> | |
<option>Cyberpunk</option> | |
<option>Fantasy</option> | |
</select> | |
</div> | |
<div> | |
<label for="quality" class="block text-sm font-medium text-gray-700 mb-1">Quality</label> | |
<select id="quality" class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-purple-500 focus:border-purple-500 sm:text-sm rounded-md"> | |
<option>Standard</option> | |
<option>High</option> | |
<option>Ultra</option> | |
</select> | |
</div> | |
</div> | |
<div class="mt-4"> | |
<label for="numImages" class="block text-sm font-medium text-gray-700 mb-1">Number of Images (Max 4 at a time)</label> | |
<input type="range" id="numImages" min="1" max="4" value="1" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"> | |
<div class="flex justify-between text-xs text-gray-500 mt-1"> | |
<span>1</span> | |
<span>2</span> | |
<span>3</span> | |
<span>4</span> | |
</div> | |
</div> | |
</div> | |
<div id="videoOptions" class="hidden"> | |
<div> | |
<label for="videoLength" class="block text-sm font-medium text-gray-700 mb-1">Video Length (Max 20 minutes)</label> | |
<input type="range" id="videoLength" min="1" max="20" value="5" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"> | |
<div class="flex justify-between text-xs text-gray-500 mt-1"> | |
<span>1 min</span> | |
<span>5 min</span> | |
<span>10 min</span> | |
<span>15 min</span> | |
<span>20 min</span> | |
</div> | |
</div> | |
<div class="mt-4"> | |
<label for="videoStyle" class="block text-sm font-medium text-gray-700 mb-1">Animation Style</label> | |
<select id="videoStyle" class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-purple-500 focus:border-purple-500 sm:text-sm rounded-md"> | |
<option>Smooth Motion</option> | |
<option>Anime Style</option> | |
<option>Stop Motion</option> | |
<option>Claymation</option> | |
</select> | |
</div> | |
</div> | |
<div class="pt-2"> | |
<button id="generateBtn" class="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"> | |
<i class="fas fa-sparkle mr-2"></i> Generate Now | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white rounded-lg shadow-sm p-6 generation-card"> | |
<h2 class="text-lg font-medium text-gray-900 mb-4">Daily Usage</h2> | |
<div class="space-y-4"> | |
<div> | |
<div class="flex justify-between text-sm font-medium text-gray-700 mb-1"> | |
<span>Image Generations</span> | |
<span><span id="imagesUsed">1</span>/100</span> | |
</div> | |
<div class="w-full bg-gray-200 rounded-full h-2.5"> | |
<div id="imageProgress" class="bg-purple-600 h-2.5 rounded-full" style="width: 1%"></div> | |
</div> | |
</div> | |
<div> | |
<div class="flex justify-between text-sm font-medium text-gray-700 mb-1"> | |
<span>Video Minutes</span> | |
<span><span id="minutesUsed">0</span>/20</span> | |
</div> | |
<div class="w-full bg-gray-200 rounded-full h-2.5"> | |
<div id="videoProgress" class="bg-indigo-600 h-2.5 rounded-full" style="width: 0%"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Right Content - Results --> | |
<div class="w-full lg:w-2/3 space-y-6"> | |
<div class="bg-white rounded-lg shadow-sm p-6"> | |
<div class="flex justify-between items-center mb-4"> | |
<h2 class="text-lg font-medium text-gray-900">Your Creations</h2> | |
<div class="flex space-x-2"> | |
<button class="p-2 rounded-md hover:bg-gray-100"> | |
<i class="fas fa-grid text-gray-500"></i> | |
</button> | |
<button class="p-2 rounded-md hover:bg-gray-100"> | |
<i class="fas fa-list text-gray-500"></i> | |
</button> | |
</div> | |
</div> | |
<!-- Results will appear here --> | |
<div id="resultsArea" class="space-y-6"> | |
<div id="emptyState" class="text-center py-12"> | |
<i class="fas fa-sparkle text-4xl text-purple-200 mb-4"></i> | |
<h3 class="text-lg font-medium text-gray-900 mb-1">Nothing here yet</h3> | |
<p class="text-gray-500">Describe your vision and click "Generate Now" to create something amazing!</p> | |
</div> | |
<div id="loadingState" class="hidden text-center py-12"> | |
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-purple-600 mx-auto mb-4"></div> | |
<h3 class="text-lg font-medium text-gray-900 mb-1">Creating your masterpiece</h3> | |
<p class="text-gray-500">This usually takes 20-45 seconds. Please wait...</p> | |
<div class="w-full bg-gray-200 rounded-full h-1.5 mt-4"> | |
<div id="generationProgress" class="bg-purple-600 h-1.5 rounded-full" style="width: 0%"></div> | |
</div> | |
</div> | |
<div id="imageResults" class="hidden"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="text-md font-medium text-gray-900">Generated Images</h3> | |
<button id="downloadAllBtn" class="text-sm text-purple-600 hover:text-purple-800 font-medium"> | |
<i class="fas fa-download mr-1"></i> Download All | |
</button> | |
</div> | |
<div id="imageGrid" class="grid grid-cols-2 md:grid-cols-3 gap-4"> | |
<!-- Images will be added here by JavaScript --> | |
</div> | |
</div> | |
<div id="videoResults" class="hidden"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="text-md font-medium text-gray-900">Generated Video</h3> | |
<div class="space-x-2"> | |
<button class="text-sm text-purple-600 hover:text-purple-800 font-medium"> | |
<i class="fas fa-download mr-1"></i> Download | |
</button> | |
<button class="text-sm text-purple-600 hover:text-purple-800 font-medium"> | |
<i class="fas fa-share-alt mr-1"></i> Share | |
</button> | |
</div> | |
</div> | |
<div class="video-preview bg-gray-100 rounded-lg overflow-hidden flex items-center justify-center"> | |
<div id="videoPlayer" class="w-full"> | |
<!-- Video will be inserted here by JavaScript --> | |
</div> | |
</div> | |
<div class="mt-4 flex justify-between items-center"> | |
<div> | |
<p class="text-sm text-gray-500">Duration: <span id="videoDuration">0</span> minutes</p> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="p-2 rounded-md hover:bg-gray-100"> | |
<i class="fas fa-edit text-gray-500"></i> | |
</button> | |
<button class="p-2 rounded-md hover:bg-gray-100"> | |
<i class="fas fa-trash text-gray-500"></i> | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white rounded-lg shadow-sm p-6"> | |
<h2 class="text-lg font-medium text-gray-900 mb-4">Recent Creations</h2> | |
<div class="grid grid-cols-2 md:grid-cols-4 gap-4"> | |
<div class="group relative aspect-square bg-gray-100 rounded-lg overflow-hidden cursor-pointer"> | |
<img src="https://images.unsplash.com/photo-1682686580391-615b3f8279b0?w=500&auto=format&fit=crop" class="w-full h-full object-cover"> | |
<div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all duration-200 flex items-center justify-center"> | |
<button class="expand-btn opacity-0 group-hover:opacity-100 transform translate-y-2 group-hover:translate-y-0 transition-all duration-200 text-white bg-purple-600 hover:bg-purple-700 rounded-full p-2"> | |
<i class="fas fa-expand"></i> | |
</button> | |
</div> | |
</div> | |
<div class="group relative aspect-square bg-gray-100 rounded-lg overflow-hidden cursor-pointer"> | |
<div class="absolute inset-0 flex items-center justify-center"> | |
<i class="fas fa-play text-gray-300 text-3xl"></i> | |
</div> | |
<div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all duration-200 flex items-center justify-center"> | |
<button class="opacity-0 group-hover:opacity-100 transform translate-y-2 group-hover:translate-y-0 transition-all duration-200 text-white bg-purple-600 hover:bg-purple-700 rounded-full p-2"> | |
<i class="fas fa-expand"></i> | |
</button> | |
</div> | |
</div> | |
<div class="group relative aspect-square bg-gray-100 rounded-lg overflow-hidden cursor-pointer"> | |
<img src="https://images.unsplash.com/photo-1682695796954-bad0d0f59ff1?w=500&auto=format&fit=crop" class="w-full h-full object-cover"> | |
<div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all duration-200 flex items-center justify-center"> | |
<button class="expand-btn opacity-0 group-hover:opacity-100 transform translate-y-2 group-hover:translate-y-0 transition-all duration-200 text-white bg-purple-600 hover:bg-purple-700 rounded-full p-2"> | |
<i class="fas fa-expand"></i> | |
</button> | |
</div> | |
</div> | |
<div class="group relative aspect-square bg-gray-100 rounded-lg overflow-hidden cursor-pointer"> | |
<div class="absolute inset-0 flex items-center justify-center"> | |
<i class="fas fa-play text-gray-300 text-3xl"></i> | |
</div> | |
<div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all duration-200 flex items-center justify-center"> | |
<button class="opacity-0 group-hover:opacity-100 transform translate-y-2 group-hover:translate-y-0 transition-all duration-200 text-white bg-purple-600 hover:bg-purple-700 rounded-full p-2"> | |
<i class="fas fa-expand"></i> | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</main> | |
<!-- Footer --> | |
<footer class="bg-white border-t border-gray-200 mt-12"> | |
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> | |
<div class="grid grid-cols-1 md:grid-cols-4 gap-8"> | |
<div> | |
<h3 class="text-sm font-semibold text-gray-900 tracking-wider uppercase mb-4">ArtFlow</h3> | |
<p class="text-sm text-gray-500">The easiest way to create stunning visuals and animations for your stories and projects.</p> | |
</div> | |
<div> | |
<h3 class="text-sm font-semibold text-gray-900 tracking-wider uppercase mb-4">Product</h3> | |
<ul class="space-y-2"> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Features</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Pricing</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">API</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Changelog</a></li> | |
</ul> | |
</div> | |
<div> | |
<h3 class="text-sm font-semibold text-gray-900 tracking-wider uppercase mb-4">Resources</h3> | |
<ul class="space-y-2"> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Documentation</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Community</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Tutorials</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Blog</a></li> | |
</ul> | |
</div> | |
<div> | |
<h3 class="text-sm font-semibold text-gray-900 tracking-wider uppercase mb-4">Company</h3> | |
<ul class="space-y-2"> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">About</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Careers</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Privacy</a></li> | |
<li><a href="#" class="text-sm text-gray-500 hover:text-purple-600">Terms</a></li> | |
</ul> | |
</div> | |
</div> | |
<div class="mt-8 pt-8 border-t border-gray-200 flex flex-col md:flex-row justify-between items-center"> | |
<p class="text-sm text-gray-500">© 2023 ArtFlow. All rights reserved.</p> | |
<div class="flex space-x-6 mt-4 md:mt-0"> | |
<a href="#" class="text-gray-400 hover:text-gray-500"> | |
<i class="fab fa-twitter"></i> | |
</a> | |
<a href="#" class="text-gray-400 hover:text-gray-500"> | |
<i class="fab fa-discord"></i> | |
</a> | |
<a href="#" class="text-gray-400 hover:text-gray-500"> | |
<i class="fab fa-github"></i> | |
</a> | |
<a href="#" class="text-gray-400 hover:text-gray-500"> | |
<i class="fab fa-instagram"></i> | |
</a> | |
</div> | |
</div> | |
</div> | |
</footer> | |
<!-- Image Preview Modal --> | |
<div id="imageModal" class="fixed inset-0 z-50 hidden overflow-y-auto"> | |
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> | |
<div class="fixed inset-0 transition-opacity" aria-hidden="true"> | |
<div class="absolute inset-0 bg-gray-500 opacity-75"></div> | |
</div> | |
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span> | |
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-4xl sm:w-full"> | |
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4"> | |
<div class="sm:flex sm:items-start"> | |
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">Image Preview</h3> | |
<button id="closeModal" class="text-gray-400 hover:text-gray-500"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="mt-2"> | |
<img id="modalImage" src="" alt="Preview" class="w-full h-auto max-h-[70vh] object-contain"> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse"> | |
<button type="button" id="downloadModalBtn" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-purple-600 text-base font-medium text-white hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500 sm:ml-3 sm:w-auto sm:text-sm"> | |
<i class="fas fa-download mr-2"></i> Download | |
</button> | |
<button type="button" id="closeModalBtn" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"> | |
Close | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
// DOM Elements | |
const imageBtn = document.getElementById('imageBtn'); | |
const videoBtn = document.getElementById('videoBtn'); | |
const imageOptions = document.getElementById('imageOptions'); | |
const videoOptions = document.getElementById('videoOptions'); | |
const generateBtn = document.getElementById('generateBtn'); | |
const emptyState = document.getElementById('emptyState'); | |
const loadingState = document.getElementById('loadingState'); | |
const imageResults = document.getElementById('imageResults'); | |
const videoResults = document.getElementById('videoResults'); | |
const imageGrid = document.getElementById('imageGrid'); | |
const videoPlayer = document.getElementById('videoPlayer'); | |
const creditsCounter = document.getElementById('creditsCounter'); | |
const imagesUsed = document.getElementById('imagesUsed'); | |
const minutesUsed = document.getElementById('minutesUsed'); | |
const imageProgress = document.getElementById('imageProgress'); | |
const videoProgress = document.getElementById('videoProgress'); | |
const generationProgress = document.getElementById('generationProgress'); | |
const numImages = document.getElementById('numImages'); | |
const videoLength = document.getElementById('videoLength'); | |
const videoDuration = document.getElementById('videoDuration'); | |
const downloadAllBtn = document.getElementById('downloadAllBtn'); | |
const promptInput = document.getElementById('prompt'); | |
const styleSelect = document.getElementById('style'); | |
const qualitySelect = document.getElementById('quality'); | |
// Modal elements | |
const imageModal = document.getElementById('imageModal'); | |
const modalImage = document.getElementById('modalImage'); | |
const closeModal = document.getElementById('closeModal'); | |
const closeModalBtn = document.getElementById('closeModalBtn'); | |
const downloadModalBtn = document.getElementById('downloadModalBtn'); | |
// State | |
let isGenerating = false; | |
let currentMode = 'image'; // 'image' or 'video' | |
let usedImagesToday = 1; // Starting with 1 as per request | |
let usedMinutesToday = 0; | |
let credits = 100; | |
// Sample image URLs for demonstration | |
const sampleImages = [ | |
'https://images.unsplash.com/photo-1682686580391-615b3f8279b0?w=500&auto=format&fit=crop', | |
'https://images.unsplash.com/photo-1682695796954-bad0d0f59ff1?w=500&auto=format&fit=crop', | |
'https://images.unsplash.com/photo-1682686580391-615b3f8279b0?w=500&auto=format&fit=crop', | |
'https://images.unsplash.com/photo-1682695796954-bad0d0f59ff1?w=500&auto=format&fit=crop' | |
]; | |
// Sample video for demonstration | |
const sampleVideo = '<video controls class="w-full h-full"><source src="https://samplelib.com/lib/preview/mp4/sample-5s.mp4" type="video/mp4"></video>'; | |
// Event Listeners | |
imageBtn.addEventListener('click', () => { | |
currentMode = 'image'; | |
imageBtn.classList.remove('bg-white', 'text-gray-700', 'border-gray-300'); | |
imageBtn.classList.add('bg-purple-600', 'text-white'); | |
videoBtn.classList.remove('bg-purple-600', 'text-white'); | |
videoBtn.classList.add('bg-white', 'text-gray-700', 'border-gray-300'); | |
imageOptions.classList.remove('hidden'); | |
videoOptions.classList.add('hidden'); | |
imageResults.classList.remove('hidden'); | |
videoResults.classList.add('hidden'); | |
}); | |
videoBtn.addEventListener('click', () => { | |
currentMode = 'video'; | |
videoBtn.classList.remove('bg-white', 'text-gray-700', 'border-gray-300'); | |
videoBtn.classList.add('bg-purple-600', 'text-white'); | |
imageBtn.classList.remove('bg-purple-600', 'text-white'); | |
imageBtn.classList.add('bg-white', 'text-gray-700', 'border-gray-300'); | |
videoOptions.classList.remove('hidden'); | |
imageOptions.classList.add('hidden'); | |
videoResults.classList.remove('hidden'); | |
imageResults.classList.add('hidden'); | |
}); | |
generateBtn.addEventListener('click', () => { | |
if (isGenerating) return; | |
const prompt = promptInput.value.trim(); | |
if (!prompt) { | |
alert('Please enter a description for your generation'); | |
return; | |
} | |
if (currentMode === 'image') { | |
const num = parseInt(numImages.value); | |
if (usedImagesToday + num > 100) { | |
alert(`You can only generate ${100 - usedImagesToday} more images today`); | |
return; | |
} | |
} else { | |
const minutes = parseInt(videoLength.value); | |
if (usedMinutesToday + minutes > 20) { | |
alert(`You can only generate ${20 - usedMinutesToday} more minutes of video today`); | |
return; | |
} | |
} | |
startGeneration(); | |
}); | |
downloadAllBtn.addEventListener('click', () => { | |
alert('All images will be downloaded as a ZIP file'); | |
}); | |
// Handle image clicks for preview and download | |
document.addEventListener('click', (e) => { | |
// Handle expand button clicks | |
if (e.target.classList.contains('expand-btn') || e.target.closest('.expand-btn')) { | |
const imgElement = e.target.closest('.group').querySelector('img'); | |
if (imgElement) { | |
openImageModal(imgElement.src); | |
} | |
} | |
// Handle download button clicks | |
if (e.target.classList.contains('download-btn') || e.target.closest('.download-btn')) { | |
const imgElement = e.target.closest('.group').querySelector('img'); | |
if (imgElement) { | |
downloadImage(imgElement.src); | |
} | |
} | |
}); | |
// Modal event listeners | |
closeModal.addEventListener('click', () => { | |
imageModal.classList.add('hidden'); | |
}); | |
closeModalBtn.addEventListener('click', () => { | |
imageModal.classList.add('hidden'); | |
}); | |
downloadModalBtn.addEventListener('click', () => { | |
downloadImage(modalImage.src); | |
}); | |
// Functions | |
function startGeneration() { | |
isGenerating = true; | |
emptyState.classList.add('hidden'); | |
loadingState.classList.remove('hidden'); | |
imageResults.classList.add('hidden'); | |
videoResults.classList.add('hidden'); | |
// Simulate generation progress | |
let progress = 0; | |
const interval = setInterval(() => { | |
progress += Math.random() * 10; | |
if (progress > 100) progress = 100; | |
generationProgress.style.width = `${progress}%`; | |
if (progress >= 100) { | |
clearInterval(interval); | |
finishGeneration(); | |
} | |
}, 300); | |
} | |
function finishGeneration() { | |
isGenerating = false; | |
loadingState.classList.add('hidden'); | |
if (currentMode === 'image') { | |
const num = parseInt(numImages.value); | |
usedImagesToday += num; | |
credits -= num; | |
// Update UI | |
imagesUsed.textContent = usedImagesToday; | |
creditsCounter.textContent = credits; | |
imageProgress.style.width = `${(usedImagesToday / 100) * 100}%`; | |
// Display results | |
imageGrid.innerHTML = ''; | |
for (let i = 0; i < num; i++) { | |
// Generate a unique image based on prompt and settings | |
const prompt = promptInput.value; | |
const style = styleSelect.value; | |
const quality = qualitySelect.value; | |
// In a real app, this would call an API to generate the image | |
// For demo, we'll use sample images with different cache-busting parameters | |
const imgUrl = getGeneratedImageUrl(prompt, style, quality, i); | |
imageGrid.innerHTML += ` | |
<div class="group relative aspect-square bg-gray-100 rounded-lg overflow-hidden generated-image"> | |
<img src="${imgUrl}" alt="Generated image" class="w-full h-full object-cover"> | |
<div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all duration-200 flex items-center justify-center opacity-0 group-hover:opacity-100"> | |
<div class="flex space-x-2"> | |
<button class="download-btn text-white bg-purple-600 hover:bg-purple-700 rounded-full p-2"> | |
<i class="fas fa-download"></i> | |
</button> | |
<button class="expand-btn text-white bg-purple-600 hover:bg-purple-700 rounded-full p-2"> | |
<i class="fas fa-expand"></i> | |
</button> | |
</div> | |
</div> | |
</div> | |
`; | |
} | |
imageResults.classList.remove('hidden'); | |
} else { | |
const minutes = parseInt(videoLength.value); | |
usedMinutesToday += minutes; | |
credits -= minutes; | |
// Update UI | |
minutesUsed.textContent = usedMinutesToday; | |
creditsCounter.textContent = credits; | |
videoProgress.style.width = `${(usedMinutesToday / 20) * 100}%`; | |
videoDuration.textContent = minutes; | |
// Display results | |
videoPlayer.innerHTML = sampleVideo; | |
videoResults.classList.remove('hidden'); | |
} | |
} | |
function getGeneratedImageUrl(prompt, style, quality, index) { | |
// In a real app, this would call an API to generate the image | |
// For demo purposes, we'll return different sample images based on parameters | |
const baseUrl = sampleImages[index % sampleImages.length]; | |
return `${baseUrl}&prompt=${encodeURIComponent(prompt)}&style=${style}&quality=${quality}&t=${Date.now()}`; | |
} | |
function openImageModal(imageUrl) { | |
modalImage.src = imageUrl; | |
imageModal.classList.remove('hidden'); | |
} | |
function downloadImage(imageUrl) { | |
// In a real app, this would properly download the image | |
// For demo, we'll just show an alert | |
alert(`Downloading image: ${imageUrl.split('?')[0]}`); | |
// This would be the actual download code: | |
/* | |
const link = document.createElement('a'); | |
link.href = imageUrl; | |
link.download = `artflow-${Date.now()}.jpg`; | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
*/ | |
} | |
// Initialize | |
imageBtn.click(); // Set default to image mode | |
imageProgress.style.width = `${(usedImagesToday / 100) * 100}%`; // Set initial progress | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=theaimoron/aet-flow" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |