Skip to content

Add configurable crossfade transitions between image assets - #3353

Open
Glassto wants to merge 1 commit into
Screenly:masterfrom
Glassto:feature/image-crossfade-transitions
Open

Glassto wants to merge 1 commit into
Screenly:masterfrom
Glassto:feature/image-crossfade-transitions

Conversation

@Glassto

@Glassto Glassto commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Issues Fixed

Fixes #3351

Description

Adds an opt-out crossfade transition when the viewer rotates from one
image asset to the next (static image or animated GIF). Previously
this was an instant swap; now the outgoing frame fades out while the
incoming one fades in. :)

Scope is strictly image → image:

  • Video and web-page assets are unaffected. Switching to/from either
    still cuts instantly, since those paths already blank the current
    image before handing back to the image loader.
  • A playing GIF's own frame updates never re-trigger a fade:only an
    actual asset change does.
  • The very first image shown after boot doesn't fade in from black,
    since there's nothing to fade from.

Implementation:

  • image_transition.h/.cpp (new) holds the pure, unit-testable logic:
    parsing/clamping ANTHIAS_IMAGE_TRANSITION_MS (default 300 ms,
    clamped to 0–5000 ms; 0 disables it), the predicate that decides
    whether a fade should start, and the progress-from-elapsed-time
    math. This follows the same shape as the existing
    image_fallback.cpp / rotation.cpp. No QtWebEngine dependency,
    so it's covered by tests/test_image_transition.cpp (13 cases, all
    passing) without pulling in the heavier Qt modules.
  • View gained the state needed to run the transition
    (fadeFromImage, a 60fps fadeTimer that only runs while a fade is
    active, fadeElapsed, fadeDurationMs, fadeActive) plus
    startImageFade()/stopImageFade().
  • loadAsStaticImage() and setupAnimation() capture the outgoing
    frame right before it's overwritten and arm the fade. If a new
    image arrives mid-fade, this same capture re-seeds the fade from
    whatever is actually on screen at that instant instead of stacking
    two transitions.
  • The three places that intentionally blank the image canvas
    (playVideo(), the "null" video-onset sentinel in loadImage(),
    loadPage()) now also cancel any in-progress fade.
  • paintEvent() draws the outgoing and incoming frames through the
    exact same scale/centre math as before (factored into a small
    drawScaledImage() helper called twice instead of once), including
    on the linuxfb manual-rotation path, so both frames of a
    cross-fading pair are rotated identically rather than blended
    before rotation.

Not touched: asset scheduling/duration semantics (the fade happens
inside the existing display window), and the video/web-page paths
themselves.

Checklist

  • I have performed a self-review of my own code.
  • New and existing unit tests pass locally and on CI with my changes.
  • I have done an end-to-end test for Raspberry Pi devices.
  • I have tested my changes for x86 devices.
  • I added a documentation for the changes I have made (when necessary).

@Glassto
Glassto requested a review from a team as a code owner September 23, 2026 20:12
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Sep 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (master@cb28b51). Learn more about missing BASE report.

Additional details and impacted files
@@            Coverage Diff            @@
##             master    #3353   +/-   ##
=========================================
  Coverage          ?   90.77%           
=========================================
  Files             ?       85           
  Lines             ?    10475           
  Branches          ?     1163           
=========================================
  Hits              ?     9509           
  Misses            ?      707           
  Partials          ?      259           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add configurable crossfade transitions only between image assets

1 participant