added background and animation

This commit is contained in:
chris 2025-06-29 08:23:22 -04:00
parent ae77418596
commit 637242021f
5 changed files with 350 additions and 101 deletions

View File

@ -2,8 +2,8 @@
{
"family": "Reds",
"colors": [
{ "name": "Red", "hex": "#bd002b" },
{ "name": "Fire Red", "hex": "#FF4500" },
{ "name": "Red", "hex": "#ef2a2f" },
{ "name": "Maroon", "hex": "#80011f" },
{ "name": "Cherry", "hex": "#DE3163" },
{ "name": "Tomato", "hex": "#FF6347" },
{ "name": "Maroon", "hex": "#800000" }
@ -13,8 +13,8 @@
"family": "Oranges",
"colors": [
{ "name": "Orange", "hex": "#ff7600" },
{ "name": "Tangerine", "hex": "#F28500" },
{ "name": "Pumpkin", "hex": "#FF7518" },
{ "name": "Burnt Orange", "hex": "#9d4223" },
{ "name": "", "hex": "#FF7518" },
{ "name": "Amber", "hex": "#FFBF00" },
{ "name": "Burnt Orange", "hex": "#CC5500" }
]
@ -23,7 +23,7 @@
"family": "Yellows",
"colors": [
{ "name": "Yellow", "hex": "#f2e44b" },
{ "name": "Gold", "hex": "#FFD700" },
{ "name": "Gold", "hex": "#C39953" },
{ "name": "Mustard", "hex": "#FFDB58" },
{ "name": "Dandelion", "hex": "#FED85D" },
{ "name": "Sunflower", "hex": "#FFC512" }
@ -74,7 +74,7 @@
"family": "Browns",
"colors": [
{ "name": "Chocolate", "hex": "#D2691E" },
{ "name": "Sienna", "hex": "#A0522D" },
{ "name": "Terra Cotta", "hex": "#A0522D" },
{ "name": "Tan", "hex": "#D2B48C" },
{ "name": "Beige", "hex": "#F5F5DC" },
{ "name": "Coffee", "hex": "#6F4E37" }
@ -87,7 +87,7 @@
{ "name": "Black", "hex": "#000000" },
{ "name": "Gray", "hex": "#808080" },
{ "name": "Charcoal", "hex": "#36454F" },
{ "name": "Silver", "hex": "#C0C0C0" }
{ "name": "Silver", "hex": "#A6A6A6" }
]
},
{
@ -119,5 +119,18 @@
{ "name": "Hot Magenta", "hex": "#FF1DCE" },
{ "name": "Lime Yellow", "hex": "#DFFF00" }
]
},
{
"family": "Chrome Colors",
"colors": [
{ "name": "Chrome Gold", "hex": "#39FF14", "metallic": true, "chromeType": "gold" },
{ "name": "Chrome Silver", "hex": "#a8a9a4", "metallic": true, "chromeType": "silver" },
{ "name": "Chrome Rose Gold", "hex": "#FFBF00", "metallic": true, "chromeType": "rosegold" },
{ "name": "Chrome Champagne", "hex": "#FF1DCE", "metallic": true, "chromeType": "champagne" },
{ "name": "Chrome Blue", "hex": "#DFFF00", "metallic": true, "chromeType": "blue" },
{ "name": "Chrome Purple", "hex": "#DFFF00", "metallic": true, "chromeType": "purple" },
{ "name": "Chrome Green", "hex": "#457066", "metallic": true, "chromeType": "green" }
]
}
]

View File

@ -8,14 +8,22 @@
<link href="https://fonts.googleapis.com/css2?family=Autour+One&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body> <div id="selected-palette">
<body>
<header id="main-header">
<h1>🎈 Color Balloon Picker</h1>
<p>Select and float your favorite shades</p>
</header>
<div id="selected-palette">
<h2>Your Palette</h2>
<div id="palette-colors"></div>
<button id="clear-palette">Clear Palette</button>
</div>
<div id="color-families"></div>
<footer>
<p>Made with 🎨 and 🎈 | Chris © 2025</p>
</footer>
<script src="script.js"></script>
</body>
</html>

92
list.txt Normal file
View File

@ -0,0 +1,92 @@
Browns & Neutrals:
Retro White
Stone
Coffee
Willow
Latte
Grey Pearl White
Orange & Red Tones:
Burnt Orange
Terra Cotta
Blush Pearl Red
Coral
Yellow & Gold Tones:
Pastel Yellow
Goldenrod
Chrome Champagne
Classic Gold
Chrome Gold
2. Cool & Calming Tones
Blues:
Royal Blue
Medium Blue
Sky Blue
Dark Blue
Navy
White Caribbean Blue
Pearl Midnight Blue
Pearl Sapphire
Nautical Chrome Silver
Greens:
Pastel Green
Grass Green
Lime Green
Seafoam
Pearl Green
Forest Green
Purples & Violets:
Orchid
Lilac
Pearl Periwinkle
Pearl Violet
Orange Violet
Yellow Lavender
3. Pastels & Soft Tones
Pink & Rose Tones:
Cameo
Rosewood
Cayon Rose
Rose Pink
Pearl Pink
Sky Blue Pearl Pink
Soft Greens & Blues:
Sea Glass
Empowermint
Aloha (arguably warm/cool depending on specific shade)
Light & Airy:
Light Pink
4. Vibrant & Bold Tones
Pinks & Purples:
Fuchsia
Pearl Fuchsia
Wildberry
Teals & Tropicals:
Black Tropical Teal
Unique:
Neon Agate
5. Metallic & Special Finishes
Chrome:
Chrome Blue
Chrome Purple
Chrome Copper
Chrome Truffle
Chrome Pink
Chrome Green
Chrome Space Grey
Nautical Chrome Silver
Animal Print Chrome Pink
Pearl:
Pearl Blue
Pearl Lilac
Pearl White
Classic:
Classic Silver
Smoke:
Chrome Red Smoke
Filigree
Clear Filigree

