IconMorphPlan class

Recipe for a IconicMorph — how the source glyph becomes the target.

The choreography the user feels — a travelling "worm", not a cross-fade:

  1. One real line of the SOURCE is the hero — e.g. the user's shoulders arc, picked by sourceAnchor. The worm rests on it.
  2. Its head launches along the line's own tangent and flies a smooth quintic-Hermite curve (flightLaunch, flightLand, flightBow, flightBias) over to the entry of a real TARGET line — e.g. the face's smile, picked by heroAnchor — arriving along the target's tangent so it eases in, never cutting across.
  3. The worm slides onto the target, the tail catching up (headLead) and drawing the smile on. Mechanically: a fixed-length window slides by arc length along one master path (source → flight → target).
  4. Meanwhile the source's other contours (the head ring) leave — by default they un-draw / retract (MorphExit.trim) rather than fade — and the target's others (brackets, eyes, nose) draw on (MorphAssemble — trim / scale / 3D flip), assembling the new icon around the line that travelled.

Everything is a tunable here so the SAME engine drives any pair of icons. This is pure data — the geometry it produces lives in MorphGeometry, the painting in IconicMorphPainter.

Annotations

Constructors

IconMorphPlan({Duration duration = IconMotion.iconMorph, Curve curve = IconicEase.flight, int samples = 200, Offset? heroAnchor, int? heroTargetIndex, Offset? sourceAnchor = const Offset(12, 20), int? sourceIndex, double flightLaunch = 1.5, double flightLand = 1.5, double flightBow = -0.40, double flightBias = 0.5, double flightRunway = 2.0, double headLead = 2.2, double headFade = 0.45, double flipStart = 0.55, double flipStagger = 0.1, double exitTaper = 0.5, double exitFade = 0.75, double assembleFade = 0.35, double taperFloor = 1, double assembleTaper = 0.18, double perspective = 0.0028, MorphAssemble assemble = MorphAssemble.trim, MorphExit exit = MorphExit.trim, bool flipSource = false, bool flipTarget = false})
const

Properties

