Double Rainbow Animated


  color skyBlue = color(0x87, 0xCE, 0xEB); // Equivalent of the CSS color #87CEEB
  color lightSkyBlue = color(0x87, 0xCE, 0xFA);
  color deepSkyBlue = color(0x00, 0xBF, 0xFF);
  color white = color(255, 255, 255);
  
  void setup()
  {
    size(600, 300);
    smooth();
    frameRate(12);
  }
  
  void draw()
  {
    setGradient(0, 0, width,   height*.333,         deepSkyBlue, skyBlue);
    setGradient(0, height*.333, width, height*.333,  skyBlue, lightSkyBlue);
    setGradient(0, height*.666, width, height*.333,  lightSkyBlue, white);
    
    float cx = width/2;
    float cy = height;
    float rainbowThick = width / 6.0;
    float bandDistance = rainbowThick*2;
    float outerDiam = width * .64;
    
    colorMode(HSB, 1);
    noFill();
    
    for (int band = 0; band < 2; ++band) {
     for (int i = 0; i < rainbowThick; ++i) {
        float ratio = i/rainbowThick;
        float ratio2 = (i+band*rainbowThick)/(rainbowThick*2);
        if (band > 0)
            ratio = 1-ratio;
        float hue = ratio*ratio;
        float sat = 0.85 + sq( sin(ratio2 - frameCount*.2))*.35;
        float bri = .9  + sq( sin(ratio2 - frameCount*.2))*.10;
        float alpha = sin( PI*ratio ) * 1.5 * (band > 0? .2 : .5);
      
        stroke( hue, sat, bri, alpha );
        float rad = band * bandDistance + outerDiam-i;
        arc(cx, cy, rad, rad, PI, PI*2);
      }
    }
  
    int fogHeight = round(height * 0.3 + cos(frameCount * .02)*height*0.2);
    int topFog = height-fogHeight;
    for (var i = 0; i <= fogHeight; ++i) {
      float fogRatio = sq(i/fogHeight);
      stroke(0,0,1,fogRatio);
      line(0, topFog+i, width, topFog+i);
    }
    colorMode(RGB, 256);
  }
  // END
  
  void setGradient(int x, int y, float w, float h, color c1, color c2 ){
    // calculate differences between color components 
    float deltaR = red(c2)-red(c1);
    float deltaG = green(c2)-green(c1);
    float deltaB = blue(c2)-blue(c1);
  
    for (int j = y; j<=(y+h); j++){
      color c = color(
      (red(c1)+(j-y)*(deltaR/h)),
      (green(c1)+(j-y)*(deltaG/h)),
      (blue(c1)+(j-y)*(deltaB/h)) 
        );
      stroke(c);
      line(x, j, x+w, j );
    }
  }