EcoArtLab Static Gallery Generator

🚀 Static Gallery Generator

Generate 2000+ SEO-optimized HTML pages from your Google Drive artwork collection

1. Scan Drive
2. Process Images
3. Generate Pages
4. Create ZIP
5. Download

Generation Progress

Initializing...
${headerHTML}
${escapeHtml(artwork.title)}

${escapeHtml(artwork.title)}

Category: ${escapeHtml(artwork.category)}

${escapeHtml(artwork.description)}

${relatedHTML}
${footerHTML} `; } function generateCategoryHTML(category, artworks) { const headerHTML = generateHeader(); const footerHTML = generateFooter(); // Generate artworks HTML const artworksHTML = artworks.map(artwork => `
${escapeHtml(artwork.title)}

${escapeHtml(artwork.title)}

` ).join(''); return ` ${escapeHtml(category.name)} Frame TV Art Collection | EcoArtLab ${headerHTML}

${escapeHtml(category.name)} Collection

Explore ${artworks.length} premium artworks in the ${escapeHtml(category.name)} category

${artworksHTML}
${footerHTML} `; } function generateMainIndexHTML() { const headerHTML = generateHeader(); const footerHTML = generateFooter(); // Generate categories HTML const categoriesHTML = allCategories.map(category => `

${escapeHtml(category.name)}

${category.artworkCount} artworks

` ).join(''); // Generate featured artworks HTML const featuredHTML = allArtworks.slice(0, 12).map(artwork => `
${escapeHtml(artwork.title)}

${escapeHtml(artwork.title)}

` ).join(''); return ` Premium Frame TV Art Gallery - 2000+ Digital Artworks | EcoArtLab ${headerHTML}

Browse by Category