assemble MorphAssemble
How the ARRIVING (target) non-hero contours assemble — MorphAssemble.trim (draw-on, the default), MorphAssemble.scale (zoom in), or MorphAssemble.flip3d (the 3D flip). Governs the NEW glyph only.
final
assembleFade double
Emergence span (0..1) — the share of an arriving contour's own draw over which its ALPHA ramps from nothing to full. The mirror of exitFade.
final
assembleTaper double
Nib press-down (0..1) — the fraction of an arriving contour's draw-on (MorphAssemble.trim) over which its stroke weight ramps from taperFloor up to full, the mirror of exitTaper. Like it, inert unless taperFloor is lowered below 1. Default 0.18.
final
curve Curve
The worm's temporal ease — the velocity profile the head and tail ride along the master path. Defaults to IconicEase.flight (peak velocity at the first frame, long soft settle — the signature). Direction-aware: a reverse play mirrors it so the worm still launches fast and lands slow going backward. Swap in IconicEase.snap for a spring launch or any Curve of your own.
final
duration Duration
Total play time. Prefer IconMotion constants for consistent timing.
final
exit MorphExit
How the LEAVING (source) non-hero contours disappear — MorphExit.trim (un-draw / retract, the default), MorphExit.fade (alpha fade), or MorphExit.scale (shrink + fade). Governs the OLD glyph only, independent of assemble.
final
exitFade double
Dissolve span (0..1) — a leaving contour's ALPHA fades to nothing over the last 1 - exitFade of the whole animation. This is the whole vanish. Default 0.75 = a quarter of the morph, ≈160 ms at the default duration.
final
exitTaper double
Pen-lift taper (0..1) — the point in a leaving contour's exit after which its STROKE WEIGHT starts easing down toward taperFloor.
final
flightBias double
Bow position — where along the flight the flightBow hump peaks (0..1; 0.5 = mid). Shift toward 0 to fatten the launch side, toward 1 the landing.
final
flightBow double
Lateral bow — signed swing perpendicular to the head→entry chord, as a fraction of the gap (≈ -0.8…0.8; 0 = no swing). When the two tangents near-oppose, a straight flight has to reverse hard through the middle (the "sharp turn"); a bow swings the whole path wide to ONE side instead, turning that reversal into a single broad arc. Sign picks the side (CW vs CCW); you own the magnitude so it never balloons. Added as a bump that's flat at both ends, so it never disturbs the launch/landing tangents.
final
flightLand double
Landing breathing — the quintic landing-velocity as a fraction of the gap (≈0.15–0.9). Higher = it eases IN more gradually onto the target tangent (a longer, gentler touchdown). Split from flightLaunch so take-off and landing can breathe independently.
final
flightLaunch double
Launch breathing — the quintic launch-velocity as a fraction of the head→entry gap (≈0.15–0.9). Higher = the flight eases OUT more gradually off the source tangent (a longer, gentler take-off runway).
final
flightRunway double
Runway — a STRAIGHT breathing segment (viewBox units, e.g. ~20 at a 24 viewBox) along the tangent at EACH end before the curve is allowed to bend. The launch leaves dead-straight for this far, then curves; the landing arrives dead-straight for the last stretch. 0 = the curve bends immediately off the tangent (no straight runway). Clamped to ≤ 45% of the head→entry gap.
final
flipSource bool
Reverse the resolved SOURCE hero line (swap its head/tail) AFTER the default "head on the right" orientation — so the worm launches from the other end of the source line. Use per-direction when the default end reads wrong.
final
flipStagger double
Per-contour flip-in delay (auto-normalized to the contour count).
final
flipStart double
When the target's non-hero contours start flipping in (0..1).
final
flipTarget bool
Reverse the resolved TARGET hero line (swap entry/head) AFTER the default "entry on the left" orientation — so the worm lands lying the other way.
final
hashCode int
The hash code for this object.
no setteroverride
headFade double
Window 0..headFade over which the source's non-hero contours LEAVE as the morph runs — it caps whichever exit choreography is active (un-draw, fade, or shrink), NOT just a fade. Default 0.45; the trim un-draw then caps at 0.35 and fade/scale at 0.18, so a smaller headFade tightens the active exit.
final
headLead double
How much the worm's head leads its tail in time (>1). 1 = head and tail move together (it slides rigidly); higher = the head launches ahead and the tail catches up, so the worm stretches out over the flight and draws the target on as the tail lands.
final
heroAnchor Offset?
Viewbox-space point used to pick the hero TARGET contour: the contour whose centroid is nearest this anchor becomes the morph's destination line — e.g. Offset(12, 16) for a mouth. Order-independent, so it's the robust selector.
final
heroTargetIndex int?
Explicit hero target contour index — wins over heroAnchor when set.
final
perspective double
3D perspective strength for the flip-in (used only when assemble is MorphAssemble.flip3d; see Projector3D).
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
samples int
Points the hero source + target lines are each resampled to. More = a smoother morph at a little more cost. >= 2.
final
sourceAnchor Offset?
Viewbox-space point used to pick the hero SOURCE contour — the line that morphs into the target. Defaults to the glyph's lower edge Offset(12, 20), e.g. the user's shoulders arc.
final
sourceIndex int?
Explicit hero source contour index — wins over sourceAnchor when set.
final
taperFloor double
Ink floor (0..1) — how thin a taper may ever take the stroke, at either end. Default 1: stroke weight is never touched.
final

Methods

copyWith({Duration? duration, Curve? curve, int? samples, Offset? heroAnchor, int? heroTargetIndex, Offset? sourceAnchor, int? sourceIndex, double? flightLaunch, double? flightLand, double? flightBow, double? flightBias, double? flightRunway, double? headLead, double? headFade, double? flipStart, double? flipStagger, double? exitTaper, double? exitFade, double? assembleFade, double? taperFloor, double? assembleTaper, double? perspective, MorphAssemble? assemble, MorphExit? exit, bool? flipSource, bool? flipTarget}) IconMorphPlan
Returns a copy with selected fields overridden. Useful for tuning a base plan without mutating it — e.g. a slider can override flightBow while keeping all other fields from the original.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
resolveHeroTarget(List<IconContour> targets) int
Which target contour the source morphs INTO.
resolveSource(List<IconContour> sources) int
Which source contour is the one that morphs (the rest fade out).
toString() String
A string representation of this object.
inherited

Operators

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