color-picker/script.js

234 lines
7.5 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');
if (color.image) {
backgroundDiv.style.backgroundImage = `url(${color.image})`;
backgroundDiv.style.backgroundSize = 'cover';
backgroundDiv.style.backgroundPosition = 'center';
} else {
backgroundDiv.style.backgroundColor = color.hex;
}
if (color.metallic && color.chromeType) {
backgroundDiv.classList.add('metallic', `chrome-${color.chromeType}`);
}
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;
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(color);
}
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');
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;
const duration = (Math.random() * 3 + 3).toFixed(2) + 's';
const delay = (Math.random() * 2).toFixed(2) + 's';
swatch.style.animationDuration = duration;
swatch.style.animationDelay = delay;
const backgroundDiv = document.createElement('div');
backgroundDiv.classList.add('color-background', 'chosen');
if (color.image) {
backgroundDiv.style.backgroundImage = `url(${color.image})`;
backgroundDiv.style.backgroundSize = 'cover';
backgroundDiv.style.backgroundPosition = 'center';
} else {
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}`);
}
swatch.appendChild(backgroundDiv);
const svgString = `
<svg class="balloon-string" viewBox="0 0 10 100" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<path d="M5 0 Q3 20 5 40 Q7 60 5 80 Q3 90 5 100" stroke="#333" fill="none" stroke-width="1" />
</svg>
`;
if (animationsEnabled) {
swatch.classList.add('balloon-float');
const duration = (Math.random() * 3 + 3).toFixed(2) + 's';
const delay = (Math.random() * 2).toFixed(2) + 's';
swatch.style.animationDuration = duration;
swatch.style.animationDelay = delay;
} else {
swatch.classList.remove('balloon-float');
swatch.style.animation = 'none';
}
swatch.insertAdjacentHTML('beforeend', svgString);
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);
});
}
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');
}
});
}
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;
}
document.getElementById('clear-palette').addEventListener('click', () => {
selectedPalette = [];
renderSelectedPalette();
updateSwatchHighlights();
});
// Toggle balloon animation globally
document.getElementById('toggle-animation').addEventListener('click', () => {
animationsEnabled = !animationsEnabled;
renderSelectedPalette(); // re-render with or without animation
});
// Shuffle selected palette
document.getElementById('shuffle-palette').addEventListener('click', () => {
selectedPalette = shuffleArray(selectedPalette);
renderSelectedPalette();
updateSwatchHighlights();
});
function shuffleArray(array) {
// FisherYates Shuffle
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
let animationsEnabled = true;
// Handle toggle switch
document.getElementById('toggle-animation').addEventListener('change', (e) => {
animationsEnabled = e.target.checked;
renderSelectedPalette();
});
// Shuffle button
document.getElementById('shuffle-palette').addEventListener('click', () => {
selectedPalette = shuffleArray(selectedPalette);
renderSelectedPalette();
updateSwatchHighlights();
});