MorphMotion class
A morph's motion profile: a pair of Motions from the motor package plus closeVelocityHint. Character can only be changed as a whole profile (a mid-flight profile swap retargets the simulation); custom profiles are built through the public constructor from any Motions (Cupertino presets, Material tokens, curves, custom springs).
The direction asymmetry is deliberate, on two axes:
- duration: open is faster than close - what unfolds responds instantly; the return is slightly lazier and has character;
- damping:
- open: critically damped (CupertinoMotion.smooth) - what the user is about to look at unfolds without jitter;
- close: underdamped (bounce 0.27, zeta ~0.73) + closeVelocityHint - a "rubbery" return bounce that the button itself finishes playing after the handoff latch.
The presets are byte-for-byte equivalent to hand-tuned SpringDescriptions: stiffness = (2pi/duration)^2, damping = (1-bounce)2sqrt(stiffness).
Contract constraints:
- closeMotion must be able to go below zero (a spring with bounce), otherwise the landing bump of the button simply cannot play (CurvedMotion degrades gracefully: the morph works, no bump);
- snapToEnd on springs must stay false - the handoff latch lives on the zero crossing.
Constructors
- MorphMotion({required String name, required Motion openMotion, required Motion closeMotion, double closeVelocityHint = 0})
-
Creates a custom profile from any two Motions.
const
Properties
- closeMotion → Motion
-
Drives close retargets; must be a spring able to cross zero, or
the landing bump cannot play.
final
- closeVelocityHint → double
-
A negative velocity injection when closing from rest - it amplifies
the return bounce. The controller applies it UNSCALED; distance
scaling (a far close lands heavier) is the responsibility of
flight.close, the only owner of pixel geometry.
final
- debugContractViolation → String?
-
The contract violation of this profile, or null when it is valid;
MorphController checks it in an assert whenever a profile is
installed. The one hard rule: a spring closeMotion must keep
snapToEnd false - the handoff latch fires on the close spring's
zero crossing and the landing bump is the undershoot below zero,
so snapping to the end clips both.
no setter
- hashCode → int
-
The hash code for this object.
no setteroverride
- name → String
-
Profile name, for debugging and toString.
final
- openMotion → Motion
-
Drives open retargets; keep it overshoot-free.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
override
Operators
-
operator ==(
Object other) → bool -
The equality operator.
override
Constants
- fast → const MorphMotion
- A brisk profile for small controls.
- glacial → const MorphMotion
- Magnifier mode: inspect the cascade and the landing frame by frame.
- instant → const MorphMotion
- ~0.28s, critically damped both ways: reduced motion and tests.
- normal → const MorphMotion
- The default: open at snappy response tempo, close at a perceptual duration.
- slow → const MorphMotion
- A relaxed profile for larger surfaces.
-
values
→ const List<
MorphMotion> - The built-in presets.