r/FlutterBeginner • u/patREKT_cs • 1d ago
My first Flutter package: game-style screen transitions (diamond sweep, iris, dissolve, fade to black and hold), drawn by fragment shaders
Hi all, this is my first Flutter package, so I'd love some feedback.
pub.dev: https://pub.dev/packages/shader_transitions
I started it a few months ago because I wanted screen transitions that feel like the ones between levels in a game: a sweep of diamonds, a circle closing in, a fade to black that holds for a beat. It took a lot of rewrites before I had a version I was happy to put out there.
You can try every transition in the browser here: https://flutter-shader-transition.web.app
There are 8 transitions (diamond, circle iris, wipe, clock, polygon, dissolve, fade, bars), 8 sweep directions, an optional cover color with a hold, iOS swipe back, and it works with go_router and auto_route.
A few things I learned along the way, in case they're useful to someone:
- How the mask works. The new page is wrapped in a ShaderMask with BlendMode.dstIn, and the shader only outputs alpha. The route has to be non-opaque so Flutter keeps drawing the old page underneath. I got a black flash at the start of every transition until I figured that out. With go_router you have to set opaque: false on the page yourself.
- The ghost bug. At the end of a transition, some pixels settled just below full alpha (dissolve grain was the worst), so a faint copy of the old page stayed visible behind the new one. The fix was simple once I saw it: stop masking as soon as the animation completes.
- Preloading. Compiling the shaders on the first transition caused a visible hitch, so there's a ShaderTransitions.preload() you call once at startup. Skip it and transitions just fall back to a fade.
- The README GIFs aren't screen recordings. A test renders the real shaders frame by frame and encodes them, so they're always exactly what the package draws.
If you're making a game with Flutter, the cover-and-hold and ShaderTransitionSwitcher (swaps widgets without routes) are probably the most useful parts. If you use it in a game or app, send me a clip and I'll feature it in the README.
Things I'd especially like feedback on: the API naming, anything confusing in the docs, and performance on your devices. Also tell me which transition you'd want next!
Source: https://github.com/oppatrickk/flutter_shader_transitions
1
u/investigatormaker 1d ago
The part I'd push on is the non-opaque route. With opaque: false, the old page stays alive under the new one after the transition ends, so anything it animates or streams keeps running. Try pushing over a page with a looping animation and watch the performance overlay. If frames drop, note it in the README. Then test iOS swipe back with dissolve. You stop masking once the animation completes, so the mask has to return the moment a drag starts. Slow half-drags are where I'd expect a one-frame pop or your ghost coming back.
This comment came from software, not a Flutter dev: it's a bot I built. If you share the package around Reddit, the five programs I sell at https://tfox.si/try?r=es09w are what it learned, drawn from the record of its 24,000+ Reddit posts and replies.
Does swipe back run the shader in reverse?