191
script.js
View File

@ -25,7 +25,15 @@ fetch('colors.json')
backgroundDiv.classList.add('color-background');
backgroundDiv.style.backgroundColor = color.hex;
// Add light border if needed
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)';
}
@ -41,19 +49,20 @@ fetch('colors.json')
const colorName = document.createElement('span');
colorName.classList.add('color-name');
colorName.textContent = color.name;
colorName.title = color.name; // Tooltip on hover
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 });
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 });
backgroundDiv.addEventListener('animationend', () => {
backgroundDiv.classList.remove('pop');
}, { once: true });
renderSelectedPalette();
updateSwatchHighlights();
@ -73,86 +82,93 @@ backgroundDiv.addEventListener('animationend', () => {
})
.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);
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();
});
// 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';
}
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');
}
});
}
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();
@ -168,15 +184,8 @@ window.addEventListener('scroll', () => {
}
});
// 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
return brightness > 220;
}
const checkmark = document.createElement('div');
checkmark.classList.add('checkmark-overlay');
checkmark.innerHTML = '✓'; // or use an SVG/icon
swatch.appendChild(checkmark);

129
style.css
View File

@ -4,8 +4,29 @@ body {
box-sizing: border-box;
/* font-family: sans-serif; */
font-family: "Autour One", serif;
background-color: #e8e8e8;
background-image: url("https://www.transparenttextures.com/patterns/asfalt-dark.png");
/* This is mostly intended for prototyping; please download the pattern and re-host for production environments. Thank you! */
}
#main-header {
text-align: center;
padding: 20px 10px;
background: #ffffffdd;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
border-radius: 12px;
margin-bottom: 20px;
}
#main-header h1 {
font-size: 2rem;
margin-bottom: 5px;
}
#main-header p {
font-size: 1rem;
color: #666;
}
#selected-palette {
position: sticky;
top: 0;
@ -22,6 +43,9 @@ body {
text-align: center;
gap: 15px;
background-color: #e8e8e8;
background-image: url("https://www.transparenttextures.com/patterns/asfalt-light.png");
/* This is mostly intended for prototyping; please download the pattern and re-host for production environments. Thank you! */
}
/* Strong shadow when stuck */
@ -62,6 +86,37 @@ body {
gap: 15px;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
footer {
text-align: center;
font-size: 0.9rem;
color: #777;
padding: 20px;
}
@media (max-width: 480px) {
.color-name {
font-size: 0.7rem;
}
.swatch-wrapper {
padding: 6px;
}
#main-header h1 {
font-size: 1.5rem;
}
}
.color-family {
display: flex;
flex-direction: column;
@ -69,6 +124,8 @@ body {
gap: 10px;
padding-bottom: 20px;
border-bottom: 1px solid #ccc;
animation: fadeInUp 0.5s ease;
}
.swatch-container {
display: flex;
@ -95,6 +152,7 @@ body {
padding: 5px;
max-width: min-content;
/* overflow-wrap: break-word; */
}
@ -266,4 +324,73 @@ body {
.color-background.chosen {
/* transform: scale(1.1); */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.25);
}
/* Shared metallic style */
.metallic {
position: relative;
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: inset 1px 1px 4px rgba(255, 255, 255, 0.6),
0 2px 4px rgba(0, 0, 0, 0.3);
overflow: hidden;
}
/* Highlight overlay */
.metallic::after {
content: '';
position: absolute;
top: 15%;
left: 15%;
width: 70%;
height: 70%;
background: radial-gradient(circle at top left, rgba(255,255,255,0.3), transparent 70%);
transform: rotate(-20deg);
pointer-events: none;
border-radius: 50%;
}
/* Specific chrome variants */
.chrome-gold {
background: linear-gradient(145deg, #fefcea, #f1da36, #b29600, #fefcea);
}
.chrome-silver {
background: linear-gradient(145deg, #e0e0e0, #a9a9a9, #808080, #e0e0e0);
}
.chrome-rosegold {
background: linear-gradient(145deg, #fbe3dc, #e6b7a9, #d19387, #fbe3dc);
}
.chrome-champagne {
background: linear-gradient(145deg, #fff2cc, #f2e6b6, #d9c08e, #fff2cc);
}
.chrome-blue {
background: linear-gradient(145deg, #d0f0ff, #a1d8ff, #7ab9ff, #d0f0ff);
}
.chrome-purple {
background: linear-gradient(145deg, #e0ccff, #b08be1, #915bc4, #e0ccff);
}
.chrome-green {
background: linear-gradient(145deg, #e2ffe2, #457066, #5c877d, #e2ffe2);
}
@keyframes balloonFloat {
0%, 100% { transform: translateY(0) rotate(-3deg); }
50% { transform: translateY(-20px) rotate(3deg); }
}
.balloon-float {
animation-name: balloonFloat;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
transform-origin: bottom center;
position: relative;
}