diff options
-rw-r--r-- | keywords.txt | 2 | ||||
-rw-r--r-- | src/colorutils.cpp | 41 | ||||
-rw-r--r-- | src/colorutils.h | 38 |
3 files changed, 79 insertions, 2 deletions
diff --git a/keywords.txt b/keywords.txt index 75df500c..4fb29ab2 100644 --- a/keywords.txt +++ b/keywords.txt @@ -130,7 +130,9 @@ fade_video KEYWORD2 fill_gradient KEYWORD2 fill_gradient_RGB KEYWORD2 fill_palette KEYWORD2 +fill_palette_circular KEYWORD2 fill_rainbow KEYWORD2 +fill_rainbow_circular KEYWORD2 fill_solid KEYWORD2 map_data_into_colors_through_palette KEYWORD2 nblend KEYWORD2 diff --git a/src/colorutils.cpp b/src/colorutils.cpp index a1acaa5a..941f4686 100644 --- a/src/colorutils.cpp +++ b/src/colorutils.cpp @@ -62,6 +62,47 @@ void fill_rainbow( struct CHSV * targetArray, int numToFill, } +void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, uint8_t initialhue, bool reversed) +{ + if (numToFill == 0) return; // avoiding div/0 + + CHSV hsv; + hsv.hue = initialhue; + hsv.val = 255; + hsv.sat = 240; + + const uint16_t hueChange = 65535 / (uint16_t)numToFill; // hue change for each LED, * 256 for precision (256 * 256 - 1) + uint16_t hueOffset = 0; // offset for hue value, with precision (*256) + + for (int i = 0; i < numToFill; ++i) { + targetArray[i] = hsv; + if (reversed) hueOffset -= hueChange; + else hueOffset += hueChange; + hsv.hue = initialhue + (uint8_t)(hueOffset >> 8); // assign new hue with precise offset (as 8-bit) + } +} + +void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, uint8_t initialhue, bool reversed) +{ + if (numToFill == 0) return; // avoiding div/0 + + CHSV hsv; + hsv.hue = initialhue; + hsv.val = 255; + hsv.sat = 240; + + const uint16_t hueChange = 65535 / (uint16_t) numToFill; // hue change for each LED, * 256 for precision (256 * 256 - 1) + uint16_t hueOffset = 0; // offset for hue value, with precision (*256) + + for (int i = 0; i < numToFill; ++i) { + targetArray[i] = hsv; + if (reversed) hueOffset -= hueChange; + else hueOffset += hueChange; + hsv.hue = initialhue + (uint8_t)(hueOffset >> 8); // assign new hue with precise offset (as 8-bit) + } +} + + void fill_gradient_RGB( CRGB* leds, uint16_t startpos, CRGB startcolor, uint16_t endpos, CRGB endcolor ) diff --git a/src/colorutils.h b/src/colorutils.h index f09d525f..43c9c0ad 100644 --- a/src/colorutils.h +++ b/src/colorutils.h @@ -37,6 +37,21 @@ void fill_rainbow( struct CHSV * targetArray, int numToFill, uint8_t deltahue = 5); +/// fill_rainbow_circular - fill a range of LEDs with a rainbow of colors, at +/// full saturation and full value (brightness), +/// so that the hues are continuous between the end +/// of the strip and the beginning +void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, + uint8_t initialhue, bool reversed=false); + +/// fill_rainbow_circular - fill a range of LEDs with a rainbow of colors, at +/// full saturation and full value (brightness), +/// so that the hues are continuous between the end +/// of the strip and the beginning +void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, + uint8_t initialhue, bool reversed=false); + + // fill_gradient - fill an array of colors with a smooth HSV gradient // between two specified HSV colors. // Since 'hue' is a value around a color wheel, @@ -1551,10 +1566,10 @@ CHSV ColorFromPalette( const CHSVPalette32& pal, TBlendType blendType=LINEARBLEND); -// Fill a range of LEDs with a sequece of entryies from a palette +// Fill a range of LEDs with a sequence of entries from a palette template <typename PALETTE> void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, - const PALETTE& pal, uint8_t brightness, TBlendType blendType) + const PALETTE& pal, uint8_t brightness=255, TBlendType blendType=LINEARBLEND) { uint8_t colorIndex = startIndex; for( uint16_t i = 0; i < N; ++i) { @@ -1563,6 +1578,25 @@ void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, } } +// Fill a range of LEDs with a sequence of entries from a palette, so that +// the entire palette smoothly covers the range of LEDs +template <typename PALETTE> +void fill_palette_circular(CRGB* L, uint16_t N, uint8_t startIndex, + const PALETTE& pal, uint8_t brightness=255, TBlendType blendType=LINEARBLEND, + bool reversed=false) +{ + if (N == 0) return; // avoiding div/0 + + const uint16_t colorChange = 65535 / N; // color change for each LED, * 256 for precision + uint16_t colorIndex = ((uint16_t) startIndex) << 8; // offset for color index, with precision (*256) + + for (uint16_t i = 0; i < N; ++i) { + L[i] = ColorFromPalette(pal, (colorIndex >> 8), brightness, blendType); + if (reversed) colorIndex -= colorChange; + else colorIndex += colorChange; + } +} + template <typename PALETTE> void map_data_into_colors_through_palette( uint8_t *dataArray, uint16_t dataCount, |