<section class="demo" id="stage"></section>.demo {
min-height: 100%;
height: 100%;
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(6, 1fr);
gap: 8px;
padding: 28px;
background: #08080a;
}
.demo__cell {
min-height: 0;
border-radius: 14px;
background: #141418;
border: 1px solid rgba(255, 255, 255, 0.05);
transform-origin: 50% 50%;
will-change: transform, background;
}const stage = document.querySelector("#stage");
const COLS = 8;
const ROWS = 6;
const cells = [];
for (let i = 0; i < COLS * ROWS; i += 1) {
const cell = document.createElement("div");
cell.className = "demo__cell";
stage.appendChild(cell);
cells.push(cell);
}
function near(clientX, clientY) {
cells.forEach(function (cell) {
const rect = cell.getBoundingClientRect();
const dx = clientX - (rect.left + rect.width / 2);
const dy = clientY - (rect.top + rect.height / 2);
const dist = Math.hypot(dx, dy);
const t = Math.max(0, 1 - dist / 150);
gsap.to(cell, {
scale: 1 + t * 0.55,
backgroundColor: t > 0.15 ? "#2a2a32" : "#141418",
duration: 0.35,
ease: "power3.out",
overwrite: "auto",
});
});
}
stage.addEventListener("pointermove", function (event) {
near(event.clientX, event.clientY);
});
near(window.innerWidth * 0.5, window.innerHeight * 0.45);