Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt

Use this file to discover all available pages before exploring further.

visualEffect applies geometry-driven transforms — opacity, offset, scale, blur, rotation — that update as a component’s position or size changes, ideal for parallax and scroll-driven UI. coordinateSpace registers a named frame of reference that visualEffect and GeometryReader can resolve positions against. Effects applied through visualEffect are purely visual and do not affect layout. Pair coordinateSpace on a ScrollView with visualEffect on its descendants to drive effects from scroll position.

visualEffect

Applies geometry-aware visual effects using a builder pattern.
.visualEffect(callback: (builder: VisualEffectBuilder, proxy: GeometryProxy) => VisualEffectBuilder): Component
callback
(builder: VisualEffectBuilder, proxy: GeometryProxy) => VisualEffectBuilder
required
A function that receives a VisualEffectBuilder and a GeometryProxy, and returns the builder with effects chained onto it. The proxy provides layout information (size, position, safe area insets) that can drive the effect values.
Scroll-driven opacity Fade a component based on its position within a scroll view.
Text("Fading text")
    .visualEffect((builder, proxy) =>
        builder.opacity(
            proxy.frame("scrollView").minY > 0 ? 1 : 0.3
        )
    )
Parallax effect
Image({ url: "banner.jpg" })
    .resizable()
    .scaledToFill()
    .frame({ height: 300 })
    .clipped()
    .visualEffect((builder, proxy) =>
        builder.offset({
            x: 0,
            y: proxy.frame("scrollView").minY * 0.5
        })
    )
Scale and blur on scroll
Text("Hero Title")
    .font("largeTitle")
    .visualEffect((builder, proxy) => {
        const scrollY = proxy.frame("scrollView").minY
        return builder
            .scale(scrollY > 0 ? 1 + scrollY / 500 : 1)
            .blur(scrollY < 0 ? -scrollY / 10 : 0)
    })
Size-based rotation
Rectangle()
    .frame({ width: 100, height: 100 })
    .foregroundStyle(Color("blue"))
    .visualEffect((builder, proxy) =>
        builder.rotation(proxy.size.width > 100 ? 45 : 0)
    )
The callback is re-evaluated whenever the component’s geometry changes (e.g., during scrolling or resizing). Effects applied through the builder do not affect the component’s layout — they are purely visual transforms. Use coordinateSpace on a parent to create named coordinate spaces that can be referenced in proxy.frame().

coordinateSpace

Assigns a named coordinate space to a component for geometry calculations.
.coordinateSpace(name: string)
name
string
required
A unique name for this coordinate space. Other components can reference this name in GeometryProxy.frame() to get their position relative to this component.
Named scroll view coordinate space
ScrollView([
    VStack(items.map((item) =>
        Text(item.name)
            .visualEffect((builder, proxy) =>
                builder.opacity(
                    proxy.frame("scroll").minY > 0 ? 1 : 0.3
                )
            )
    ))
])
    .coordinateSpace("scroll")
Track position relative to a container
VStack([
    GeometryReader((proxy) =>
        Text("Y: " + String(proxy.frame("container").minY))
    )
])
    .coordinateSpace("container")

See also

  • offset — translate a component without affecting layout
  • scaleEffect — static scaling without geometry feedback
  • rotationEffect — static rotation
  • blur — apply a Gaussian blur
  • opacity — set transparency