<!
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Smooth Chakra Color Motion Simulation - Grid</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
}
.grid {
display: grid;
grid-template-columns: repeat(16, 25px);
grid-gap: 5px;
}
.square {
width: 25px;
height: 25px;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<h1>Smooth Chakra Color Motion Simulation - Grid</h1>
<div class="grid" id="grid"></div>
<script>
// Define the chakra colors in Lab color space
const chakraColors = [
{ L: 53, a: 80, b: 67 }, // Red
{ L: 66, a: 49, b: 78 }, // Orange
{ L: 97, a: -11, b: 92 }, // Yellow
{ L: 87, a: -31, b: 36 }, // Green
{ L: 32, a: 79, b: -108 }, // Blue
{ L: 24, a: 52, b: -60 }, // Indigo
{ L: 29, a: 66, b: -43 } // Violet
];
const gridContainer = [Link]('grid');
const numSquares = 16;
const transitionTime = 5000; // Time in milliseconds for each color
transition
const transitionSteps = 100; // Number of steps for smooth transition
// Create an array to store animation intervals
const animationIntervals = [];
// Initialize the grid with squares
for (let i = 0; i < numSquares * numSquares; i++) {
const square = [Link]('div');
[Link] = 'square';
[Link](square);
// Start animation for each square
animateSquare(square);
}
function animateSquare(square) {
let startTime = null;
let currentColor = getRandomChakraColor();
let targetColor = { L: 100, a: 0, b: 0 }; // White in Lab color space
function animate(timestamp) {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const progress = elapsed / transitionTime;
// Interpolate colors
const interpolatedColor = interpolateColors(currentColor,
targetColor, progress);
drawSquare(square, interpolatedColor);
if (elapsed >= transitionTime) {
// Update current color and generate new target color
currentColor = targetColor;
targetColor = getRandomChakraColor();
startTime = timestamp; // Reset start time for next animation
cycle
}
// Continue animation
[Link](requestAnimationFrame(animate));
}
// Start animation loop
requestAnimationFrame(animate);
}
function drawSquare(square, colorLab) {
// Convert Lab to RGB
const { r, g, b } = labToRgb(colorLab.L, colorLab.a, colorLab.b);
// Apply color to square
[Link] = `rgb(${r}, ${g}, ${b})`;
}
function interpolateColors(startColor, endColor, progress) {
const startLab = [startColor.L, startColor.a, startColor.b];
const endLab = [endColor.L, endColor.a, endColor.b];
const interpolatedLab = [Link]((start, i) => {
return start + (endLab[i] - start) * progress;
});
return {
L: interpolatedLab[0],
a: interpolatedLab[1],
b: interpolatedLab[2]
};
}
function labToRgb(L, a, b) {
// Convert Lab to XYZ
const delta = 6 / 29;
const fy = (L + 16) / 116;
const fx = fy + (a / 500);
const fz = fy - (b / 200);
const x = fx > delta ? [Link](fx, 3) : (fx - 16 / 116) * 3 *
[Link](delta, 2);
const y = L > 8 ? [Link]((L + 16) / 116, 3) : L / 903.3;
const z = fz > delta ? [Link](fz, 3) : (fz - 16 / 116) * 3 *
[Link](delta, 2);
// Convert XYZ to RGB
let r = x * 3.2406 + y * -1.5372 + z * -0.4986;
let g = x * -0.9689 + y * 1.8758 + z * 0.0415;
let b = x * 0.0557 + y * -0.2040 + z * 1.0570;
// Apply gamma correction
r = r > 0.0031308 ? 1.055 * [Link](r, 1 / 2.4) - 0.055 : 12.92 * r;
g = g > 0.0031308 ? 1.055 * [Link](g, 1 / 2.4) - 0.055 : 12.92 * g;
b = b > 0.0031308 ? 1.055 * [Link](b, 1 / 2.4) - 0.055 : 12.92 * b;
// Clamp values to [0, 255]
r = [Link](0, [Link](255, r * 255));
g = [Link](0, [Link](255, g * 255));
b = [Link](0, [Link](255, b * 255));
return { r: [Link](r), g: [Link](g), b: [Link](b) };
}
function getRandomChakraColor() {
const randomIndex = [Link]([Link]() * [Link]);
return chakraColors[randomIndex];
}
</script>
</body>
</html>