#include <FastLED.h>

#define kMatrixWidth 16
#define kMatrixHeight 16
#define NUM_LEDS ((kMatrixWidth) * (kMatrixHeight))

CRGB leds[NUM_LEDS + 1];

uint16_t XY(uint8_t x, uint8_t y) {
  if (x >= kMatrixWidth || y >= kMatrixHeight)
    return NUM_LEDS;
  if (y & 1)
    x = kMatrixWidth - 1 - x;
  return x + (y * kMatrixWidth);
}

void setup() {
  FastLED.addLeds<WS2812B, 3, GRB>(leds, NUM_LEDS);
}

void loop() {
  static uint16_t startHue = 0;
  static uint8_t xPhase = 0;
  static uint8_t yPhase = 64;
  uint8_t pixelHue = startHue;
  for (uint16_t i = 0; i < 128; i++) {
    uint8_t x = cos8(xPhase + i * 2) / (256 / kMatrixWidth);
    uint8_t y = sin8(yPhase + i * 2) / (256 / kMatrixHeight);
    leds[XY(x, y)] = ColorFromPalette(RainbowColors_p, pixelHue, 255, LINEARBLEND);
    pixelHue += 2;
  }
  FastLED.show();
  FastLED.clear();
  startHue += 3;
  xPhase += 2;
}