added chrome and balloon strings. updated colors
72
colors.json
@ -114,14 +114,72 @@
|
||||
{
|
||||
"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": "#2d576f", "metallic": true, "chromeType": "blue" },
|
||||
{ "name": "Chrome Purple", "hex": "#DFFF00", "metallic": true, "chromeType": "purple" },
|
||||
{ "name": "Chrome Green", "hex": "#457066", "metallic": true, "chromeType": "green" }
|
||||
{
|
||||
"name": "Chrome Gold",
|
||||
"hex": "#a18b67",
|
||||
"metallic": true,
|
||||
"chromeType": "gold",
|
||||
"image": "images/chrome-gold.png"
|
||||
},
|
||||
{
|
||||
"name": "Chrome Champagne",
|
||||
"hex": "#FF1DCE",
|
||||
"metallic": true,
|
||||
"chromeType": "champagne",
|
||||
"image": "images/chrome-champagne.png"
|
||||
},
|
||||
{
|
||||
"name": "Chrome Silver",
|
||||
"hex": "#a8a9a4",
|
||||
"metallic": true,
|
||||
"chromeType": "silver",
|
||||
"image": "images/chrome-silver.png"
|
||||
},
|
||||
{
|
||||
"name": "Chrome Rose Gold",
|
||||
"hex": "#FFBF00",
|
||||
"metallic": true,
|
||||
"chromeType": "rosegold",
|
||||
"image": "images/chrome-rosegold.png"
|
||||
},
|
||||
{
|
||||
"name": "Chrome Pink",
|
||||
"hex": "#FFBF00",
|
||||
"metallic": true,
|
||||
"chromeType": "rosegold",
|
||||
"image": "images/chrome-pink.png"
|
||||
},
|
||||
{
|
||||
"name": "Chrome Truffel",
|
||||
"hex": "#FF1DCE",
|
||||
"metallic": true,
|
||||
"chromeType": "champagne",
|
||||
"image": "images/chrome-truffel.png"
|
||||
},
|
||||
{
|
||||
"name": "Chrome Blue",
|
||||
"hex": "#2d576f",
|
||||
"metallic": true,
|
||||
"chromeType": "blue",
|
||||
"image": "images/chrome-blue.png"
|
||||
},
|
||||
{
|
||||
"name": "Chrome Purple",
|
||||
"hex": "#DFFF00",
|
||||
"metallic": true,
|
||||
"chromeType": "purple",
|
||||
"image": "images/chrome-purple.png"
|
||||
},
|
||||
{
|
||||
"name": "Chrome Green",
|
||||
"hex": "#457066",
|
||||
"metallic": true,
|
||||
"chromeType": "green",
|
||||
"image": "images/chrome-green.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
BIN
images/chrome-blue.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
images/chrome-champagne.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
images/chrome-gold.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
images/chrome-green.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
images/chrome-pink.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
images/chrome-purple.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
images/chrome-rosegold.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
images/chrome-silver.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
images/chrome-truffel.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
@ -15,6 +15,14 @@
|
||||
</header>
|
||||
<div id="selected-palette">
|
||||
<h2>Your Palette</h2>
|
||||
<div id="palette-controls">
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="toggle-animation" checked>
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<button id="shuffle-palette" title="Shuffle Palette">🔀</button>
|
||||
</div>
|
||||
|
||||
<div id="palette-colors"></div>
|
||||
<button id="clear-palette">Clear Palette</button>
|
||||
</div>
|
||||
|
||||
120
script.js
@ -23,23 +23,26 @@ fetch('colors.json')
|
||||
|
||||
const backgroundDiv = document.createElement('div');
|
||||
backgroundDiv.classList.add('color-background');
|
||||
backgroundDiv.style.backgroundColor = color.hex;
|
||||
|
||||
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}`);
|
||||
}
|
||||
|
||||
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";
|
||||
@ -49,14 +52,13 @@ fetch('colors.json')
|
||||
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 });
|
||||
selectedPalette.push(color);
|
||||
}
|
||||
|
||||
backgroundDiv.classList.add('pop');
|
||||
@ -82,10 +84,8 @@ fetch('colors.json')
|
||||
})
|
||||
.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 => {
|
||||
@ -95,21 +95,22 @@ function renderSelectedPalette() {
|
||||
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 duration = (Math.random() * 3 + 3).toFixed(2) + 's';
|
||||
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;
|
||||
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)';
|
||||
@ -119,9 +120,25 @@ function renderSelectedPalette() {
|
||||
backgroundDiv.classList.add('metallic', `chrome-${color.chromeType}`);
|
||||
}
|
||||
|
||||
backgroundDiv.classList.add('chosen');
|
||||
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";
|
||||
@ -142,14 +159,8 @@ function renderSelectedPalette() {
|
||||
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');
|
||||
|
||||
@ -169,23 +180,54 @@ function updateSwatchHighlights() {
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
const palette = document.getElementById('selected-palette');
|
||||
if (window.scrollY > 0) {
|
||||
palette.classList.add('stuck');
|
||||
} else {
|
||||
palette.classList.remove('stuck');
|
||||
}
|
||||
|
||||
|
||||
// Toggle balloon animation globally
|
||||
document.getElementById('toggle-animation').addEventListener('click', () => {
|
||||
animationsEnabled = !animationsEnabled;
|
||||
renderSelectedPalette(); // re-render with or without animation
|
||||
});
|
||||
|
||||
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;
|
||||
// Shuffle selected palette
|
||||
document.getElementById('shuffle-palette').addEventListener('click', () => {
|
||||
selectedPalette = shuffleArray(selectedPalette);
|
||||
renderSelectedPalette();
|
||||
updateSwatchHighlights();
|
||||
});
|
||||
|
||||
function shuffleArray(array) {
|
||||
// Fisher–Yates 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();
|
||||
});
|
||||
|
||||
113
style.css
@ -262,6 +262,8 @@ background-image: url("https://www.transparenttextures.com/patterns/asfalt-light
|
||||
/* overflow: hidden; /*Hide overflow text if necessary */
|
||||
text-overflow: ellipsis; /* Add ... when text is too long */
|
||||
max-width: 90%;
|
||||
background-color: #e8e8e8;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#palette-colors .color-swatch {
|
||||
@ -332,13 +334,13 @@ background-image: url("https://www.transparenttextures.com/patterns/asfalt-light
|
||||
.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);
|
||||
/* 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 {
|
||||
.metallic1::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 15%;
|
||||
@ -353,7 +355,7 @@ background-image: url("https://www.transparenttextures.com/patterns/asfalt-light
|
||||
|
||||
/* Specific chrome variants */
|
||||
.chrome-gold {
|
||||
background: linear-gradient(145deg, #fefcea, #f1da36, #b29600, #fefcea);
|
||||
background: linear-gradient(145deg, #fefcea, #b69978, #a18b67, #806748);
|
||||
}
|
||||
|
||||
.chrome-silver {
|
||||
@ -382,17 +384,106 @@ background-image: url("https://www.transparenttextures.com/patterns/asfalt-light
|
||||
|
||||
|
||||
@keyframes balloonFloat {
|
||||
0%, 100% { transform: translateY(0) rotate(-3deg); }
|
||||
50% { transform: translateY(-20px) rotate(3deg); }
|
||||
0%, 100% { transform: translateY(0) rotate(-4deg); }
|
||||
50% { transform: translateY(-25px) rotate(4deg); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.balloon-float {
|
||||
animation-name: balloonFloat;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-timing-function: 4s ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
transform-origin: bottom center;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.color-background {
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.balloon-string {
|
||||
width: 6px;
|
||||
height: 45px;
|
||||
position: absolute;
|
||||
bottom: -45px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
animation: stringWiggle 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes stringWiggle {
|
||||
0%, 100% {
|
||||
transform: translateX(-50%) rotate(0deg);
|
||||
}
|
||||
25% {
|
||||
transform: translateX(-50%) rotate(1.5deg);
|
||||
}
|
||||
50% {
|
||||
transform: translateX(-50%) rotate(-1.5deg);
|
||||
}
|
||||
75% {
|
||||
transform: translateX(-50%) rotate(1deg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#palette-controls {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
/* Toggle Switch Styling */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
}
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0; left: 0;
|
||||
right: 0; bottom: 0;
|
||||
background-color: #ccc;
|
||||
transition: 0.4s;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
background-color: white;
|
||||
transition: 0.4s;
|
||||
border-radius: 50%;
|
||||
}
|
||||
input:checked + .slider {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
/* Shuffle Button */
|
||||
#shuffle-palette {
|
||||
font-size: 16px;
|
||||
padding: 4px 8px;
|
||||
border: none;
|
||||
background: #f0f0f0;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||