GlassUnion class Composition

Draws every GlassSurface below it as one piece of glass, however far apart they are.

SwiftUI's glassEffectUnion. It is a type of its own rather than GlassGroup(spacing: infinity) because infinity is not a value the fused draw can take. The quad it shades is the members' union grown by delta(n) * k, so an infinite k is an infinite quad; and the fold's skip, a quarter of a twelve-shape group's cost on Adreno and 44% of it on Xclipse, fires when a shape is farther than k from the field so far, so an infinite k never skips anything. A union declared that way would shade every pixel on the screen at full price.

So the union solves for k instead of taking it: the smallest radius that connects the members that are there, which is twice the longest edge of their minimum spanning tree (unionBlendRadius). Finite, minimal for the picture asked for, and usually smaller than the spacing somebody would have declared to be safe — a spacing costs the quad and nothing else (the fragment is the same to within 0.4% at spacing 0 and 8), so the difference between a solved k and a guessed one is paid in area.

Two visible consequences:

  • k smooths the whole fold, not just the bridges, so a union spread over a distance is a puffier silhouette than the same shapes near each other — the members swell by up to k / 4 of field. That is what "one piece of glass" looks like at distance, and it is the reason this is a declaration rather than a default.
  • k is a function of where the members are, so moving one member changes the shape of all of them, continuously. A declared spacing is the other trade: a member that drifts out of range breaks its bridge and leaves everything else alone.

No GlassId. Apple needs one because glassEffectUnion(id:namespace:) is a modifier on each view, with no common ancestor to group by, so the identity has to be written down. Here the ancestor is the namespace: membership is position in the tree, the nearest GlassGroupScope wins, and a union nested inside a group partitions it — the inner surfaces fuse with each other and the outer ones with each other. Two unions are two widgets. An id would be a second way to say what the tree already says, and the thing Apple's id does that position cannot — carrying a shape's identity across an appearance so the glass morphs between them — is not supported. The half that needs no identity is: a member that appears or leaves inside a group buds out of its neighbours through GlassSurface.presence, which is a field offset and exact at zero.

GlassUnion(
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: <Widget>[
      GlassButton(onPressed: back, child: const Icon(Icons.arrow_back)),
      GlassButton(onPressed: share, child: const Icon(Icons.ios_share)),
    ],
  ),
)

See also:

Inheritance

Constructors

GlassUnion({required Widget child, GlassFinish? finish, bool labelled = true, Key? key})
Draws every GlassSurface in child as one connected piece of glass.
const

Properties

child → Widget
The subtree whose surfaces are the members. Painted over the fused glass.
final
finish → GlassFinish?
The optics for the whole union. Null takes the host's.
final
hashCode → int
The hash code for this object.
no setterinherited
key → Key?
Controls how one widget replaces another widget in the tree.
finalinherited
labelled → bool
See GlassGroup.labelled.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

createElement() → StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() → State<GlassUnion>
Creates the mutable state for this widget at a given location in the tree.
override
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