Interactive gradient backgound

by Csaba Hellinger

HTML

<svg id="svg" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <radialGradient id="red" cx="50%" cy="50%" r="50%">
      <stop offset="0%" stop-color="#f00" stop-opacity="1" />
      <stop offset="100%" stop-color="#f00" stop-opacity="0" />
    </radialGradient>
    <radialGradient id="green" cx="50%" cy="50%" r="50%">
      <stop offset="0%" stop-color="#0f0" stop-opacity="1" />
      <stop offset="100%" stop-color="#0f0" stop-opacity="0" />
    </radialGradient>
    <radialGradient id="blue" cx="50%" cy="50%" r="50%">
      <stop offset="0%" stop-color="#00f" stop-opacity="1" />
      <stop offset="100%" stop-color="#00f" stop-opacity="0" />
    </radialGradient>
  </defs>
  
  <!-- adjust the radiuses here to make it more -->
  <circle cx="0"    cy="50%" r="70%" fill="url(#red)" />
  <circle cx="50%"  cy="50%" r="70%" fill="url(#green)" />
  <circle cx="100%" cy="50%" r="70%" fill="url(#blue)" />  
</svg>

CSS

body {
  background: #333;
  margin: 0;
}

scg circle {
  /* color-dodge, plus-lighter, lighten, screen */
  mix-blend-mode: color-dodge;
}

JavaScript

const svg = document.getElementById('svg');
svg.setAttribute('width', '100vw');
svg.setAttribute('height', '100svh');

const circles = svg.getElementsByTagName('circle');

// this would need to be updated on window resize
const width = svg.clientWidth;
const height = svg.clientHeight;

svg.onmousemove = (event) => {
  const x = event.offsetX / width;
  const y = event.offsetY / height; 
  
  // just some arbitrary calculations to put the circles somewhere based on the mouse position
  circles[0].style.cx = x * width;
  circles[0].style.cy = y * height;  
  circles[1].style.cx = (1-x) * width;
  circles[1].style.cy = y * height ;  
  circles[2].style.cx = x * width ;
  circles[2].style.cy = (1-y) * height;  
};