Skip to content

Animated GIF preview in Firefox (4.1.1.0) - #56

Merged
bardesss merged 3 commits into
mainfrom
fix/gif-preview-firefox
Oct 15, 2026
Merged

bardesss merged 3 commits into
mainfrom
fix/gif-preview-firefox

Conversation

@bardesss

Copy link
Copy Markdown
Owner

Release 4.1.1.0: an animated GIF background now also moves in the live preview in Firefox.

Cause

A probe on the user's Firefox 153 with 4.1.0.0 showed that the GIF was recognised and the repaint loop was running (119 calls in 2 s). Even so, drawImage of the animated <img> kept returning the same frame. Chrome draws an animated image's current frame; Firefox doesn't for this hidden image. Applied covers were never affected.

Fix

  • The editor decodes the GIF frame by frame with WebCodecs ImageDecoder (Firefox ≥ 133, Chrome/Edge ≥ 94) and draws the current frame.
    • Only that frame is kept in memory, and every VideoFrame is closed.
    • The frame count is read after decoder.completed, because Firefox may report it late.
  • Playback runs in real time on its own schedule: nextAt += delay, with per-frame delays. Late frames are skipped, while redraws stay capped at about 15 per second. The clock resyncs on resume, so returning to the page doesn't fast-forward.
  • There is still one repaint loop. A decode that finishes after the background was replaced or the loop stopped is dropped. The decoder is closed when the background is replaced or cleared.
  • Without ImageDecoder (Safari), or if decoding fails, the editor falls back to the previous <img> behaviour; a failure is logged with console.debug.

CHANGELOG ## 4.1.1.0 and README are updated.

Testing

  • 351 tests pass locally (net9.0 / Jellyfin 10.11.3). CI verifies net10.0 / Jellyfin 12.
  • Chromium harness: a 10-frame GIF at 30 ms per frame played at 1.00× real time (33.2 vs 33.3 frames/s) with 13.7 redraws/s. After a stop it resumed at the kept frame.
  • Reviewed, with one fix round (real-time speed and frame count read after completed) that was then re-reviewed.

Live check (not yet done in a real Firefox)

  1. In Firefox and Chrome, upload the same animated GIF as background (e.g. the Gandalf one). The live preview moves at the GIF's own speed in both.
  2. Switch to Gradient and back: it stops, then starts again.
  3. Move the title and press Ctrl+Z: it keeps moving.
  4. Go to another dashboard page and come back: it was stopped while you were away and resumes without racing ahead.
  5. Turn on reduced motion in the OS: the preview stays still.
  6. Safari (if available): still preview, no errors in the console.

🤖 Generated with Claude Code

bardesss and others added 3 commits October 15, 2026 12:53
Firefox keeps handing drawImage() the same frame of an animated GIF <img>,
so the editor preview stood still although the repaint loop ran. Where
WebCodecs' ImageDecoder exists, the GIF's frames are now decoded one at a
time and painted from a per-image canvas at the GIF's own frame delays
(<= 10 ms -> 100 ms), driven by the existing single gifTick loop and its
15 fps cap. Each VideoFrame is closed right after drawing; a frame that
arrives for a replaced background or a stopped loop is dropped and the
index kept, so returning to the page resumes. The decoder is closed when
its bitmap is replaced, cleared, loses the pick race or fails to load.
Without ImageDecoder, or if it fails, the old <img> path is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 1 for 4.1.1.0:
- Decoded playback keeps a schedule: nextAt += delay (not now + delay),
  frames whose time is over are skipped (decode() returns composited
  frames), per-frame delays are remembered as numbers, and the clock
  restarts on (re)start or when more than a loop behind, so a return to
  the page does not fast-forward. Fast GIFs now play in real time under
  the 15 fps render cap (also in Chrome, where the <img> path did).
- frameCount is read after Promise.all([tracks.ready, completed]) and
  re-read in the stepper, since Firefox reports it late.
- Simplified the draw-source expression; console.debug on a real decode
  failure before falling back to the <img>.
- CHANGELOG wording: real-time speed, redrawn up to ~15 fps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bardesss
bardesss merged commit 82a4c18 into main Oct 15, 2026
1 check passed
@bardesss
bardesss deleted the fix/gif-preview-firefox branch October 15, 2026 08:21
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.

1 participant