From d22fe9227b1c24768999e249ecb87317061c6a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Sun, 16 Feb 2025 10:21:24 +0100 Subject: [PATCH] Prevent push transition if effect stays the same --- wled00/FX_fcn.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index ff1cd9838a..d9fbd8b431 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1550,6 +1550,11 @@ void WS2812FX::service() { #ifndef WLED_DISABLE_MODE_BLEND Segment::setClippingRect(0, 0); // disable clipping (just in case) if (seg.isInTransition()) { + // a hack to determine if effect has changed + uint8_t m = seg.currentMode(); + Segment::modeBlend(true); // set semaphore + bool sameEffect = (m == seg.currentMode()); + Segment::modeBlend(false); // clear semaphore // set clipping rectangle // new mode is run inside clipping area and old mode outside clipping area unsigned p = seg.progress(); @@ -1558,7 +1563,20 @@ void WS2812FX::service() { unsigned dw = p * w / 0xFFFFU + 1; unsigned dh = p * h / 0xFFFFU + 1; unsigned orgBS = blendingStyle; - if (w*h == 1) blendingStyle = BLEND_STYLE_FADE; // disable belending for single pixel segments (use fade instead) + if (w*h == 1) blendingStyle = BLEND_STYLE_FADE; // disable style for single pixel segments (use fade instead) + else if (sameEffect && (blendingStyle & BLEND_STYLE_PUSH_MASK)) { + // when effect stays the same push will look awful, change it to swipe + switch (blendingStyle) { + case BLEND_STYLE_PUSH_BR: + case BLEND_STYLE_PUSH_TR: + case BLEND_STYLE_PUSH_RIGHT: blendingStyle = BLEND_STYLE_SWIPE_RIGHT; break; + case BLEND_STYLE_PUSH_BL: + case BLEND_STYLE_PUSH_TL: + case BLEND_STYLE_PUSH_LEFT: blendingStyle = BLEND_STYLE_SWIPE_LEFT; break; + case BLEND_STYLE_PUSH_DOWN: blendingStyle = BLEND_STYLE_SWIPE_DOWN; break; + case BLEND_STYLE_PUSH_UP: blendingStyle = BLEND_STYLE_SWIPE_UP; break; + } + } switch (blendingStyle) { case BLEND_STYLE_FAIRY_DUST: // fairy dust (must set entire segment, see isPixelXYClipped()) Segment::setClippingRect(0, w, 0, h); @@ -1604,7 +1622,7 @@ void WS2812FX::service() { Segment::setClippingRect(0, dw, h - dh, h); break; } - frameDelay = (*_mode[seg.currentMode()])(); // run new/current mode + frameDelay = (*_mode[m])(); // run new/current mode // now run old/previous mode Segment::tmpsegd_t _tmpSegData; Segment::modeBlend(true); // set semaphore