Documentation Index
Fetch the complete documentation index at: https://mintlify.com/danielitoCode/Spatial/llms.txt
Use this file to discover all available pages before exploring further.
CameraState is a @Stable Compose state holder that represents an orbit camera. Its observable properties — yaw, pitch, and zoom — are backed by Compose mutableStateOf / mutableFloatStateOf and trigger recomposition in any composable that reads them. Under the hood, CameraState delegates to a SpatialCamera runtime and a ComposeFrameCameraAnimationScheduler that hooks into the Compose frame clock for smooth, frame-synchronised animation. You should never instantiate CameraState directly; always use rememberCameraState().
Import
Factory Function
CameraState instance that survives recomposition. Pass initial values to set the starting orientation of the orbit camera.
Initial horizontal orbit angle around the scene’s Y axis.
0f.deg positions the camera looking straight down the −Z axis. Use the deg extension property from spatial-units (e.g. 90f.deg).Initial vertical tilt of the orbit camera. Clamped to the safe range
[−89°, 89°] to prevent gimbal flip. Negative values tilt the camera downward (looking down into a scene).Initial visual magnification factor.
1.0 is the default field of view. Values above 1.0 zoom in (objects appear larger); values below 1.0 zoom out. Clamped to [0.3, 4.0].Observable Properties
All properties below are backed by Compose state and will trigger recomposition in any composable that reads them.| Property | Type | Description |
|---|---|---|
yaw | Angle | Current horizontal orbit angle. Read-only from the outside; mutated by orbit and animate calls. |
pitch | Angle | Current vertical tilt. Clamped to [−89°, 89°]. |
zoom | Float | Current visual magnification factor. Clamped to [0.3, 4.0]. |
version | Long | Monotonically increasing counter incremented on every mutation. Useful for triggering effects that need to react to any camera change. |
source | CameraUpdateSource | Origin of the most recent update: Gesture, Remote, or Animation. |
CameraUpdateSource
CameraUpdateSource is an enum that identifies who last updated the camera. Values in source-precedence order (highest to lowest when the same frame/version has a conflict):
Methods
orbitTo
yaw and pitch default to the current values, so you can change only one axis if you wish.
orbitBy
GestureMotionPolicy.Raw (no inertia). Positive deltaYawDegrees rotates the camera to the right; positive deltaPitchDegrees tilts it upward. Typically called from a custom gesture handler.
zoomTo
[0.3, 4.0] before being applied.
zoomBy
scaleDelta greater than 1f zooms in (objects appear closer/larger); a value less than 1f zooms out. The result is clamped to the safe zoom range.
jumpTo
syncSnapshot
CameraState from an externally obtained CameraSnapshot. Useful when driving the camera from a remote data source or replaying a recorded session.
animateTo
suspend function and must be called from a coroutine (typically launched from rememberCoroutineScope()). The animation uses the Compose frame clock for smooth, lifecycle-aware updates.
Target horizontal orbit angle. Defaults to the current yaw so you can animate only one axis at a time. The planner automatically takes the shortest angular path.
Target vertical tilt. Clamped to the safe range
[−89°, 89°] before the animation starts.Target zoom level. Clamped to
[0.3, 4.0] before the animation starts.Optional explicit animation duration in milliseconds. When
null, the duration is derived adaptively from the angular and zoom distance to travel using the MotionSpec planner. Pass an explicit value to override the adaptive calculation.Animation profile controlling duration bounds, easing, and velocity. Defaults to
MotionSpec.Adaptive. Pass MotionSpec.Instant for an immediate jump, or MotionSpec.custom(...) to tune the velocity and duration range.snapshot
CameraSnapshot capturing the current yaw, pitch, zoom, version, and source. The snapshot is safe to read off the main thread or to pass to other modules.
Example
CameraState is annotated @Stable so Compose can skip recomposition of composables that receive it as a parameter when its reference has not changed. Only the individual state-backed properties (yaw, pitch, zoom, version) trigger recomposition in composables that read them.