color-picker/script.js

192 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 = `<h3>${family.family}</h3>`;
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'; // 3s6s
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;
}