πŸ”§Color Palette Generator

Generate beautiful color palettes with AI. Create harmonious color schemes from images, color theory, or random generation. Perfect for designers, artists, and developers.

πŸ€” What Is a Color Palette Generator?

Think of a fashion stylist who always knows which colors look perfect together - that's a Color Palette Generator! It creates harmonious color schemes based on color theory, your images, or inspiration, giving designers and creatives perfectly matched colors for any project.

🎲 Random Generator
🎨 Color Wheel
πŸ“Έ From Image
🌈 Gradient

Color Harmony Type

Complementary
Analogous
Triadic
Split Comp
Tetradic
Monochrome
πŸ“·
Drop an image here or click to upload
JPG, PNG, GIF up to 10MB
/* CSS will appear here */

🎨 Generated Color Palette

Generate a palette using one of the methods above

β™Ώ Accessibility Check

πŸ“€ Export Palette

CSS Variables
For web development
SCSS/Sass
For preprocessors
JSON
For applications
PNG Image
For presentations
Adobe ASE
For Adobe apps
Sketch Palette
For Sketch app
`; container.appendChild(colorCard); }); } // Copy color code function copyColorCode(code, event) { if (event) { event.stopPropagation(); } navigator.clipboard.writeText(code).then(() => { showNotification(`Copied: ${code}`, 'success'); trackEvent('color_copied', { code }); }).catch(() => { showNotification('Copy failed', 'error'); }); } // Update accessibility check function updateAccessibilityCheck() { if (currentPalette.length < 2) return; const container = document.getElementById('contrastChecker'); container.innerHTML = ''; // Check contrast between first few colors for (let i = 0; i < Math.min(currentPalette.length - 1, 3); i++) { for (let j = i + 1; j < Math.min(currentPalette.length, 4); j++) { const color1 = currentPalette[i]; const color2 = currentPalette[j]; const ratio = calculateContrastRatio(color1, color2); const contrastPair = document.createElement('div'); contrastPair.className = 'contrast-pair'; const passes = ratio >= 4.5; const statusClass = passes ? 'status-pass' : 'status-fail'; const statusText = passes ? 'WCAG AA Pass' : 'WCAG AA Fail'; contrastPair.innerHTML = `
Sample Text
${ratio.toFixed(2)}:1
${statusText}
`; container.appendChild(contrastPair); } } } // Calculate contrast ratio function calculateContrastRatio(color1, color2) { const l1 = getRelativeLuminance(color1.r, color1.g, color1.b); const l2 = getRelativeLuminance(color2.r, color2.g, color2.b); const lighter = Math.max(l1, l2); const darker = Math.min(l1, l2); return (lighter + 0.05) / (darker + 0.05); } // Get relative luminance function getRelativeLuminance(r, g, b) { const [rs, gs, bs] = [r, g, b].map(c => { c = c / 255; return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); }); return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs; } // Export palette function exportPalette(format) { if (currentPalette.length === 0) { showNotification('Generate a palette first', 'error'); return; } let content = ''; let filename = `palette-${Date.now()}`; let mimeType = 'text/plain'; switch (format) { case 'css': content = generateCSSVariables(); filename += '.css'; mimeType = 'text/css'; break; case 'scss': content = generateSCSSVariables(); filename += '.scss'; mimeType = 'text/scss'; break; case 'json': content = generateJSONExport(); filename += '.json'; mimeType = 'application/json'; break; case 'png': exportAsPNG(); trackEvent('palette_exported', { format: 'png' }); return; case 'ase': showNotification('ASE export coming soon!', 'warning'); return; case 'sketch': showNotification('Sketch export coming soon!', 'warning'); return; } downloadFile(content, filename, mimeType); trackEvent('palette_exported', { format }); } // Generate CSS variables function generateCSSVariables() { let css = ':root {\n'; currentPalette.forEach((color, index) => { css += ` --color-${index + 1}: ${color.hex};\n`; css += ` --color-${index + 1}-rgb: ${color.r}, ${color.g}, ${color.b};\n`; }); css += '}'; return css; } // Generate SCSS variables function generateSCSSVariables() { let scss = ''; currentPalette.forEach((color, index) => { scss += `$color-${index + 1}: ${color.hex};\n`; scss += `$color-${index + 1}-rgb: ${color.r}, ${color.g}, ${color.b};\n`; }); return scss; } // Generate JSON export function generateJSONExport() { const data = { palette: currentPalette.map((color, index) => ({ name: `color-${index + 1}`, hex: color.hex, rgb: [color.r, color.g, color.b], hsl: color.hsl || ColorTheory.rgbToHsl(color.r, color.g, color.b) })), timestamp: new Date().toISOString() }; return JSON.stringify(data, null, 2); } // Export as PNG function exportAsPNG() { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 800; canvas.height = 200; const swatchWidth = canvas.width / currentPalette.length; currentPalette.forEach((color, index) => { ctx.fillStyle = color.hex; ctx.fillRect(index * swatchWidth, 0, swatchWidth, canvas.height); // Add color code text ctx.fillStyle = getContrastColor(color); ctx.font = '16px Arial'; ctx.textAlign = 'center'; ctx.fillText(color.hex, (index + 0.5) * swatchWidth, canvas.height / 2); }); canvas.toBlob(blob => { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `palette-${Date.now()}.png`; a.click(); URL.revokeObjectURL(url); showNotification('Palette exported as PNG!', 'success'); }); } // Get contrast color for text function getContrastColor(color) { const luminance = getRelativeLuminance(color.r, color.g, color.b); return luminance > 0.5 ? '#000000' : '#ffffff'; } // Download file function downloadFile(content, filename, mimeType) { const blob = new Blob([content], { type: mimeType }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); showNotification(`Exported as ${filename}!`, 'success'); } // ========== UTILITY FUNCTIONS ========== function showNotification(message, type = 'success') { const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => toast.remove(), 3000); } function showOTA() { const otaContainer = document.getElementById('otaContainer'); if (otaContainer && (otaContainer.style.display === 'none' || !otaContainer.style.display)) { otaContainer.style.display = 'block'; } } function trackEvent(eventName, data = {}) { if (typeof gtag !== 'undefined') { gtag('event', eventName, { 'event_category': TOOL_CONFIG.category, 'event_label': TOOL_CONFIG.name, ...data }); } } // ========== AI ASSISTANT FUNCTIONS ========== function openAIModal() { document.getElementById('aiModal').classList.add('show'); } function closeAIModal() { document.getElementById('aiModal').classList.remove('show'); } function selectAI(aiType) { const context = `I'm using a Color Palette Generator tool. I need help with color theory, design harmony, or creative color combinations.`; let url; switch(aiType) { case 'chatgpt': url = `https://chat.openai.com/?q=${encodeURIComponent(context)}`; break; case 'claude': url = `https://claude.ai/chat?q=${encodeURIComponent(context)}`; break; case 'gemini': url = `https://gemini.google.com/?q=${encodeURIComponent(context)}`; break; } window.open(url, '_blank'); closeAIModal(); trackEvent('ai_selection', { ai_type: aiType }); } // ========== EVENT LISTENERS ========== document.addEventListener('DOMContentLoaded', function() { // Tab switching document.querySelectorAll('.generation-tab').forEach(tab => { tab.addEventListener('click', function() { const tabId = this.dataset.tab; document.querySelectorAll('.generation-tab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.generation-content').forEach(c => c.classList.remove('active')); this.classList.add('active'); document.getElementById(`${tabId}-content`).classList.add('active'); }); }); // Color wheel interaction const colorWheel = document.getElementById('colorWheel'); const pickerDot = document.getElementById('pickerDot'); colorWheel.addEventListener('click', function(e) { const rect = this.getBoundingClientRect(); const centerX = rect.width / 2; const centerY = rect.height / 2; const x = e.clientX - rect.left - centerX; const y = e.clientY - rect.top - centerY; const angle = Math.atan2(y, x) * 180 / Math.PI; selectedHue = (angle + 360) % 360; const radius = Math.min(centerX, centerY) - 10; const dotX = centerX + Math.cos(angle * Math.PI / 180) * radius; const dotY = centerY + Math.sin(angle * Math.PI / 180) * radius; pickerDot.style.left = dotX + 'px'; pickerDot.style.top = dotY + 'px'; pickerDot.style.backgroundColor = `hsl(${selectedHue}, 100%, 50%)`; }); // Harmony button selection document.querySelectorAll('.harmony-btn').forEach(btn => { btn.addEventListener('click', function() { document.querySelectorAll('.harmony-btn').forEach(b => b.classList.remove('active')); this.classList.add('active'); }); }); // Image upload const imageUpload = document.getElementById('imageUpload'); const imageInput = document.getElementById('imageInput'); const uploadedImage = document.getElementById('uploadedImage'); const extractBtn = document.getElementById('extractColorsBtn'); imageUpload.addEventListener('click', () => imageInput.click()); imageUpload.addEventListener('dragover', e => { e.preventDefault(); imageUpload.classList.add('drag-over'); }); imageUpload.addEventListener('dragleave', () => { imageUpload.classList.remove('drag-over'); }); imageUpload.addEventListener('drop', e => { e.preventDefault(); imageUpload.classList.remove('drag-over'); const files = e.dataTransfer.files; if (files.length > 0) { handleImageUpload(files[0]); } }); imageInput.addEventListener('change', e => { if (e.target.files.length > 0) { handleImageUpload(e.target.files[0]); } }); function handleImageUpload(file) { if (!file.type.startsWith('image/')) { showNotification('Please upload an image file', 'error'); return; } const reader = new FileReader(); reader.onload = e => { uploadedImage.src = e.target.result; uploadedImage.classList.remove('hidden'); extractBtn.classList.remove('hidden'); imageUpload.style.display = 'none'; }; reader.readAsDataURL(file); } // AI modal events document.getElementById('aiBtn').addEventListener('click', openAIModal); document.getElementById('aiModal').addEventListener('click', e => { if (e.target === e.currentTarget) closeAIModal(); }); document.addEventListener('keydown', e => { if (e.key === 'Escape') closeAIModal(); }); // Initialize updateCurrentYear(); updateToolCount(); trackEvent('page_view', { tool: TOOL_CONFIG.name, category: TOOL_CONFIG.category }); // Generate initial random palette generateRandomPalette(); }); // ========== DYNAMIC TOOL COUNT ========== async function updateToolCount() { try { const response = await fetch('/api/tool-count.php'); const data = await response.json(); document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${data.count}+ free online tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${data.count}+ ${suffix}`; }); } catch (error) { const fallbackCount = 333; document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${fallbackCount}+ free online tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${fallbackCount}+ ${suffix}`; }); } } function updateCurrentYear() { const currentYear = new Date().getFullYear(); document.querySelectorAll('.current-year').forEach(el => { el.textContent = currentYear; }); } // ========== ANALYTICS ========== window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXX');