#pragma once #include "effects/Common.h" #include "helpers/BellCurve.h" #pragma pack(push, 1) struct EffectReverseSwipeConfig { float swipeSpeed; // in degrees per second float bellCurveWidthInLeds; float startPosition; }; #pragma pack(pop) template class EffectReverseSwipe { public: static constexpr auto NUM_LEDS = numLeds(); static constexpr int DELAY_MS = 10; using ConfigType = EffectReverseSwipeConfig; EffectReverseSwipe(const EffectReverseSwipeConfig &cfg, TLedStrip &ledStrip) : ledStrip_(ledStrip), currentPosition_(float(NUM_LEDS) / 2 + cfg.bellCurveWidthInLeds), bellCurveWidth_(cfg.bellCurveWidthInLeds), invBellCurveWidth_(1.0f / cfg.bellCurveWidthInLeds), speed_(cfg.swipeSpeed / 360 / 1000 * NUM_LEDS * DELAY_MS), startPosition_(cfg.startPosition / 360.0f * NUM_LEDS), finished_(false) { for (int i = 0; i < NUM_LEDS; ++i) state_[i] = getLedRGBW(ledStrip_, i); } bool finished() const { return finished_; } int operator()() { if (finished_) return 60000; const auto width = std::min(int(currentPosition_ + 1), int(NUM_LEDS / 2) + 1); { float brightness = stepFunction(currentPosition_, bellCurveWidth_, invBellCurveWidth_); ColorRGBW &prevC = state_[ledStrip_.normalizeIdx(startPosition_)]; setLedRGBW(ledStrip_, startPosition_, prevC * brightness); } for (int i = 1; i < width; ++i) { const float x = currentPosition_ - float(i); if (x > 0.0f) { const int led1 = startPosition_ + i; const int led2 = startPosition_ - i; float brightness = stepFunction(x, bellCurveWidth_, invBellCurveWidth_); ColorRGBW &prevC1 = state_[ledStrip_.normalizeIdx(led1)]; ColorRGBW &prevC2 = state_[ledStrip_.normalizeIdx(led2)]; setLedRGBW(ledStrip_, led1, prevC1 * brightness); setLedRGBW(ledStrip_, led2, prevC2 * brightness); } } currentPosition_ -= speed_; if (currentPosition_ < 0) { finished_ = true; clear(ledStrip_); } return DELAY_MS; } private: TLedStrip &ledStrip_; float currentPosition_; float bellCurveWidth_; float invBellCurveWidth_; float speed_; int startPosition_; bool finished_; ColorRGBW state_[NUM_LEDS]; }; // Traits template <> struct EffectIdToConfig { using type = EffectReverseSwipeConfig; }; template <> struct EffectConfigToId { static constexpr auto id = EffectId::REVERSE_SWIPE; }; template struct EffectIdToClass { using type = EffectReverseSwipe; };