gravatar
 · 
December 6, 2025
 · 
4 min read
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>Spinning CD — Animated Background</title>
  <style>
    :root{
      --size: 360px;        /* disc diameter, change as needed */
      --speed: 6s;          /* spin speed */
      --bg: #0b0f14;        /* page background color */
      --gloss-opacity: 0.25;/* glare intensity */
    }
    html,body{height:100%;margin:0}
    body{
      background: radial-gradient(1200px 800px at 10% 10%, rgba(255,255,255,0.02), transparent 5%),
                  radial-gradient(900px 600px at 90% 90%, rgba(255,255,255,0.01), transparent 10%),
                  var(--bg);
      display:flex;align-items:center;justify-content:center;overflow:hidden;
      font-family:system-ui,Segoe UI,Roboto,"Helvetica Neue",Arial;
    }

    /* full-screen subtle animation so the background feels alive */
    .stage{
      position:fixed;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;
    }

    .cd-wrap{
      width:var(--size);height:var(--size);border-radius:50%;position:relative;transform-style:preserve-3d;
      filter:drop-shadow(0 20px 40px rgba(0,0,0,0.55));
    }

    /* The spinning disc (base) */
    .disc{
      position:absolute;inset:0;border-radius:50%;overflow:hidden;transform:translateZ(1px);
      background: radial-gradient(circle at 60% 35%, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.02) 8%, transparent 30%),
                  radial-gradient(circle at 35% 65%, rgba(0,0,0,0.12) 0%, rgba(0,0,0,0.02) 18%, transparent 40%),
                  #0f1720;
    }

    /* rainbow reflection layer created with a conic-gradient and blur, animated to shimmer */
    .rainbow{
      position:absolute;inset:0;border-radius:50%;mix-blend-mode:screen;opacity:0.95;pointer-events:none;
      background: conic-gradient(from 200deg at 50% 50%,
        rgba(255,0,90,0.9), rgba(255,140,0,0.9), rgba(255,240,0,0.9), rgba(0,200,80,0.9), rgba(0,160,255,0.9), rgba(120,0,255,0.9), rgba(255,0,90,0.9));
      filter: blur(10px) saturate(140%);
      transform-origin:50% 50%;
      animation: rainbow-rotate calc(var(--speed) * 0.8) linear infinite;
    }

    @keyframes rainbow-rotate{
      from{transform: rotate(0deg) scale(1.12) translateZ(0)}
      50%{transform: rotate(180deg) scale(1.06) translateZ(0)}
      to{transform: rotate(360deg) scale(1.12) translateZ(0)}
    }

    /* subtle inner ring to mimic the shiny metal area near the hole */
    .inner-ring{
      position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:28%;height:28%;border-radius:50%;
      background: radial-gradient(circle at 40% 40%, rgba(255,255,255,0.85), rgba(255,255,255,0.45) 10%, rgba(255,255,255,0.08) 20%, transparent 40%),
                  rgba(20,20,20,0.9);
      box-shadow: inset 0 2px 12px rgba(255,255,255,0.06), inset 0 -6px 18px rgba(0,0,0,0.6);
      z-index:5;backdrop-filter: blur(2px);
    }

    /* gloss overlay that travels across the disc to simulate reflection */
    .gloss{
      position:absolute;inset:-30% -30% -30% -30%;border-radius:50%;pointer-events:none;
      background: linear-gradient(120deg, transparent 0%, rgba(255,255,255,var(--gloss-opacity)) 48%, rgba(255,255,255,0.0) 60%);
      transform: rotate(-14deg);
      animation: gloss-slide 3.6s ease-in-out infinite;
      mix-blend-mode: overlay;
      z-index:6;
    }
    @keyframes gloss-slide{
      0%{transform: translateX(-30%) rotate(-14deg)}
      50%{transform: translateX(30%) rotate(-14deg)}
      100%{transform: translateX(-30%) rotate(-14deg)}
    }

    /* spin the whole cd-wrap to simulate playback */
    .playing .cd-wrap{animation: spin var(--speed) linear infinite}
    @keyframes spin{from{transform: rotateZ(0)}to{transform: rotateZ(360deg)}}

    /* small animated 'play' indicator - pulses while playing */
    .indicator{
      position:absolute;right:8%;bottom:8%;width:40px;height:40px;border-radius:8px;background:rgba(255,255,255,0.06);
      display:grid;place-items:center;backdrop-filter: blur(4px);z-index:8;pointer-events:auto;
    }
    .indicator .triangle{width:0;height:0;border-left:12px solid rgba(255,255,255,0.9);border-top:8px solid transparent;border-bottom:8px solid transparent;}
    .playing .indicator{animation: pulse 1.8s ease-in-out infinite}
    @keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.08)}100%{transform:scale(1)}}

    /* make the whole thing responsive on tiny viewports */
    @media (max-width:420px){:root{--size:220px}}

    /* optional: a subtle VHS noise texture overlay to make the background feel tactile */
    .grain{position:fixed;inset:0;pointer-events:none;mix-blend-mode:overlay;opacity:0.06;background-image:
      linear-gradient(transparent 50%, rgba(255,255,255,0.02) 51%);background-size:100% 2px;z-index:20}

  </style>
</head>
<body>
  <div class="stage playing" aria-hidden="true">
    <div class="cd-wrap">
      <div class="disc">
        <div class="rainbow"></div>
        <div class="gloss"></div>
        <div class="inner-ring"></div>
      </div>
      <div class="indicator" title="Playing">
        <div class="triangle"></div>
      </div>
    </div>
  </div>
  <div class="grain"></div>

  <script>
    // Small script to toggle the "playing" state when clicked (useful for demos)
    document.querySelector('.stage').addEventListener('click', e=>{
      const st = document.querySelector('.stage');
      st.classList.toggle('playing');
    });

    // Expose CSS custom properties for convenience so you can control speed/size from JS
    window.setDiscSize = sizePx => document.documentElement.style.setProperty('--size', sizePx+'px');
    window.setSpinSpeed = seconds => document.documentElement.style.setProperty('--speed', seconds+'s');
  </script>

  <!--
    Text prompts for image models (DALL·E / Stable Diffusion / Midjourney):

    Short single-line prompt:
    "Photorealistic close-up of a blank compact disc spinning, showing vivid multi-color iridescent reflections and a soft glossy glare, isolated on dark background, cinematic lighting, ultra-detailed, 4k"

    Enhanced prompt with style parameters:
    "Blank compact disc spinning in place, strong multi-color interference/reflections across the surface (rainbow concentric bands), subtle motion blur, soft glossy specular highlights and a linear sheen, high contrast cinematic lighting, shallow depth of field, studio backdrop, photorealistic, ultra-detailed, 8k --ar 16:9 --v 5 --q 2"

    Tips:
    - Use 'conic gradient' or 'interference' keywords for generators that support technical words.
    - Ask for 'transparent background' if you need the disc as an overlay for web use.
  -->

</body>
</html>

View