67 lines
2.2 KiB
C++
67 lines
2.2 KiB
C++
|
#include "../Figments/Figments.h"
|
||
|
|
||
|
using namespace NSFastLED;
|
||
|
class DrainAnimation: public Figment {
|
||
|
public:
|
||
|
|
||
|
DrainAnimation(Task::State initialState) : Figment("Drain", initialState) {}
|
||
|
|
||
|
void loop() override {
|
||
|
EVERY_N_MILLISECONDS(8) {
|
||
|
m_pos++;
|
||
|
m_fillColor.update();
|
||
|
}
|
||
|
EVERY_N_MILLISECONDS(50) {
|
||
|
if (random(255) >= 10) {
|
||
|
m_burst -= m_burst / 10;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void handleEvent(const InputEvent& event) override {
|
||
|
if (event.intent == InputEvent::SetColor) {
|
||
|
m_fillColor = event.asRGB();
|
||
|
} else if (event.intent == InputEvent::Acceleration) {
|
||
|
m_pos += log10(event.asInt());
|
||
|
uint16_t burstInc = event.asInt() / 6;
|
||
|
m_burst = (m_burst > 0xFFFF - burstInc) ? 0xFFFF : m_burst + burstInc;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
AnimatedRGB m_fillColor;
|
||
|
|
||
|
void render(Display* dpy) const override {
|
||
|
dpy->clear();
|
||
|
Surface leftPanel{dpy, {0, 0}, {128, 0}};
|
||
|
Surface rightPanel{dpy, {128, 0}, {255, 0}};
|
||
|
fillRange(dpy, leftPanel.start, leftPanel.end, rgb2hsv_approximate(m_fillColor));
|
||
|
fillRange(dpy, rightPanel.end, rightPanel.start, rgb2hsv_approximate(m_fillColor));
|
||
|
}
|
||
|
|
||
|
void fillRange(Display* dpy, const PhysicalCoordinates &start, const PhysicalCoordinates& end, const CHSV &baseColor) const {
|
||
|
int length = end.x - start.x;
|
||
|
int direction = 1;
|
||
|
if (length < 0) {
|
||
|
direction = -1;
|
||
|
}
|
||
|
|
||
|
uint8_t frac = 255 / std::abs(length);
|
||
|
for(int i = 0; i < std::abs(length); i++) {
|
||
|
auto coords = PhysicalCoordinates((start.x + (i * direction)), 0);
|
||
|
|
||
|
const uint8_t localScale = inoise8(i * 80, m_pos * 3);
|
||
|
const uint8_t dimPosition = lerp8by8(50, 190, scale8(sin8((frac * i) / 2), localScale));
|
||
|
const uint8_t withBurst = ease8InOutCubic(lerp16by16(dimPosition, 255, m_burst));
|
||
|
auto scaledColor = CHSV(baseColor.hue, lerp8by8(100, 255, localScale), withBurst);
|
||
|
|
||
|
CRGB src(dpy->pixelAt(coords));
|
||
|
dpy->pixelAt(coords) = blend(scaledColor, src, 200);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint16_t m_pos;
|
||
|
uint16_t m_burst;
|
||
|
};
|
||
|
|
||
|
|