JIT
Grid - Untitled
Write a script for the classic "DVD Logo" bounce animation. A rectangle must move diagonally, bounce off the viewport edges, and change its color to a random value upon every collision.
<html> <head> <meta charset="UTF-8"> <title>DVD Logo Bounce</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } html, body { width: 100%; height: 100%; overflow: hidden; background: radial-gradient(circle at top left, #222 0%, #000 60%); font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color: #fff; } .viewport { position: relative; width: 100vw; height: 100vh; } .dvd-logo { position: absolute; width: min(18vw, 220px); height: min(10vw, 120px); min-width: 120px; min-height: 60px; max-width: 260px; max-height: 130px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: clamp(1.4rem, 2.2vw, 2.3rem); letter-spacing: 0.22em; text-transform: uppercase; color: #ffffff; box-shadow: 0 0 30px rgba(255,255,255,0.4), 0 0 80px rgba(0,0,0,0.9); transform: translate3d(0, 0, 0); will-change: transform, background-color; } .dvd-logo span { transform: translateY(-0.06em); }
.hint {
  position: absolute;
  bottom: 2vh;
  left: 50%;
  transform: translateX(-50%);
  font-size: clamp(0.7rem, 1.1vw, 0.9rem);
  opacity: 0.55;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}
</style> </head> <body> <div class="viewport"> <div class="dvd-logo" id="dvdLogo"> <span>DVD</span> </div> <div class="hint">Bouncing DVD logo – resize the window to see it adapt</div> </div> <script> (function () { const logo = document.getElementById('dvdLogo'); const viewport = document.querySelector('.viewport'); let vw = viewport.clientWidth; let vh = viewport.clientHeight; let rectWidth = logo.offsetWidth; let rectHeight = logo.offsetHeight; let x = Math.random() * (vw - rectWidth); let y = Math.random() * (vh - rectHeight); // px per second (scaled a bit with viewport) const baseSpeed = 220; const speedFactor = Math.min(Math.max(vw, vh) / 800, 2.0); const speed = baseSpeed * speedFactor; // Start with diagonal direction let dirX = Math.random() > 0.5 ? 1 : -1; let dirY = Math.random() > 0.5 ? 1 : -1; let lastTime = null; function randomColor() { const h = Math.floor(Math.random() * 360); const s = 70 + Math.random() * 25; // 70–95% const l = 45 + Math.random() * 15; // 45–60% return `hsl(${h} ${s}% ${l}%)`; } function setColor() { const color = randomColor(); logo.style.backgroundColor = color; logo.style.boxShadow = `0 0 30px ${color}, 0 0 90px rgba(0,0,0,0.9)`; } function updateSize() { vw = viewport.clientWidth; vh = viewport.clientHeight; rectWidth = logo.offsetWidth; rectHeight = logo.offsetHeight; // Keep logo inside bounds after resize if (x + rectWidth > vw) x = vw - rectWidth; if (y + rectHeight > vh) y = vh - rectHeight; if (x < 0) x = 0; if (y < 0) y = 0; } function step(timestamp) { if (lastTime == null) { lastTime = timestamp; requestAnimationFrame(step); return; } const delta = (timestamp - lastTime) / 1000; // seconds since last frame lastTime = timestamp; x += dirX * speed * delta; y += dirY * speed * delta; let bounced = false; // Right edge if (x + rectWidth >= vw) { x = vw - rectWidth; dirX *= -1; bounced = true; } // Left edge else if (x <= 0) { x = 0; dirX *= -1; bounced = true; } // Bottom edge if (y + rectHeight >= vh) { y = vh - rectHeight; dirY *= -1; bounced = true; } // Top edge else if (y <= 0) { y = 0; dirY *= -1; bounced = true; } if (bounced) { setColor(); } logo.style.transform = `translate3d(${x}px, ${y}px, 0)`; requestAnimationFrame(step); } window.addEventListener('resize', updateSize); // Initialize setColor(); updateSize(); requestAnimationFrame(step); })(); </script> </body> </html>*
Updated files
v1