Knight Rider Effect with NeoPixel LED strip

Hi, I'm having trouble with my logic. I'm trying to simulate the Knight Rider effect with an Arduino Nano (ATmega328P) and a Neo Pixel strip (WS2812B). I have everything communicating and working fine. I'm struggling with my code flow. Basically starting from one side of the strip I want to fill 10 LEDs (out of 60 total) and then shift the 10 LEDs down. My plan was to use a for loop to light the first 10 LEDs within a while loop and then exit the for loop when the 10 LEDs are lit and then within the while loop, clear the first LED and light the next (11th) led, then delay, and continue incrementing in an else loop. I'm stuck with exiting the if loop and continuing to the else loop.

Thanks for any help in advance.

// A basic everyday NeoPixel strip test program.

// NEOPIXEL BEST PRACTICES for most reliable operation:
// - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections.
// - MINIMIZE WIRING LENGTH between microcontroller board and first pixel.
// - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR.
// - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS
//   connect GROUND (-) first, then +, then data.
// - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip,
//   a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED.
// (Skipping these may work OK on your workbench but can fail in the field)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    3

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 60

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


// setup() function -- runs once at startup --------------------------------

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
  Serial.begin(9600);
}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop() {
//g_vons loop functions
    knightRider(strip.Color(255,  0,  0), 1000, 10); // Red Bar
  
}

//g_vons functions for animated effects

void knightRider(uint32_t color, int wait, int barLength) {
  int i=0;
//  int j=0;
  int k=0;
   while(i<strip.numPixels()) {
    if (k<=barLength) {
       for(int k=0; k<barLength; k++) {
        strip.setPixelColor(k, color);         //  Set pixel's color (in RAM)
        strip.show();                          //  Update strip to match
        delay(wait);                           //  Pause for a moment
        }
       }
    else {
      strip.setPixelColor(i, strip.Color(0,  0,  0));
      strip.setPixelColor(i+barLength, color);
      i++;
      delay(wait);
//      j++;
      }
   }
}

Right now I'm trying to get this working in one direction and then I'll figure out how to do the reverse direction.

No fading yet ?

Keep it simple, use separate for-loops for each thing. Let's call this: "everything in code".

// a for-loop for the 10 first leds
for( int i=0; i<10; i++)
{
  turn on led[i]
}

// a for-loop to shift
for( int i=0; i<(60-10); i++)
{
  turn off led[i]
  turn on led[i+10]
}

// a for-loop for the last 10
for( int i=49; i<60; i++)
{
  turn off led[i]
}

There is another way.
Suppose that you have many leds, numbered from -1000 to +1000. They are all turned on, but only the leds 0 to +59 are visible.
Then you can make a mask of 10 leds and move it along the many leds.
If that works, then you could make a mask that is getting less transparent on one side to create a fading effect.
The "mask" is an array with constants of course.
Let's call this: "with a table".

Another way is using math only.
Suppose there is just one led that is moving. The rest of the leds has less brightness according to a curve. You can make the curve with math so that the first leds are still at full brightness.
Let's call this: "just math".

Thanks I was actually able to figure out how to make the bar move both directions. I still haven't figured out the fading tail part. I posted my progress on reddit and someone suggested playing with Cylon. It's pretty cool. Now I have to break it down and figure out how I'm going to modify the code.

Here's my working code:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    3

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 30

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


// setup() function -- runs once at startup --------------------------------

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
  Serial.begin(9600);
}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop() {
//g_vons loop functions
    knightRider(strip.Color(255,  0,  0), 500, 7); // Red Bar
 }

//g_vons functions for animated effects

void knightRider(uint32_t color, int wait, int barLength) {
  uint32_t off = (0, 0, 0);
  int i=0;
  int j=0;
  int k=0;
   while(i<strip.numPixels()) {
      for(int k=0; k<barLength; k++) {
       strip.setPixelColor(k, color);         //  Set pixel's color (in RAM)
       strip.show();                          //  Update strip to match
       delay(wait);                           //  Pause for a moment
        }
      for(int j=0; j<strip.numPixels(); j++) {
       strip.setPixelColor(j, off);         //  Set Bar Pixel 1 to 0 (in RAM)
       strip.setPixelColor(j+barLength, color);         //  Set next Bar pixel to color (in RAM)
       strip.show();                          //  Update strip to match
       delay(wait); 
       }
      for(int k=strip.numPixels(); k>strip.numPixels()-barLength; k--) {
       strip.setPixelColor(k, color);         //  Set pixel's color (in RAM)
       strip.show();                          //  Update strip to match
       delay(wait);                           //  Pause for a moment
        }
      for(int j=strip.numPixels(); j>0; j--) {
       strip.setPixelColor(j, off);         //  Set Bar Pixel 1 to 0 (in RAM)
       strip.setPixelColor(j-barLength, color);         //  Set next Bar pixel to color (in RAM)
       strip.show();                          //  Update strip to match
       delay(wait); 
       }
      strip.setPixelColor(0, off);
      strip.show();                          //  Update strip to match
      delay(wait);
}
}