let selectedPalette = []; fetch('colors.json') .then(response => response.json()) .then(data => { const colorFamiliesContainer = document.getElementById('color-families'); data.forEach(family => { const familyDiv = document.createElement('div'); familyDiv.classList.add('color-family'); familyDiv.innerHTML = `

${family.family}

`; const swatchContainer = document.createElement('div'); swatchContainer.classList.add('swatch-container'); family.colors.forEach(color => { const swatchWrapper = document.createElement('div'); swatchWrapper.classList.add('swatch-wrapper'); const swatch = document.createElement('div'); swatch.classList.add('color-swatch'); swatch.dataset.color = color.hex; const backgroundDiv = document.createElement('div'); backgroundDiv.classList.add('color-background'); backgroundDiv.style.backgroundColor = color.hex; if (color.metallic && color.chromeType) { backgroundDiv.classList.add('metallic', `chrome-${color.chromeType}`); } const metallicNames = ["Gold", "Silver", "Rose Gold", "Hot Magenta"]; if (metallicNames.includes(color.name)) { backgroundDiv.classList.add('metallic'); } if (isLightColor(color.hex)) { backgroundDiv.style.border = '1px solid rgba(0, 0, 0, 0.2)'; } swatch.appendChild(backgroundDiv); const shineImg = document.createElement('img'); shineImg.classList.add('color-shine'); shineImg.src = "shine.svg"; shineImg.alt = ""; swatch.appendChild(shineImg); const colorName = document.createElement('span'); colorName.classList.add('color-name'); colorName.textContent = color.name; colorName.title = color.name; swatch.addEventListener('click', () => { const isSelected = selectedPalette.some(c => c.hex === color.hex); if (isSelected) { selectedPalette = selectedPalette.filter(c => c.hex !== color.hex); } else { selectedPalette.push({ name: color.name, hex: color.hex, metallic: color.metallic, chromeType: color.chromeType }); } backgroundDiv.classList.add('pop'); backgroundDiv.addEventListener('animationend', () => { backgroundDiv.classList.remove('pop'); }, { once: true }); renderSelectedPalette(); updateSwatchHighlights(); }); swatchWrapper.appendChild(swatch); swatchWrapper.appendChild(colorName); swatchContainer.appendChild(swatchWrapper); }); familyDiv.appendChild(swatchContainer); colorFamiliesContainer.appendChild(familyDiv); }); renderSelectedPalette(); updateSwatchHighlights(); }) .catch(error => console.error('Error loading colors:', error)); function renderSelectedPalette() { const paletteColorsContainer = document.getElementById('palette-colors'); const previousHeight = paletteColorsContainer.offsetHeight; paletteColorsContainer.innerHTML = ''; selectedPalette.forEach(color => { const swatchWrapper = document.createElement('div'); swatchWrapper.classList.add('swatch-wrapper'); const swatch = document.createElement('div'); swatch.classList.add('color-swatch', 'balloon-float'); swatch.dataset.color = color.hex; // Randomize animation const duration = (Math.random() * 3 + 3).toFixed(2) + 's'; // 3s–6s const delay = (Math.random() * 2).toFixed(2) + 's'; swatch.style.animationDuration = duration; swatch.style.animationDelay = delay; // Optional random float rotation direction const rotate = Math.random() > 0.5 ? 'rotate(-3deg)' : 'rotate(3deg)'; swatch.style.transform = rotate; const backgroundDiv = document.createElement('div'); backgroundDiv.classList.add('color-background'); backgroundDiv.style.backgroundColor = color.hex; if (isLightColor(color.hex)) { backgroundDiv.style.border = '1px solid rgba(0, 0, 0, 0.2)'; } if (color.metallic && color.chromeType) { backgroundDiv.classList.add('metallic', `chrome-${color.chromeType}`); } backgroundDiv.classList.add('chosen'); swatch.appendChild(backgroundDiv); const shineImg = document.createElement('img'); shineImg.classList.add('color-shine'); shineImg.src = "shine.svg"; shineImg.alt = ""; swatch.appendChild(shineImg); swatch.addEventListener('click', () => { selectedPalette = selectedPalette.filter(c => c.hex !== color.hex); renderSelectedPalette(); updateSwatchHighlights(); }); const colorName = document.createElement('span'); colorName.classList.add('color-name', 'highlighted-name'); colorName.textContent = color.name; swatchWrapper.appendChild(swatch); swatchWrapper.appendChild(colorName); paletteColorsContainer.appendChild(swatchWrapper); }); const newHeight = paletteColorsContainer.scrollHeight; paletteColorsContainer.style.maxHeight = previousHeight + 'px'; void paletteColorsContainer.offsetWidth; paletteColorsContainer.style.maxHeight = newHeight + 'px'; } function updateSwatchHighlights() { const allSwatches = document.querySelectorAll('#color-families .color-swatch'); allSwatches.forEach(swatch => { const color = swatch.dataset.color; const background = swatch.querySelector('.color-background'); const nameEl = swatch.parentElement.querySelector('.color-name'); const isSelected = selectedPalette.some(c => c.hex === color); if (isSelected) { background.classList.add('chosen'); nameEl.classList.add('highlighted-name'); } else { background.classList.remove('chosen'); nameEl.classList.remove('highlighted-name'); } }); } document.getElementById('clear-palette').addEventListener('click', () => { selectedPalette = []; renderSelectedPalette(); updateSwatchHighlights(); }); window.addEventListener('scroll', () => { const palette = document.getElementById('selected-palette'); if (window.scrollY > 0) { palette.classList.add('stuck'); } else { palette.classList.remove('stuck'); } }); function isLightColor(hex) { const rgb = hex.replace('#', '').match(/.{1,2}/g).map(x => parseInt(x, 16)); const brightness = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; return brightness > 220; }