Spaces:
Running
Running
| // Demo Data for Cat Images | |
| const catImages = [ | |
| { id: 1, url: 'https://static.photos/cats/640x360/10', title: 'Regal Persian', category: 'realistic', likes: 234, author: 'CatLover99' }, | |
| { id: 2, url: 'https://static.photos/cats/640x360/11', title: 'Cyber Punk Kitty', category: 'anime', likes: 567, author: 'NeonArtist' }, | |
| { id: 3, url: 'https://static.photos/cats/640x360/12', title: 'Abstract Feline', category: 'artistic', likes: 123, author: 'ArtMaster' }, | |
| { id: 4, url: 'https://static.photos/cats/640x360/13', title: '3D Render Cat', category: '3d', likes: 890, author: 'RenderPro' }, | |
| { id: 5, url: 'https://static.photos/cats/640x360/14', title: 'Vintage Tabby', category: 'vintage', likes: 456, author: 'RetroFan' }, | |
| { id: 6, url: 'https://static.photos/cats/640x360/15', title: 'Realistic Maine Coon', category: 'realistic', likes: 678, author: 'NaturePhotog' }, | |
| { id: 7, url: 'https://static.photos/cats/640x360/16', title: 'Chibi Cat', category: 'anime', likes: 789, author: 'KawaiiMaker' }, | |
| { id: 8, url: 'https://static.photos/cats/640x360/17', title: 'Oil Painting Style', category: 'artistic', likes: 345, author: 'PainterAI' }, | |
| ]; | |
| // Demo Data for Cat Videos | |
| const catVideos = [ | |
| { id: 1, thumbnail: 'https://static.photos/cats/640x360/20', title: 'Sleepy Cat Loop', category: 'loop', duration: '0:15', views: '2.3k' }, | |
| { id: 2, thumbnail: 'https://static.photos/cats/640x360/21', title: 'Epic Cat Jump', category: 'cinematic', duration: '0:08', views: '5.1k' }, | |
| { id: 3, thumbnail: 'https://static.photos/cats/640x360/22', title: 'Cartoon Cat Dance', category: 'animation', duration: '0:12', views: '1.8k' }, | |
| { id: 4, thumbnail: 'https://static.photos/cats/640x360/23', title: 'Slow Blink', category: 'slowmo', duration: '0:20', views: '3.4k' }, | |
| { id: 5, thumbnail: 'https://static.photos/cats/640x360/24', title: 'Playful Kitten', category: 'cinematic', duration: '0:25', views: '4.2k' }, | |
| { id: 6, thumbnail: 'https://static.photos/cats/640x360/25', title: 'Floating Cat', category: 'animation', duration: '0:10', views: '2.9k' }, | |
| { id: 7, thumbnail: 'https://static.photos/cats/640x360/26', title: 'Pounce in Slow Mo', category: 'slowmo', duration: '0:30', views: '6.7k' }, | |
| { id: 8, thumbnail: 'https://static.photos/cats/640x360/27', title: 'Endless Purring', category: 'loop', duration: '0:08', views: '1.2k' }, | |
| ]; | |
| // Initialize Sidebar Toggle | |
| function toggleSidebar() { | |
| const sidebar = document.getElementById('sidebar'); | |
| const overlay = document.getElementById('mobile-overlay'); | |
| if (sidebar.classList.contains('-translate-x-full')) { | |
| sidebar.classList.remove('-translate-x-full'); | |
| overlay.classList.remove('hidden'); | |
| } else { | |
| sidebar.classList.add('-translate-x-full'); | |
| overlay.classList.add('hidden'); | |
| } | |
| } | |
| // Render Image Cards | |
| function renderImages(filter = 'all') { | |
| const grid = document.getElementById('image-grid'); | |
| grid.innerHTML = ''; | |
| const filtered = filter === 'all' ? catImages : catImages.filter(img => img.category === filter); | |
| filtered.forEach(img => { | |
| const card = document.createElement('div'); | |
| card.className = 'card-hover bg-white rounded-xl overflow-hidden border border-slate-200 group cursor-pointer'; | |
| card.innerHTML = ` | |
| <div class="relative aspect-[4/3] overflow-hidden bg-slate-100"> | |
| <img src="${img.url}" alt="${img.title}" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"> | |
| <div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors flex items-center justify-center opacity-0 group-hover:opacity-100"> | |
| <button class="bg-white text-slate-900 px-4 py-2 rounded-full text-sm font-medium shadow-lg transform scale-90 group-hover:scale-100 transition-transform"> | |
| Use Template | |
| </button> | |
| </div> | |
| <div class="absolute top-2 right-2"> | |
| <span class="px-2 py-1 bg-white/90 backdrop-blur text-xs font-medium text-slate-700 rounded-md capitalize"> | |
| ${img.category} | |
| </span> | |
| </div> | |
| </div> | |
| <div class="p-4"> | |
| <div class="flex items-start justify-between mb-2"> | |
| <h3 class="font-semibold text-slate-900 truncate pr-2">${img.title}</h3> | |
| <button class="text-slate-400 hover:text-red-500 transition-colors" onclick="event.stopPropagation(); toggleLike(this)"> | |
| <i data-lucide="heart" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center justify-between text-sm text-slate-500"> | |
| <span class="flex items-center gap-1"> | |
| <i data-lucide="user" class="w-3 h-3"></i> | |
| ${img.author} | |
| </span> | |
| <span class="flex items-center gap-1"> | |
| <i data-lucide="heart" class="w-3 h-3 fill-current"></i> | |
| ${img.likes} | |
| </span> | |
| </div> | |
| </div> | |
| `; | |
| grid.appendChild(card); | |
| }); | |
| // Re-initialize Lucide icons for new content | |
| if (window.lucide) { | |
| lucide.createIcons(); | |
| } | |
| } | |
| // Render Video Cards | |
| function renderVideos(filter = 'all') { | |
| const grid = document.getElementById('video-grid'); | |
| grid.innerHTML = ''; | |
| const filtered = filter === 'all' ? catVideos : catVideos.filter(vid => vid.category === filter); | |
| filtered.forEach(vid => { | |
| const card = document.createElement('div'); | |
| card.className = 'card-hover bg-white rounded-xl overflow-hidden border border-slate-200 group cursor-pointer'; | |
| card.innerHTML = ` | |
| <div class="relative aspect-video overflow-hidden bg-slate-100"> | |
| <img src="${vid.thumbnail}" alt="${vid.title}" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"> | |
| <div class="absolute inset-0 bg-black/20 group-hover:bg-black/40 transition-colors flex items-center justify-center"> | |
| <div class="w-12 h-12 bg-white/90 rounded-full flex items-center justify-center shadow-lg transform scale-90 group-hover:scale-100 transition-transform"> | |
| <i data-lucide="play" class="w-5 h-5 text-slate-900 ml-1"></i> | |
| </div> | |
| </div> | |
| <div class="absolute top-2 right-2 px-2 py-1 bg-black/70 text-white text-xs font-medium rounded"> | |
| ${vid.duration} | |
| </div> | |
| <div class="absolute bottom-2 left-2"> | |
| <span class="px-2 py-1 bg-white/90 backdrop-blur text-xs font-medium text-slate-700 rounded-md capitalize"> | |
| ${vid.category} | |
| </span> | |
| </div> | |
| </div> | |
| <div class="p-4"> | |
| <h3 class="font-semibold text-slate-900 mb-1 truncate">${vid.title}</h3> | |
| <div class="flex items-center gap-2 text-sm text-slate-500"> | |
| <i data-lucide="eye" class="w-4 h-4"></i> | |
| <span>${vid.views} views</span> | |
| </div> | |
| </div> | |
| `; | |
| grid.appendChild(card); | |
| }); | |
| // Re-initialize Lucide icons | |
| if (window.lucide) { | |
| lucide.createIcons(); | |
| } | |
| } | |
| // Toggle Like Button | |
| function toggleLike(btn) { | |
| const icon = btn.querySelector('i'); | |
| if (btn.classList.contains('text-red-500')) { | |
| btn.classList.remove('text-red-500'); | |
| btn.classList.add('text-slate-400'); | |
| icon.classList.remove('fill-current'); | |
| } else { | |
| btn.classList.add('text-red-500'); | |
| btn.classList.remove('text-slate-400'); | |
| icon.classList.add('fill-current'); | |
| } | |
| } | |
| // Filter Event Listeners | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // Initialize grids | |
| renderImages(); | |
| renderVideos(); | |
| // Image filters | |
| const imageFilters = document.getElementById('image-filters'); | |
| imageFilters.addEventListener('click', (e) => { | |
| if (e.target.classList.contains('filter-pill')) { | |
| imageFilters.querySelectorAll('.filter-pill').forEach(btn => btn.classList.remove('active')); | |
| e.target.classList.add('active'); | |
| renderImages(e.target.dataset.filter); | |
| } | |
| }); | |
| // Video filters | |
| const videoFilters = document.getElementById('video-filters'); | |
| videoFilters.addEventListener('click', (e) => { | |
| if (e.target.classList.contains('filter-pill')) { | |
| videoFilters.querySelectorAll('.filter-pill').forEach(btn => btn.classList.remove('active')); | |
| e.target.classList.add('active'); | |
| renderVideos(e.target.dataset.filter); | |
| } | |
| }); | |
| // Close sidebar on window resize if open | |
| window.addEventListener('resize', () => { | |
| if (window.innerWidth >= 1024) { | |
| document.getElementById('mobile-overlay').classList.add('hidden'); | |
| } | |
| }); | |
| }); |