MorphSkin class
A group of pieces with one shared "skin": the smooth union of their SDFs traced into a single Path behind live content. Nearby pieces fuse with a concave fillet on their own; the blend width comes from style or an explicit blend (low - a geometric joint, high - a gooey neck).
"One mass - one shadow": elevation is drawn as a single shadow of the unified contour, so pieces cannot visually split into layers.
The flight neck comes for free: the group finds flights launched in the MorphScope under its piece ids (including a declarative MorphAnchor with an explicit tagId) and plays the airborne blob under the shuttle, bridge detachment, and the landing squash of the skin by itself. Outside a MorphScope the group degrades to pure fusion.
Implemented as a render object: spring ticks mark paint only - no widget rebuild, no relayout participates in an animation frame. App-driven geometry gets the same citizenship through MorphPieceChannel: a channel write repaints and re-traces without touching the widget tree. The landing squash (and the channel delta) is a paint transform of the content, mirroring the skin's mass deformation. The group is its own repaint boundary, so an animating skin never repaints its ancestors.
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatelessWidget
- MorphSkin
Constructors
-
MorphSkin({Key? key, required List<
MorphPiece> pieces, List<MorphLink> links = const <MorphLink>[], List<MorphMass> extraMasses = const <MorphMass>[], MorphSkinStyle? style, double? blend, double? cell, int? smoothPasses, int? evalBudget = defaultEvalBudget, required Color color, Gradient? gradient, double elevation = 0, Color? shadowColor, Clip clipBehavior = .none}) -
Creates a skin over
pieces, optionally bridged bylinks.const
Properties
- blend → double?
-
Blend width in pixels. A distance, not a fraction: at a different
scene scale it scales along with the scene.
final
- cell → double?
-
Marching-squares grid step in pixels: smaller - crisper and more
expensive.
final
- clipBehavior → Clip
-
The skin bulges past the piece bounds by up to ~k; not clipped by
default.
final
- color → Color
-
Fill color of the skin; also the surface color that shuttles of
morphable pieces take off from.
final
- elevation → double
-
Shadow of the unified contour: one mass, one shadow.
final
- evalBudget → int?
-
Cap on field evaluations per cluster per trace (default
defaultEvalBudget): extreme scenes coarsen their grid so the
worst frame stays bounded - quality degrades before the frame
rate does. null disables the cap.
final
-
extraMasses
→ List<
MorphMass> -
Extra contentless mass: raw SDF masses poured into the skin
alongside the pieces.
final
- gradient → Gradient?
-
Optional skin fill gradient, shaded across the group bounds; when
set it wins over color for the fill (the color still names the
surface for morph shuttles of morphable pieces).
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
-
links
→ List<
MorphLink> -
Explicit bridges between distant pieces.
final
-
pieces
→ List<
MorphPiece> -
The pieces sharing this skin; ids must be unique.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- shadowColor → Color?
-
Color of the elevation shadow, opacity included; null resolves
MorphTheme.shadowColor, then 60% black - the same builtin
flights use, so a launch out of a piece keeps its shadow tint
with no theme installed.
final
- smoothPasses → int?
-
Chaikin smoothing passes over the traced contour.
final
- style → MorphSkinStyle?
-
A ready-made knob bundle; explicit blend/cell/smoothPasses
win over it. null falls back to MorphTheme.skinStyle, then to
blend 24 / cell 6 / smoothPasses 2.
final
Methods
-
build(
BuildContext context) → Widget -
Describes the part of the user interface represented by this widget.
override
-
createElement(
) → StatelessElement -
Creates a StatelessElement to manage this widget's location in the tree.
inherited
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Constants
- defaultEvalBudget → const int
- The default evalBudget: the cap on field evaluations (grid vertices x shapes) per cluster per trace. A deterministic function of geometry - no time, no hysteresis; the same scene always traces identically.