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; // Add light border if needed 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; // Tooltip on hover 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 }); } 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'); // Capture the current height before DOM changes const previousHeight = paletteColorsContainer.offsetHeight; // Clear and repopulate 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'); swatch.dataset.color = color.hex; 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)'; } 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); }); // Animate to new height const newHeight = paletteColorsContainer.scrollHeight; paletteColorsContainer.style.maxHeight = previousHeight + 'px'; // Trigger reflow to ensure animation 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'); } }); // Helper: determine if a color is visually light 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; // Higher threshold = fewer borders } const checkmark = document.createElement('div'); checkmark.classList.add('checkmark-overlay'); checkmark.innerHTML = '✓'; // or use an SVG/icon swatch.appendChild(checkmark);