${categoriesHTML}
${footerHTML} `; } function generateHeader() { return `
EcoArtLab Frame TV Art Library
`; } function generateFooter() { return ``; } function generateCSS() { return `/* EcoArtLab Static Gallery Styles */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Montserrat', Arial, sans-serif; background: #f5f5f5; color: #333; line-height: 1.6; } .container { max-width: 1200px; margin: 0 auto; padding: 2rem; } /* Header styles (same as original) */ header.top-bar { background: #000; color: #fff; min-height: 56px; display: flex; align-items: center; justify-content: space-between; padding: 7px 12px; position: sticky; top: 0; z-index: 1000; } .brand { display: flex; align-items: center; text-decoration: none; color: inherit; } .logo { height: 36px; margin-right: 10px; } .brand-title { font-size: 18px; font-weight: bold; } .nav-menu { display: flex; list-style: none; gap: 25px; align-items: center; } .nav-menu a { color: #fff; text-decoration: none; font-size: 15px; padding: 8px 12px; border-radius: 6px; transition: all 0.3s ease; } .nav-menu a:hover { background: rgba(0, 214, 180, 0.1); color: #00d6b4; } .nav-cta { background: #00d6b4 !important; color: #000 !important; font-weight: bold; padding: 10px 18px !important; border-radius: 25px; } /* Gallery styles */ .gallery-hero, .category-hero, .artwork-hero { text-align: center; padding: 3rem 0; background: white; border-radius: 12px; margin-bottom: 2rem; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .gallery-hero h1, .category-hero h1 { font-size: 3rem; margin-bottom: 1rem; color: #333; } .gallery-hero p, .category-hero p { font-size: 1.2rem; color: #666; } .category-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; margin: 2rem 0; } .category-card { background: white; border-radius: 12px; padding: 2rem; text-align: center; box-shadow: 0 2px 10px rgba(0,0,0,0.1); transition: transform 0.3s ease; } .category-card:hover { transform: translateY(-5px); } .category-card a { text-decoration: none; color: inherit; } .artwork-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.5rem; margin: 2rem 0; } .artwork-card { background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); transition: transform 0.3s ease; } .artwork-card:hover { transform: translateY(-5px); } .artwork-card img { width: 100%; height: 250px; object-fit: cover; } .artwork-card h3 { padding: 1rem; font-size: 1.1rem; color: #333; } .artwork-card a { text-decoration: none; color: inherit; } /* Individual artwork page */ .artwork-hero { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center; text-align: left; } .artwork-image img { width: 100%; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); } .artwork-details h1 { font-size: 2.5rem; margin-bottom: 1rem; } .artwork-category { color: #666; margin-bottom: 1rem; } .artwork-description { font-size: 1.1rem; margin-bottom: 2rem; line-height: 1.8; } .artwork-actions { display: flex; gap: 1rem; } .btn { padding: 12px 24px; border-radius: 6px; text-decoration: none; font-weight: bold; border: none; cursor: pointer; transition: all 0.3s ease; } .btn-primary { background: #00d6b4; color: black; } .btn-secondary { background: #6c757d; color: white; } .btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.2); } .breadcrumb { background: white; padding: 1rem; border-radius: 8px; margin-bottom: 2rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); } .breadcrumb a { color: #00d6b4; text-decoration: none; } .breadcrumb a:hover { text-decoration: underline; } .site-footer { background: #fff; padding: 40px 4vw 32px 4vw; text-align: center; border-top: 1px solid #eee; margin-top: 4rem; } .footer-logo { max-width: 100px; border-radius: 10px; margin: 14px 0; } .social-links a, .shop-links a { color: #00d6b4; text-decoration: none; margin: 0 8px; } @media (max-width: 768px) { .container { padding: 1rem; } .artwork-hero { grid-template-columns: 1fr; gap: 2rem; } .gallery-hero h1, .category-hero h1 { font-size: 2rem; } .artwork-grid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); } .category-grid { grid-template-columns: 1fr; } }`; } function generateJS() { return `// EcoArtLab Static Gallery JavaScript document.addEventListener('DOMContentLoaded', function() { // Navigation functionality const menuToggle = document.getElementById('menuToggle'); const navContainer = document.getElementById('navContainer'); if (menuToggle && navContainer) { menuToggle.addEventListener('click', function() { menuToggle.classList.toggle('active'); navContainer.classList.toggle('active'); }); } }); // Share artwork function function shareArtwork() { if (navigator.share) { navigator.share({ title: document.title, url: window.location.href }); } else { // Fallback: copy to clipboard navigator.clipboard.writeText(window.location.href).then(() => { alert('Link copied to clipboard!'); }); } } // Search functionality (if needed) function searchArtworks(query) { // Implementation for search console.log('Searching for:', query); }`; } // Utility functions function createSlug(text) { return text .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, '') .substring(0, 100); } function formatTitle(filename) { return filename .replace(/\.[^/.]+$/, '') .replace(/[-_]/g, ' ') .replace(/\b\w/g, l => l.toUpperCase()) .trim(); } function generateDescription(title, category) { return `Premium ${title} artwork for Samsung Frame TV. High-quality digital art in ${category} style. Perfect for modern home decor and smart displays.`; } function generateKeywords(title, category) { const baseKeywords = ['frame tv art', 'digital art', 'samsung frame tv', 'wall art']; const titleWords = title.toLowerCase().split(' ').filter(word => word.length > 3); const categoryWords = category.toLowerCase().split(' '); return [...baseKeywords, ...titleWords, ...categoryWords].join(', '); } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // UI functions function showStatus(message, type) { const statusDiv = document.getElementById('status'); statusDiv.innerHTML = `
${message}
`; if (type === 'success' || type === 'info') { setTimeout(() => statusDiv.innerHTML = '', 5000); } } function showProgress(show) { document.getElementById('progressContainer').style.display = show ? 'block' : 'none'; } function updateProgress(percent, text) { document.getElementById('progressFill').style.width = percent + '%'; document.getElementById('progressText').textContent = text; } function setStep(step) { // Reset all steps for (let i = 1; i <= 5; i++) { const stepEl = document.getElementById(`step${i}`); stepEl.className = 'step'; } // Mark completed steps for (let i = 1; i < step; i++) { document.getElementById(`step${i}`).classList.add('completed'); } // Mark current step if (step <= 5) { document.getElementById(`step${step}`).classList.add('active'); } currentStep = step; } function updateStats() { document.getElementById('totalImages').textContent = allArtworks.length; document.getElementById('totalCategories').textContent = allCategories.length; document.getElementById('generatedPages').textContent = generatedFiles.length; const totalSize = generatedFiles.reduce((size, file) => { return size + (new Blob([file.content]).size / 1024 / 1024); }, 0); document.getElementById('totalSize').textContent = totalSize.toFixed(1) + ' MB'; } function previewData() { const preview = document.getElementById('dataPreview'); const content = document.getElementById('previewContent'); let html = `
📁 Categories (${allCategories.length})
${allCategories.slice(0, 8).map(cat => `
${escapeHtml(cat.name)}
${cat.artworkCount} artworks
`).join('')}
🖼️ Sample Artworks (${allArtworks.length} total)
${allArtworks.slice(0, 10).map(artwork => `
${escapeHtml(artwork.title)}
${escapeHtml(artwork.title)}
Category: ${escapeHtml(artwork.category)} | URL: ${artwork.url}
`).join('')}
`; content.innerHTML = html; preview.style.display = 'block'; // Also show code preview showCodePreview(); } function showCodePreview() { const codePreview = document.getElementById('codePreview'); const codeContent = document.getElementById('codeContent'); const sampleArtwork = allArtworks[0]; const sampleHTML = generateArtworkHTML(sampleArtwork); codeContent.textContent = sampleHTML.substring(0, 2000) + '\n\n... (truncated for preview)'; codePreview.style.display = 'block'; } async function downloadZip() { if (generatedFiles.length === 0) { showStatus('No files generated yet. Please run the generation first.', 'error'); return; } showStatus('Creating ZIP file...', 'info'); try { // Create a tar-like archive using JSON structure const archive = { info: { name: 'EcoArtLab Static Gallery', version: '1.0.0', generated: new Date().toISOString(), totalFiles: generatedFiles.length, totalSize: generatedFiles.reduce((size, file) => size + new Blob([file.content]).size, 0) }, files: {} }; // Add all generated files to archive generatedFiles.forEach(file => { archive.files[file.path] = { content: file.content, type: file.type, size: new Blob([file.content]).size }; }); // Create archive file const archiveContent = JSON.stringify(archive, null, 2); const archiveBlob = new Blob([archiveContent], { type: 'application/json' }); // Download archive const archiveUrl = URL.createObjectURL(archiveBlob); const archiveLink = document.createElement('a'); archiveLink.href = archiveUrl; archiveLink.download = 'ecoartlab-static-gallery-archive.json'; document.body.appendChild(archiveLink); archiveLink.click(); document.body.removeChild(archiveLink); URL.revokeObjectURL(archiveUrl); // Also download individual key files for immediate use const keyFiles = [ { file: generatedFiles.find(f => f.path === 'index.html'), name: 'index.html' }, { file: generatedFiles.find(f => f.path === 'assets/styles.css'), name: 'styles.css' }, { file: generatedFiles.find(f => f.path === 'assets/script.js'), name: 'script.js' }, { file: generatedFiles.find(f => f.path === 'data/artworks.json'), name: 'artworks.json' }, { file: generatedFiles.filter(f => f.type === 'category')[0], name: 'sample-category.html' }, { file: generatedFiles.filter(f => f.type === 'artwork')[0], name: 'sample-artwork.html' } ].filter(item => item.file); // Download key files with delay for (const item of keyFiles) { await new Promise(resolve => setTimeout(resolve, 800)); const blob = new Blob([item.file.content], { type: item.name.endsWith('.html') ? 'text/html' : item.name.endsWith('.css') ? 'text/css' : item.name.endsWith('.js') ? 'text/javascript' : 'application/json' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = item.name; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); } // Create extraction instructions const instructions = createInstructionsHTML(); // Download instructions file await new Promise(resolve => setTimeout(resolve, 1000)); const instructionsBlob = new Blob([instructions], { type: 'text/html' }); const instructionsUrl = URL.createObjectURL(instructionsBlob); const instructionsLink = document.createElement('a'); instructionsLink.href = instructionsUrl; instructionsLink.download = 'SETUP-INSTRUCTIONS.html'; document.body.appendChild(instructionsLink); instructionsLink.click(); document.body.removeChild(instructionsLink); URL.revokeObjectURL(instructionsUrl); showStatus(`Gallery archive created! Downloaded ${keyFiles.length + 2} files total. Check your downloads folder.`, 'success'); } catch (error) { console.error('Download failed:', error); showStatus('Download failed. Please try again.', 'error'); } } function createInstructionsHTML() { return `# EcoArtLab Static Gallery - Setup Instructions ## What you downloaded: 1. **ecoartlab-static-gallery-archive.json** - Complete archive with all files 2. **Key files** - Individual files for immediate testing ## Quick Setup: 1. Extract the archive using the provided extractor tool 2. Upload files to your web server 3. Point your domain to the new gallery ## Archive Extractor Tool: Use this simple HTML tool to extract all files from the archive: Gallery Archive Extractor

🎨 EcoArtLab Gallery Archive Extractor

Drop your archive file here or click to select

`; } function resetGenerator() { allArtworks = []; allCategories = []; generatedFiles = []; currentStep = 1; // Reset UI document.getElementById('previewBtn').disabled = true; document.getElementById('downloadBtn').disabled = true; document.getElementById('statsGrid').style.display = 'none'; document.getElementById('downloadSection').style.display = 'none'; document.getElementById('dataPreview').style.display = 'none'; document.getElementById('codePreview').style.display = 'none'; showProgress(false); setStep(1); showStatus('Generator reset. Ready to start again!', 'info'); }