morph_route 0.1.3
morph_route: ^0.1.3 copied to clipboard
iOS 26-inspired container morph for Flutter. A modified OpenContainer with backdrop blur, accent scrim, 3D tilt, and a scaffold-level recede helper — drop-in widgets to make any tile-to-screen navigat [...]
Changelog #
0.1.3 #
- Package archive shrinks from ~2 MB to ~18 KB:
demo.gif/demo.mov(the README already embeds the GIF by URL) and repo tooling (AGENTS.md,CLAUDE.md,docs/,tool/,.github/) no longer ship to pub.dev. MorphTile: the press scale now applies to the whole card (background, shape, shadow) instead of shrinking the content inside a full-size card.MorphTile: releasing a press no longer flashes grey — the tint fades by alpha instead of lerping toward transparent black.MorphTile: exposed to VoiceOver/TalkBack as a button.OpenContainer: the close morph now re-measures the tile on pop, so it lands on the tile's real position after a rotation, keyboard or list scroll while open (previously it aimed at the push-time rect and snapped up to ~150 pt at the end).MorphRecede's own scale is still excluded from the measurement.OpenContainer: no longer allocates aCurvedAnimation(plus a status listener) every frame of the morph, and no longer rebuilds the open and closed screens every frame — ~2× less UI-thread build time per frame on device.OpenContainer: the fading closed copy ignores taps mid-morph; the tile's slot keeps its untransformed size while the route is open.MorphRecede: the receding body is a repaint boundary, so it re-composites instead of repainting each frame.- Respect Reduce Motion: on iOS (
AccessibilityFeatures.reduceMotion) and Android "Remove animations" (MediaQuery.disableAnimations),OpenContainer/MorphTilecross-fade instead of morphing, and 3D tilt,MorphRecedescale and the press scale are off. Scrim, blur, tint and durations are unchanged. No API change. - Source formatted at 120 columns (
formatter.page_width), enforced in CI. - Example: four tiles that showcase every widget (
MorphTilewith tilt,fadeThrough,OpenContainerwith a return value, a route pushed on top of a morph), and a layout that fits the largest accessibility text size and landscape. - CI: format, analyze, tests and publish dry-run on every PR, plus the example's end-to-end suite on an iOS simulator.
0.1.2 #
- Restructured README header (centered title, tagline, and pub/platform/license badges).
- Tightened wording, added subtle section emojis, and split the long lead paragraph into a scannable feature list.
- Removed the invalid
publisher:pubspec key (publisher attribution lives in pub.dev's admin UI, not pubspec).
0.1.1 #
- Set
publisher: hashstudios.devso the package is attributed to the verified publisher. - Use absolute GitHub raw URL for the demo GIF so it renders on pub.dev.
- Update README install instructions to point at the published version.
0.1.0 — Initial release #
First public-shaped cut. Extracted from a Flutter wallet app where the morph shipped on the Send flow.
OpenContainer #
Vendored from package:animations (BSD-3) with the following modifications:
- No more
Material. Replaced withContainer+ShapeDecorationso we don't inherit the ink splash, default elevation paint, oranimationDurationfor color changes. Custom shadow tokens viaclosedShadows/openShadows. - Dropped
closedElevation/openElevationand the elevation tween. - Tunable scrim color.
scrimColor(default transparent) replaces the hard-codedColors.black54. - Backdrop blur.
closedBlurSigma/openBlurSigma— the route inserts aBackdropFilterthat lerps with the morph curve so the underlying screen progressively goes out of focus. - 3D tilt.
peakTiltY/peakTiltX/tiltPerspective— iOS 26-style perspective rotation that peaks at the morph's midpoint (sin(π·t)) and is 0 at both endpoints. activeProgress. StaticValueNotifier<double>published every animation tick so widgets outside the route (the host shell) can react in lock-step.reverseTransitionDuration. Override for snappier closes than opens.- Pop fix.
_takeMeasurementsno longer re-reads the source rect on pop — upstream walks through every transform on the underlying screen (getTransformTo(navigator)), which lands the close at a transformed rect if the host applies its own transform during the morph (e.g. via [MorphRecede]).
MorphTile #
Pressable wrapper around OpenContainer. Adds:
- Tap handling (so you don't have to wire
tappable: falseplumbing). - Press feedback: subtle
AnimatedScale(default 0.98) + optional tinted overlay color. onTaphook for haptics / analytics.
MorphRecede #
Scaffold-body wrapper that scales down (and optionally translates) as a morph
route opens, synced to OpenContainer.activeProgress. Pluggable progress
source via the progress parameter for custom integrations.
Example #
example/ runs a minimal demo of MorphTile + MorphRecede against a
placeholder destination screen.