added background and animation
This commit is contained in:
parent
ae77418596
commit
637242021f
27
colors.json
27
colors.json
@ -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" }
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
12
index.html
12
index.html
@ -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
92
list.txt
Normal 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
191
script.js
@ -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'; // 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();
|
||||
});
|
||||
|
||||
// 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
129
style.css
@ -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;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user