// https://www.reddit.com/r/FastLED/comments/18br0uw/meteor_rain_replace_fadetoblack_with/

// Libraries
#include "FastLED.h"
 
#define NUM_LEDS 60
CRGB leds[NUM_LEDS];
uint8_t meteor[NUM_LEDS];  // to hold the meteor trail(s)
#define PIN 3
#define BRIGHTNESS  255


DEFINE_GRADIENT_PALETTE(meteorGradPal) {
  0,   0, 0, 0,
  64,  128, 0, 0,
  128, 192, 0, 192,
  255, 255, 255, 255
};
CRGBPalette16 palette = meteorGradPal;

void setup()
{
 delay(1000); // 1 second delay for recovery
 
  FastLED.addLeds<WS2813, PIN, GRB>(leds, NUM_LEDS); //.setCorrection( TypicalSMD5050 ); // tell FastLED about the LED strip configuration
  FastLED.setBrightness(BRIGHTNESS); // set master brightness control
}
 
void loop() {
  meteorRain(10, 16, true, 10);
}
 
void meteorRain(byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) {
   
   
    // fade brightness all LEDs one step
    for(int j=0; j<NUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10)>5) ) {
        // fadeToBlack(j, meteorTrailDecay );
        fadeMeteor(j, meteorTrailDecay);
      }
    }
   
    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j <NUM_LEDS) && (i-j>=0) ) {
        // setPixel(i-j, red, green, blue);
        setMeteor(i-j, 255);
      }
    }
   
    showStrip();
    delay(SpeedDelay);
  }
}
 
void fadeToBlack(int ledNo, byte fadeValue) {
   leds[ledNo].fadeToBlackBy( fadeValue );
}
 
void showStrip() {
  // fill the LEDs with the meteor data mapped to a palette
  for (int i = 0; i < NUM_LEDS; i++) {
    // values over 240 cause ColorFromPalette to wrap around back to 0
    // so constrain to the range 0-240
    uint8_t meteorVal = meteor[i] <= 240 ? meteor[i] : 240;
    leds[i] = ColorFromPalette(palette, meteorVal);
  }
  FastLED.show();
}
 
void setPixel(int Pixel, byte red, byte green, byte blue) {
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
}
 
void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

void fadeMeteor(int ledNo, uint8_t fadeValue) {
  if (meteor[ledNo] >= fadeValue)
    meteor[ledNo] -= fadeValue;
  else
    meteor[ledNo] = 0;
}

void setMeteor(int ledNo, uint8_t value) {
  meteor[ledNo] = value;
}