GlassMorphController class

A Flutter-idiomatic controller for liquid glass morph animations.

Works like AnimationController but encapsulates the iOS 26 spring physics, J-curve interpolation, and LiquidMorphState computation behind a clean, semantic API.

Lifecycle

GlassMorphController must be created inside a State that mixes in TickerProviderStateMixin and disposed in State.dispose.

class _MyWidgetState extends State<MyWidget> with TickerProviderStateMixin {
  late final GlassMorphController _morph;

  @override
  void initState() {
    super.initState();
    _morph = GlassMorphController(vsync: this);
    _morph.addListener(_onFrame);
  }

  @override
  void dispose() {
    _morph.dispose();
    super.dispose();
  }

  void _open()  => _morph.open();
  void _close() => _morph.close();

  void _onFrame() {
    if (!mounted) return;
    setState(() {});
  }
}

Computing render state

final state = _morph.computeState(
  finalDx: finalDx,
  finalDy: finalDy,
  horizontalOffset: _horizontalOffset,
  verticalOffset: _verticalOffset,
);

// Use state.pathT, state.anchorScale, state.blend, etc. in your layout.

Customisation

Use speed and style for safe, semantic control. Avoid constructing LiquidMorphPhysics manually with custom spring constants — the physics parameters are interdependent and incorrect values produce unstable animations.

Inheritance

Constructors

GlassMorphController({required TickerProvider vsync, MorphSpeed speed = MorphSpeed.normal, MorphStyle style = MorphStyle.teardrop})
Creates a GlassMorphController.

Properties

animation AnimationController
The underlying AnimationController for callers that need to listen to AnimationStatus changes or drive additional Animations from it.
no setter
disableAnimations bool
Whether reduced-motion override is currently active.
no setter
hasHandedOff bool
Whether the anchor blob has handed off back to the real trigger.
no setter
hashCode int
The hash code for this object.
no setterinherited
hasListeners bool
Whether any listeners are currently registered.
no setterinherited
isClosing bool
Whether the controller is in the closing phase.
no setter
isShowing bool
Whether the morph overlay should currently be visible.
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
speed MorphSpeed
Speed profile for the morph animation.
final
status AnimationStatus
Current AnimationStatus of the underlying controller.
no setter
style MorphStyle
Visual shape style of the morph transition.
final
value double
The raw, unclamped spring simulation value.
no setter
velocity double
Instantaneous velocity of the spring simulation.
no setter

Methods

addListener(VoidCallback listener) → void
Register a closure to be called when the object changes.
inherited
close() → void
Closes the morph animation with the iOS 26 rubber-band bounce.
computeState({required double finalDx, required double finalDy, double horizontalOffset = 0.0, double verticalOffset = 0.0}) LiquidMorphState
Computes the current LiquidMorphState for the given layout geometry.
dispose() → void
Discards any resources used by the object. After this is called, the object is not in a usable state and should be discarded (calls to addListener will throw after the object is disposed).
override
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
notifyListeners() → void
Call all the registered listeners.
inherited
open() → void
Opens the morph animation from the current position.
removeListener(VoidCallback listener) → void
Remove a previously registered closure from the list of closures that are notified when the object changes.
inherited
setDisableAnimations(bool disableAnimations) → void
Updates the reduced-motion override.
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited