jquerycssradial-gradients

Subtle CSS gradient animations


I'm trying to make an animated background gradient similar to the one on Interweave's website here: https://interweaveagency.com/ but made out of CSS and jQuery onto a background element rather than a canvas element. I've made something like this in a fork from another codepen:

https://codepen.io/Jamie-Patterson/pen/rNrWXKL

$( document ).ready(function() {
var colors = new Array(
  [17,17,17],
  [17,17,17],
  [17,17,17],
  [187,238,0]);

var step = 0;
//color table indices for: 
// current color left
// next color left
// current color right
// next color right
var colorIndices = [0,1,2,3];

//transition speed
var gradientSpeed = 0.002;

function updateGradient() {
  var c0_0 = colors[colorIndices[0]];
  var c0_1 = colors[colorIndices[1]];
  var c1_0 = colors[colorIndices[2]];
  var c1_1 = colors[colorIndices[3]];

  var istep = 1 - step;
  var r1 = Math.round(istep * c0_0[0] + step * c0_1[0]);
  var g1 = Math.round(istep * c0_0[1] + step * c0_1[1]);
  var b1 = Math.round(istep * c0_0[2] + step * c0_1[2]);
  var color1 = "#"+((r1 << 16) | (g1 << 8) | b1).toString(16);

  var r2 = Math.round(istep * c1_0[0] + step * c1_1[0]);
  var g2 = Math.round(istep * c1_0[1] + step * c1_1[1]);
  var b2 = Math.round(istep * c1_0[2] + step * c1_1[2]);
  var color2 = "#"+((r2 << 16) | (g2 << 8) | b2).toString(16);

    $('#gradient').css({background: "-webkit-radial-gradient(80% 10%, circle, "+color1+", transparent), -webkit-radial-gradient(80% 50%, circle, "+color2+", transparent)"});
    
    step += gradientSpeed;
    if ( step >= 1 )
    {
      step %= 1;
      colorIndices[0] = colorIndices[1];
      colorIndices[2] = colorIndices[3];
      
      //pick two new target color indices
      //do not pick the same as the current one
      colorIndices[1] = ( colorIndices[1] + Math.floor( 1 + Math.random() * (colors.length - 1))) % colors.length;
      colorIndices[3] = ( colorIndices[3] + Math.floor( 1 + Math.random() * (colors.length - 1))) % colors.length;
      
    }
} setInterval(updateGradient,10);

});

But it lacks the subtlety I've been trying to achieve as it shifts heavily from one gradient to another rather than the more lavalamp effect from the Interweave site. If anyone's built something similar out of CSS/jQuery before and has a solution let me know.


Solution

  • Here's a plain CSS implementation you can adapt.

    For the subtlety, create a larger background, e.g. 400%, and move it around. See .bg1

    For the light and dark gradients, they look to me as transparently layered, so I'm adding a second div with a semi-transparent highlight. See .bg2

    body,
    html {
      margin: 0;
      padding: 0;
    }
    
    .container {
      width: 100vw;
      height: 100vh;
      position: relative;
    }
    
    .bg1,
    .bg2 {
      position: absolute;
      width: 100%;
      height: 100%;
    
    }
    
    .bg1 {
    
      animation: bg1 8s ease infinite;
      animation-direction: alternate-reverse;
      background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #1cb693);
      background-size: 400% 400%;
    }
    
    @keyframes bg1 {
      0% {
        background-position: 100% 50%;
      }
    
      100% {
        background-position: 0 50%;
      }
    }
    
    .bg2 {
      animation: bg2 5s ease infinite;
      animation-direction: alternate-reverse;
      background: radial-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));
      background-size: 100% 200%;
      background-repeat: no-repeat;
    }
    
    @keyframes bg2 {
      0% {
        background-position: 0% 100%;
      }
    
      100% {
        background-position: 100% 0%;
      }
    }
    <div class="container">
      <div class="bg1"></div>
      <div class="bg2"></div>
    </div>