# androidx.compose.foundation.gestures

Common/AllAndroid/JVM

In this page, you'll find documentation for types, properties, and functions available in the `androidx.compose.foundation.gestures` package. For example:

- Drag APIs such as `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/draggable.modifier#(androidx.compose.ui.Modifier).draggable(androidx.compose.foundation.gestures.DraggableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Boolean,kotlin.coroutines.SuspendFunction2,kotlin.coroutines.SuspendFunction2,kotlin.Boolean)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)`, and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberDraggableState.composable#rememberDraggableState(kotlin.Function1)`.

- Scroll APIs such as `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).animateScrollBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/scrollable.modifier#(androidx.compose.ui.Modifier).scrollable(androidx.compose.foundation.gestures.ScrollableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,kotlin.Boolean,androidx.compose.foundation.gestures.FlingBehavior,androidx.compose.foundation.interaction.MutableInteractionSource)`, and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberScrollableState.composable#rememberScrollableState(kotlin.Function1)`.

- And other gestures APIs such as `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateZoomBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateRotateBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)`.

If you're looking for guidance instead, check out the [Gestures in Compose guide](https://developer.android.com/jetpack/compose/gestures).

## Interfaces

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDragScope` | Scope used for suspending anchored drag blocks. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/BringIntoViewSpec` | The configuration of how a scrollable reacts to bring into view requests. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Drag2DScope` | Scope used for suspending drag blocks | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DragScope` | Scope used for suspending drag blocks | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Draggable2DState` | State of Draggable2D. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchors` | Structure that represents the anchors of a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState`. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableState` | State of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/draggable.modifier#(androidx.compose.ui.Modifier).draggable(androidx.compose.foundation.gestures.DraggableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Boolean,kotlin.coroutines.SuspendFunction2,kotlin.coroutines.SuspendFunction2,kotlin.Boolean)`. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/FlingBehavior` | Interface to specify fling behavior. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/PressGestureScope` | Receiver scope for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`'s `onPress` lambda. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Scroll2DScope` | Scope used for suspending scroll blocks | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollScope` | Scope used for suspending scroll blocks | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Scrollable2DState` |   | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` | An object representing something that can be scrolled. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TargetedFlingBehavior` | Interface to specify fling behavior with additional information about its animation target. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformScope` | Scope used for suspending transformation operations. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState` | State of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/transformable.modifier#(androidx.compose.ui.Modifier).transformable(androidx.compose.foundation.gestures.TransformableState,kotlin.Boolean,kotlin.Boolean)`. | Cmn |

## Classes

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState` | State of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/anchoredDraggable.modifier#(androidx.compose.ui.Modifier).anchoredDraggable(androidx.compose.foundation.gestures.AnchoredDraggableState,kotlin.Boolean,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.foundation.OverscrollEffect,androidx.compose.foundation.gestures.FlingBehavior)` modifier. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsConfig` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsConfig` stores a mutable configuration anchors, comprised of values of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsConfig` and corresponding `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` positions. | Cmn |

## Exceptions

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/GestureCancellationException` | A gesture was canceled and cannot continue, likely because another gesture has taken over the pointer input stream. | Cmn |

## Objects

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableDefaults` | Contains useful defaults for use with `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState` and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/anchoredDraggable.modifier#(androidx.compose.ui.Modifier).anchoredDraggable(androidx.compose.foundation.gestures.AnchoredDraggableState,kotlin.Boolean,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.foundation.OverscrollEffect,androidx.compose.foundation.gestures.FlingBehavior)` | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableDefaults` | Contains the default values used by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/scrollable.modifier#(androidx.compose.ui.Modifier).scrollable(androidx.compose.foundation.gestures.ScrollableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,kotlin.Boolean,androidx.compose.foundation.gestures.FlingBehavior,androidx.compose.foundation.interaction.MutableInteractionSource)` | Cmn |

## Enums

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Orientation` | Class to define possible directions in which common gesture modifiers like `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/draggable.modifier#(androidx.compose.ui.Modifier).draggable(androidx.compose.foundation.gestures.DraggableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Boolean,kotlin.coroutines.SuspendFunction2,kotlin.coroutines.SuspendFunction2,kotlin.Boolean)` and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/scrollable.modifier#(androidx.compose.ui.Modifier).scrollable(androidx.compose.foundation.gestures.ScrollableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,kotlin.Boolean,androidx.compose.foundation.gestures.FlingBehavior,androidx.compose.foundation.interaction.MutableInteractionSource)` can drag. | Cmn |

## Composables

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberDraggable2DState.composable` | Create and remember default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Draggable2DState` interface that allows to pass a simple action that will be invoked when the drag occurs. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberDraggableState.composable` | Create and remember default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableState` interface that allows to pass a simple action that will be invoked when the drag occurs. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberScrollable2DState.composable` | Create and remember the default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Scrollable2DState` interface that contains necessary information about the ongoing fling and provides smooth scrolling capabilities. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberScrollableState.composable` | Create and remember the default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` interface that contains necessary information about the ongoing fling and provides smooth scrolling capabilities. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberTransformableState.composable` | Create and remember default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState` interface that contains necessary information about the ongoing transformations and provides smooth transformation capabilities. | Cmn |

## Modifiers

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/anchoredDraggable.modifier` | Enable drag gestures between a set of predefined values. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/draggable.modifier` | Configure touch dragging for the UI element in a single `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Orientation`. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/draggable2D.modifier` | Configure touch dragging for the UI element in both orientations. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/scrollable.modifier` | Configure touch scrolling and flinging for the UI element in a single `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Orientation`. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/scrollable2D.modifier` | Configure touch scrolling and flinging for the UI element in both XY orientations. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/transformable.modifier` | Enable transformation gestures of the modified UI element. | Cmn |

## Top-level functions summary

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState<T>` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> [AnchoredDraggableState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#AnchoredDraggableState(kotlin.Any,kotlin.Function1,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec,kotlin.Function1))( initialValue: T, positionalThreshold: (totalDistance: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, velocityThreshold: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, snapAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, decayAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/DecayAnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, confirmValueChange: (newValue) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` **This function is deprecated.** This constructor of AnchoredDraggableState has been deprecated. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState<T>` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> [AnchoredDraggableState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#AnchoredDraggableState(kotlin.Any,androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Function1,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec,kotlin.Function1))( initialValue: T, anchors: https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchors<T>, positionalThreshold: (totalDistance: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, velocityThreshold: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, snapAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, decayAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/DecayAnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, confirmValueChange: (newValue) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` **This function is deprecated.** This constructor of AnchoredDraggableState has been deprecated. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Draggable2DState` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Draggable2DState(kotlin.Function1)(onDelta: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)` Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Draggable2DState(kotlin.Function1)` interface that allows to pass a simple action that will be invoked when the drag occurs. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchors<T>` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html> https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableAnchors(kotlin.Function1)(builder: https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsConfig<T>.() -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)` Create a new `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableAnchors(kotlin.Function1)` instance using a builder function. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableState` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableState(kotlin.Function1)(onDelta: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)` Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableState(kotlin.Function1)` interface that allows to pass a simple action that will be invoked when the drag occurs. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Scrollable2DState` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Scrollable2DState(kotlin.Function1)(consumeScrollDelta: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset)` Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Scrollable2DState(kotlin.Function1)` interface that contains necessary information about the ongoing fling and provides smooth scrolling capabilities. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#ScrollableState(kotlin.Function1)(consumeScrollDelta: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html)` Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#ScrollableState(kotlin.Function1)` interface that contains necessary information about the ongoing fling and provides smooth scrolling capabilities. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState` | `[TransformableState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function3))( onTransformation: (zoomChange: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, panChange: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, rotationChange: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` **This function is deprecated.** Prefer creating TransformableState with a onTransformation lambda that takes the centroid. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function4)( onTransformation: (centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, zoomChange: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, panChange: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, rotationChange: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function4)` interface that contains necessary information about the ongoing transformations and provides smooth transformation capabilities. | Cmn |

## Extension functions summary

|---|---|---|
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateBy(kotlin.Float,androidx.compose.ui.geometry.Offset,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)( zoomFactor: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, panOffset: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, rotationDegrees: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, zoomAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, panAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset>, rotationAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset )` Animate zoom, pan, and rotation simultaneously and suspend until the animation is finished. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animatePanBy(androidx.compose.ui.geometry.Offset,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)( offset: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset>, centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset )` Animate pan by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animatePanBy(androidx.compose.ui.geometry.Offset,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` Offset in pixels and suspend until its finished | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateRotateBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)( degrees: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset )` Animate rotate by a ratio of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateRotateBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` clockwise and suspend until its finished. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).animateScrollBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec)( value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> )` Scroll by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).animateScrollBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec)` pixels with animation. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Scrollable2DState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.Scrollable2DState).animateScrollBy(androidx.compose.ui.geometry.Offset,androidx.compose.animation.core.AnimationSpec)( value: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset> )` Scroll by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.Scrollable2DState).animateScrollBy(androidx.compose.ui.geometry.Offset,androidx.compose.animation.core.AnimationSpec)` pixels with animation. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState<T>.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateTo(kotlin.Any,androidx.compose.animation.core.AnimationSpec)( targetValue: T, animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> )` Animate to a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateTo(kotlin.Any,androidx.compose.animation.core.AnimationSpec)`. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState<T>.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)( targetValue: T, velocity: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, snapAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, decayAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/DecayAnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> )` Attempt to animate using decay Animation to a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)`. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateZoomBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)( zoomFactor: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>, centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset )` Animate zoom by a ratio of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateZoomBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` over the current size and suspend until its finished. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)(pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId)` Reads pointer input events until a drag is detected or all pointers are up. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).awaitEachGesture(kotlin.coroutines.SuspendFunction1)(block: suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.() -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)` Repeatedly calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).awaitEachGesture(kotlin.coroutines.SuspendFunction1)` to handle gestures. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitFirstDown(kotlin.Boolean,androidx.compose.ui.input.pointer.PointerEventPass)( requireUnconsumed: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html, pass: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEventPass )` Reads events until the first down is received in the given `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitFirstDown(kotlin.Boolean,androidx.compose.ui.input.pointer.PointerEventPass)`. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId )` Reads pointer input events until a horizontal drag is detected or all pointers are up. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId, pointerType: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerType, onPointerSlopReached: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, overSlop: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Waits for horizontal drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)`'s touch slop, using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` as the pointer to examine. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId, onTouchSlopReached: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, overSlop: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Waits for horizontal drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()`, using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` as the pointer to examine. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitLongPressOrCancellation(androidx.compose.ui.input.pointer.PointerId)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId )` Waits for a long press by examining `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitLongPressOrCancellation(androidx.compose.ui.input.pointer.PointerId)`. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId, onTouchSlopReached: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, overSlop: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Waits for drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()`, using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` as the pointer to examine. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId )` Reads pointer input events until a vertical drag is detected or all pointers are up. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId, pointerType: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerType, onPointerSlopReached: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, overSlop: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Waits for vertical drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)`'s touch slop using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` as the pointer to examine. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId, onTouchSlopReached: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, overSlop: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Waits for vertical drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()`, using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` as the pointer to examine. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEvent.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerEvent).calculateCentroid(kotlin.Boolean)(useCurrent: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html)` Returns the centroid of all pointers that are down and were previously down. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEvent.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerEvent).calculateCentroidSize(kotlin.Boolean)(useCurrent: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html)` Returns the average distance from the centroid for all pointers that are currently and were previously down. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEvent.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerEvent).calculatePan()()` Returns the change in the centroid location between the previous and the current pointers that are down. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEvent.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerEvent).calculateRotation()()` Returns the rotation, in degrees, of the pointers between the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#previousPosition()` and `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#position()` states. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEvent.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerEvent).calculateZoom()()` Uses the change of the centroid size between the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#previousPosition()` and `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#position()` to determine how much zoom was intended. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)( onDragStart: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragEnd: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragCancel: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDrag: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, dragAmount: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Gesture detector that waits for pointer down and touch slop in any direction and then calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each drag event. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)( orientationLock: https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Orientation?, onDragStart: (down: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, slopTriggerChange: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, overSlopOffset: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragEnd: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragCancel: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, shouldAwaitTouchSlop: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html, onDrag: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, dragAmount: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` A Gesture detector that waits for pointer down and touch slop in the direction specified by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` and then calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each drag event. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGesturesAfterLongPress(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)( onDragStart: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragEnd: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragCancel: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDrag: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, dragAmount: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Gesture detector that waits for pointer down and long press, after which it calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGesturesAfterLongPress(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each drag event. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)( onDragStart: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragEnd: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragCancel: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onHorizontalDrag: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, dragAmount: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Gesture detector that waits for pointer down and touch slop in the horizontal direction and then calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each horizontal drag event. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)( onDoubleTap: ((https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)?, onLongPress: ((https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)?, onPress: suspend https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/PressGestureScope.(https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onTap: ((https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)? )` Detects tap, double-tap, and long press gestures and calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, respectively, when detected. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTransformGestures(kotlin.Boolean,kotlin.Function4)( panZoomLock: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html, onGesture: (centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, pan: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, zoom: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, rotation: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` A gesture detector for rotation, panning, and zoom. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)( onDragStart: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragEnd: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onDragCancel: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onVerticalDrag: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, dragAmount: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Gesture detector that waits for pointer down and touch slop in the vertical direction and then calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each vertical drag event. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId, onDrag: (https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Reads position change events for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` and calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` for every change in position. | Cmn |
| `inline https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchors<T>.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.DraggableAnchors).forEach(kotlin.Function2)(block: (key, position: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)` Iterate over all the anchors. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.[forEachGesture](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).forEachGesture(kotlin.coroutines.SuspendFunction1))(block: suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope.() -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)` **This function is deprecated.** Use awaitEachGesture instead. forEachGesture() can drop events between gestures. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId, onDrag: (https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Reads horizontal position change events for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` and calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` for every change in position. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).panBy(androidx.compose.ui.geometry.Offset,androidx.compose.ui.geometry.Offset)(offset: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset)` Pan without animation by a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).panBy(androidx.compose.ui.geometry.Offset,androidx.compose.ui.geometry.Offset)` Offset in pixels and suspend until it's set. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).rotateBy(kotlin.Float,androidx.compose.ui.geometry.Offset)(degrees: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset)` Rotate without animation by a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).rotateBy(kotlin.Float,androidx.compose.ui.geometry.Offset)` degrees and suspend until it's set. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).scrollBy(kotlin.Float)(value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html)` Jump instantly by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).scrollBy(kotlin.Float)` pixels. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Scrollable2DState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.Scrollable2DState).scrollBy(androidx.compose.ui.geometry.Offset)(value: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset)` Jump instantly by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.Scrollable2DState).scrollBy(androidx.compose.ui.geometry.Offset)` pixels. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState<T>.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).snapTo(kotlin.Any)(targetValue: T)` Snap to a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).snapTo(kotlin.Any)` without any animation. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).stopScroll(androidx.compose.foundation.MutatePriority)(scrollPriority: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MutatePriority)` Stop and suspend until any ongoing animation, smooth scrolling, fling, or any other scroll occurring via `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` is terminated. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Scrollable2DState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.Scrollable2DState).stopScroll(androidx.compose.foundation.MutatePriority)(scrollPriority: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MutatePriority)` Stop and suspend until any ongoing animation, smooth scrolling, fling, or any other scroll occurring via `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` is terminated. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).stopTransformation(androidx.compose.foundation.MutatePriority)( terminationPriority: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MutatePriority )` Stop and suspend until any ongoing `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState#transform(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` with priority `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).stopTransformation(androidx.compose.foundation.MutatePriority)` or lower is terminated. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)( pointerId: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId, onDrag: (https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` Reads vertical position change events for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` and calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` for every change in position. | Cmn |
| `suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).waitForUpOrCancellation(androidx.compose.ui.input.pointer.PointerEventPass)(pass: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEventPass)` Reads events in the given `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).waitForUpOrCancellation(androidx.compose.ui.input.pointer.PointerEventPass)` until all pointers are up or the gesture was canceled. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState.https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).zoomBy(kotlin.Float,androidx.compose.ui.geometry.Offset)(zoomFactor: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset)` Zoom without animation by a ratio of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).zoomBy(kotlin.Float,androidx.compose.ui.geometry.Offset)` over the current size and suspend until it's set. | Cmn |

## Top-level properties summary

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/runtime/ProvidableCompositionLocal<https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/BringIntoViewSpec>` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#LocalBringIntoViewSpec()` A composition local to customize the focus scrolling behavior used by some scrollable containers. | Cmn android |

## Top-level functions

### AnchoredDraggableState

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/AnchoredDraggable.kt+function:AnchoredDraggableState) Added in [1.8.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.8.0) Deprecated in [1.8.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.8.0)

```
fun <T : Any?> [AnchoredDraggableState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#AnchoredDraggableState(kotlin.Any,kotlin.Function1,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec,kotlin.Function1))(
    initialValue: T,
    positionalThreshold: (totalDistance: Float) -> Float,
    velocityThreshold: () -> Float,
    snapAnimationSpec: AnimationSpec<Float>,
    decayAnimationSpec: DecayAnimationSpec<Float>,
    confirmValueChange: (newValue) -> Boolean = { true }
): AnchoredDraggableState<T>
```

> [!CAUTION]
> **This function is deprecated.**   
> This constructor of AnchoredDraggableState has been deprecated. Please pass thresholds and animation specs to AnchoredDraggableDefaults.flingBehavior(..) instead, which can be passed to Modifier.anchoredDraggable.

State of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/anchoredDraggable.modifier#(androidx.compose.ui.Modifier).anchoredDraggable(androidx.compose.foundation.gestures.AnchoredDraggableState,kotlin.Boolean,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.foundation.OverscrollEffect,androidx.compose.foundation.gestures.FlingBehavior)` modifier. Use the constructor overload with anchors if the anchors are defined in composition, or update the anchors using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#updateAnchors(androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Any)`.

This contains necessary information about any ongoing drag or animation and provides methods to change the state either immediately or by starting an animation.

| Parameters |
|---|---|
| `initialValue: T` | The initial value of the state. |
| `positionalThreshold: (totalDistance: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | The positional threshold, in px, to be used when calculating the target state while a drag is in progress and when settling after the drag ends. This is the distance from the start of a transition. It will be, depending on the direction of the interaction, added or subtracted from/to the origin offset. It should always be a positive value. |
| `velocityThreshold: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | The velocity threshold (in px per second) that the end velocity has to exceed in order to animate to the next state, even if the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#AnchoredDraggableState(kotlin.Any,kotlin.Function1,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec,kotlin.Function1)` has not been reached. |
| `confirmValueChange: (newValue) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = { true }` | Optional callback invoked to confirm or veto a pending state change. |

### AnchoredDraggableState

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/AnchoredDraggable.kt+function:AnchoredDraggableState) Added in [1.8.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.8.0) Deprecated in [1.8.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.8.0)

```
fun <T : Any?> [AnchoredDraggableState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#AnchoredDraggableState(kotlin.Any,androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Function1,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec,kotlin.Function1))(
    initialValue: T,
    anchors: DraggableAnchors<T>,
    positionalThreshold: (totalDistance: Float) -> Float,
    velocityThreshold: () -> Float,
    snapAnimationSpec: AnimationSpec<Float>,
    decayAnimationSpec: DecayAnimationSpec<Float>,
    confirmValueChange: (newValue) -> Boolean = { true }
): AnchoredDraggableState<T>
```

> [!CAUTION]
> **This function is deprecated.**   
> This constructor of AnchoredDraggableState has been deprecated. Please pass thresholds and animation specs to AnchoredDraggableDefaults.flingBehavior(..) instead, which can be passed to Modifier.anchoredDraggable.

Construct an `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#AnchoredDraggableState(kotlin.Any,androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Function1,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec,kotlin.Function1)` instance with anchors.

| Parameters |
|---|---|
| `initialValue: T` | The initial value of the state. |
| `anchors: https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchors<T>` | The anchors of the state. Use `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#updateAnchors(androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Any)` to update the anchors later. |
| `positionalThreshold: (totalDistance: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | The positional threshold, in px, to be used when calculating the target state while a drag is in progress and when settling after the drag ends. This is the distance from the start of a transition. It will be, depending on the direction of the interaction, added or subtracted from/to the origin offset. It should always be a positive value. |
| `velocityThreshold: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | The velocity threshold (in px per second) that the end velocity has to exceed in order to animate to the next state, even if the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#AnchoredDraggableState(kotlin.Any,androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Function1,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec,kotlin.Function1)` has not been reached. |
| `snapAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>` | The default animation spec that will be used to animate to a new state. |
| `decayAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/DecayAnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>` | The animation spec that will be used when flinging with a large enough velocity to reach or cross the target state. |
| `confirmValueChange: (newValue) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = { true }` | Optional callback invoked to confirm or veto a pending state change. |

### Draggable2DState

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/Draggable2D.kt+function:Draggable2DState) Added in [1.6.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.6.0)

```
fun Draggable2DState(onDelta: (Offset) -> Unit): Draggable2DState
```

Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Draggable2DState(kotlin.Function1)` interface that allows to pass a simple action that will be invoked when the drag occurs.

This is the simplest way to set up a draggable2D modifier. When constructing this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Draggable2DState(kotlin.Function1)`, you must provide a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Draggable2DState(kotlin.Function1)` lambda, which will be invoked whenever drag happens (by gesture input or a custom `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Draggable2DState#drag(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` call) with the delta in pixels.

If you are creating `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Draggable2DState(kotlin.Function1)` in composition, consider using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberDraggable2DState.composable#rememberDraggable2DState(kotlin.Function1)`.

| Parameters |
|---|---|
| `onDelta: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | callback invoked when drag occurs. The callback receives the delta in pixels. |

### DraggableAnchors

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/AnchoredDraggable.kt+function:DraggableAnchors) Added in [1.6.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.6.0)

```
fun <T : Any> DraggableAnchors(builder: DraggableAnchorsConfig<T>.() -> Unit): DraggableAnchors<T>
```

Create a new `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableAnchors(kotlin.Function1)` instance using a builder function.

| Parameters |
|---|---|
| `builder: https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsConfig<T>.() -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | A function with a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsConfig` that offers APIs to configure anchors |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchors<T>` | A new `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableAnchors(kotlin.Function1)` instance with the anchor positions set by the `builder` function. |

### DraggableState

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/Draggable.kt+function:DraggableState) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
fun DraggableState(onDelta: (Float) -> Unit): DraggableState
```

Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableState(kotlin.Function1)` interface that allows to pass a simple action that will be invoked when the drag occurs.

This is the simplest way to set up a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/draggable.modifier#(androidx.compose.ui.Modifier).draggable(androidx.compose.foundation.gestures.DraggableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Boolean,kotlin.coroutines.SuspendFunction2,kotlin.coroutines.SuspendFunction2,kotlin.Boolean)` modifier. When constructing this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableState(kotlin.Function1)`, you must provide a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableState(kotlin.Function1)` lambda, which will be invoked whenever drag happens (by gesture input or a custom `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableState#drag(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` call) with the delta in pixels.

If you are creating `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#DraggableState(kotlin.Function1)` in composition, consider using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/rememberDraggableState.composable#rememberDraggableState(kotlin.Function1)`.

| Parameters |
|---|---|
| `onDelta: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | callback invoked when drag occurs. The callback receives the delta in pixels. |

### Scrollable2DState

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/Scrollable2DState.kt+function:Scrollable2DState) Added in [1.9.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.9.0)

```
fun Scrollable2DState(consumeScrollDelta: (Offset) -> Offset): Scrollable2DState
```

Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Scrollable2DState(kotlin.Function1)` interface that contains necessary information about the ongoing fling and provides smooth scrolling capabilities.

This is the simplest way to set up a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/scrollable2D.modifier#(androidx.compose.ui.Modifier).scrollable2D(androidx.compose.foundation.gestures.Scrollable2DState,kotlin.Boolean,androidx.compose.foundation.OverscrollEffect,androidx.compose.foundation.gestures.FlingBehavior,androidx.compose.foundation.interaction.MutableInteractionSource)` modifier. When constructing this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Scrollable2DState(kotlin.Function1)`, you must provide a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#Scrollable2DState(kotlin.Function1)` lambda, which will be invoked whenever scroll happens (by gesture input, by smooth scrolling, by flinging or nested scroll) with the delta in pixels. The amount of scrolling delta consumed must be returned from this lambda to ensure proper nested scrolling behaviour.

| Parameters |
|---|---|
| `consumeScrollDelta: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | callback invoked when drag/fling/smooth scrolling occurs. The callback receives the delta in pixels. Callers should update their state in this lambda and return the amount of delta consumed |

### ScrollableState

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ScrollableState.kt+function:ScrollableState) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
fun ScrollableState(consumeScrollDelta: (Float) -> Float): ScrollableState
```

Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#ScrollableState(kotlin.Function1)` interface that contains necessary information about the ongoing fling and provides smooth scrolling capabilities.

This is the simplest way to set up a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/scrollable.modifier#(androidx.compose.ui.Modifier).scrollable(androidx.compose.foundation.gestures.ScrollableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,kotlin.Boolean,androidx.compose.foundation.gestures.FlingBehavior,androidx.compose.foundation.interaction.MutableInteractionSource)` modifier. When constructing this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#ScrollableState(kotlin.Function1)`, you must provide a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#ScrollableState(kotlin.Function1)` lambda, which will be invoked whenever scroll happens (by gesture input, by smooth scrolling, by flinging or nested scroll) with the delta in pixels. The amount of scrolling delta consumed must be returned from this lambda to ensure proper nested scrolling behaviour.

| Parameters |
|---|---|
| `consumeScrollDelta: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | callback invoked when drag/fling/smooth scrolling occurs. The callback receives the delta in pixels. Callers should update their state in this lambda and return the amount of delta consumed |

### TransformableState

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:TransformableState) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0) Deprecated in [1.11.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.11.0)

```
fun [TransformableState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function3))(
    onTransformation: (zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit
): TransformableState
```

> [!CAUTION]
> **This function is deprecated.**   
> Prefer creating TransformableState with a onTransformation lambda that takes the centroid. This centroid (if specified) is the point at which zooming or rotation should happen around which allows for more natural transformations.

Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function3)` interface that contains necessary information about the ongoing transformations and provides smooth transformation capabilities.

This is the simplest way to set up a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/transformable.modifier#(androidx.compose.ui.Modifier).transformable(androidx.compose.foundation.gestures.TransformableState,kotlin.Boolean,kotlin.Boolean)` modifier. When constructing this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function3)`, you must provide a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function3)` lambda, which will be invoked whenever pan, zoom or rotation happens (by gesture input or any `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState#transform(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` call) with the deltas from the previous event.

| Parameters |
|---|---|
| `onTransformation: (zoomChange: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, panChange: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, rotationChange: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | callback invoked when transformation occurs. The callback receives the change from the previous event. It's relative scale multiplier for zoom, `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` in pixels for pan and degrees for rotation. Callers should update their state in this lambda. |

### TransformableState

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:TransformableState) Added in [1.11.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.11.0)

```
fun TransformableState(
    onTransformation: (centroid: Offset, zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit
): TransformableState
```

Default implementation of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function4)` interface that contains necessary information about the ongoing transformations and provides smooth transformation capabilities.

This is the simplest way to set up a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/transformable.modifier#(androidx.compose.ui.Modifier).transformable(androidx.compose.foundation.gestures.TransformableState,kotlin.Boolean,kotlin.Boolean)` modifier. When constructing this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function4)`, you must provide a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#TransformableState(kotlin.Function4)` lambda, which will be invoked whenever pan, zoom or rotation happens (by gesture input or any `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState#transform(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` call) with the deltas from the previous event.

| Parameters |
|---|---|
| `onTransformation: (centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, zoomChange: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html, panChange: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, rotationChange: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | callback invoked when transformation occurs. The callback receives the change from the previous event. The centroid `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` refers to where the transformation occurs. The changes are a relative scale multiplier for zoom, `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` in pixels for pan and degrees for rotation. Callers should update their state in this lambda. |

## Extension functions

### TransformableState.animateBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:animateBy)

```
suspend fun TransformableState.animateBy(
    zoomFactor: Float,
    panOffset: Offset,
    rotationDegrees: Float,
    zoomAnimationSpec: AnimationSpec<Float> = SpringSpec(stiffness = Spring.StiffnessLow),
    panAnimationSpec: AnimationSpec<Offset> = SpringSpec(stiffness = Spring.StiffnessLow),
    rotationAnimationSpec: AnimationSpec<Float> = SpringSpec(stiffness = Spring.StiffnessLow),
    centroid: Offset = Offset.Unspecified
): Unit
```

Animate zoom, pan, and rotation simultaneously and suspend until the animation is finished.

Zoom is animated by a ratio of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateBy(kotlin.Float,androidx.compose.ui.geometry.Offset,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` over the current size. Pan is animated by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateBy(kotlin.Float,androidx.compose.ui.geometry.Offset,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` in pixels. Rotation is animated by the value of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateBy(kotlin.Float,androidx.compose.ui.geometry.Offset,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` clockwise. Any of these parameters can be set to a no-op value that will result in no animation of that parameter. The no-op values are the following: `1f` for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateBy(kotlin.Float,androidx.compose.ui.geometry.Offset,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)`, `Offset.Zero` for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateBy(kotlin.Float,androidx.compose.ui.geometry.Offset,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)`, and `0f` for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateBy(kotlin.Float,androidx.compose.ui.geometry.Offset,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)`.

```kotlin
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.animateBy
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.rememberTransformableState
import androidx.compose.foundation.gestures.transformable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.center
import androidx.compose.ui.geometry.isSpecified
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.toSize

/**
 * Rotates the given offset around the origin by the given angle in degrees.
 *
 * A positive angle indicates a counterclockwise rotation around the right-handed 2D Cartesian
 * coordinate system.
 *
 * See: [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
 */
fun Offset.rotateBy(angle: Float): Offset {
    val angleInRadians = angle * (PI / 180)
    val cos = cos(angleInRadians)
    val sin = sin(angleInRadians)
    return Offset((x * cos - y * sin).toFloat(), (x * sin + y * cos).toFloat())
}

Box(Modifier.size(200.dp).clipToBounds().background(Color.LightGray)) {
    // set up all transformation states
    var scale by remember { mutableStateOf(1f) }
    var rotation by remember { mutableStateOf(0f) }
    var offset by remember { mutableStateOf(Offset.Zero) }
    val coroutineScope = rememberCoroutineScope()

    var size by remember { mutableStateOf(Size.Zero) }

    // let's create a modifier state to specify how to update our UI state defined above
    val state =
        rememberTransformableState { centroid, zoomChange, offsetChange, rotationChange ->
            val oldScale = scale
            val newScale = max(scale * zoomChange, 1f)

            // If the centroid isn't specified, assume it should be applied from the center
            val effectiveCentroid = centroid.takeIf { it.isSpecified } ?: size.center

            // For natural zooming and rotating, the centroid of the gesture should
            // be the fixed point where zooming and rotating occurs.
            // We compute where the centroid was (in the pre-transformed coordinate
            // space), and then compute where it will be after this delta.
            // We then compute what the new offset should be to keep the centroid
            // visually stationary for rotating and zooming, and also apply the pan.
            offset =
                (offset + effectiveCentroid / oldScale).rotateBy(rotationChange) -
                    (effectiveCentroid / newScale + offsetChange / oldScale)
            scale = newScale
            rotation += rotationChange
        }
    Box(
        Modifier.onSizeChanged { size = it.toSize() }
            // add transformable to listen to multitouch transformation events after offset
            .transformable(state = state)
            // detect tap gestures:
            // 1) single tap to simultaneously animate zoom, pan, and rotation
            // 2) double tap to animate back to the initial position
            .pointerInput(Unit) {
                detectTapGestures(
                    onTap = { offset ->
                        coroutineScope.launch {
                            state.animateBy(
                                zoomFactor = 1.5f,
                                panOffset = Offset(20f, 20f),
                                rotationDegrees = 90f,
                                zoomAnimationSpec = spring(),
                                panAnimationSpec = tween(durationMillis = 1000),
                                rotationAnimationSpec = spring(),
                                centroid = offset,
                            )
                        }
                    },
                    onDoubleTap = { offset ->
                        coroutineScope.launch {
                            state.animateBy(
                                zoomFactor = 1 / scale,
                                panOffset = -offset,
                                rotationDegrees = -rotation,
                                centroid = offset,
                            )
                        }
                    },
                )
            }
            .fillMaxSize()
            .border(1.dp, Color.Green)
    ) {
        Text(
            "\uD83C\uDF55",
            fontSize = 32.sp,
            modifier =
                Modifier.fillMaxSize()
                    .graphicsLayer {
                        translationX = -offset.x * scale
                        translationY = -offset.y * scale
                        scaleX = scale
                        scaleY = scale
                        rotationZ = rotation
                        transformOrigin = TransformOrigin(0f, 0f)
                    }
                    .wrapContentSize(align = Alignment.Center),
        )
    }
}
```

| Parameters |
|---|---|
| `zoomFactor: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | ratio over the current size by which to zoom. For example, if `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateBy(kotlin.Float,androidx.compose.ui.geometry.Offset,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` is `3f`, zoom will be increased 3 fold from the current value. |
| `panOffset: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | offset to pan, in pixels |
| `rotationDegrees: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | the degrees by which to rotate clockwise |
| `zoomAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = SpringSpec(stiffness = Spring.StiffnessLow)` | `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec` to be used for animating zoom |
| `panAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset> = SpringSpec(stiffness = Spring.StiffnessLow)` | `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec` to be used for animating offset |
| `rotationAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = SpringSpec(stiffness = Spring.StiffnessLow)` | `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec` to be used for animating rotation |
| `centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset = Offset.Unspecified` | the `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` around which the animation should occur, if any. The default value is `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Unspecified()`, which leaves the behavior up to the implementation of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState`. |

### TransformableState.animatePanBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:animatePanBy)

```
suspend fun TransformableState.animatePanBy(
    offset: Offset,
    animationSpec: AnimationSpec<Offset> = SpringSpec(stiffness = Spring.StiffnessLow),
    centroid: Offset = Offset.Unspecified
): Unit
```

Animate pan by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animatePanBy(androidx.compose.ui.geometry.Offset,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` Offset in pixels and suspend until its finished

| Parameters |
|---|---|
| `offset: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | offset to pan, in pixels |
| `animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset> = SpringSpec(stiffness = Spring.StiffnessLow)` | `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec` to be used for pan animation |
| `centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset = Offset.Unspecified` | the `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` around which the pan should occur, if any. The default value is `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Unspecified()`, which leaves the behavior up to the implementation of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState`. |

### TransformableState.animateRotateBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:animateRotateBy)

```
suspend fun TransformableState.animateRotateBy(
    degrees: Float,
    animationSpec: AnimationSpec<Float> = SpringSpec(stiffness = Spring.StiffnessLow),
    centroid: Offset = Offset.Unspecified
): Unit
```

Animate rotate by a ratio of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateRotateBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` clockwise and suspend until its finished.

| Parameters |
|---|---|
| `degrees: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | the degrees by which to rotate clockwise |
| `animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = SpringSpec(stiffness = Spring.StiffnessLow)` | `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec` to be used for animation |
| `centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset = Offset.Unspecified` | the `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` around which the rotation should occur, if any. The default value is `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Unspecified()`, which leaves the behavior up to the implementation of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState`. |

### ScrollableState.animateScrollBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ScrollExtensions.kt+function:animateScrollBy)

```
suspend fun ScrollableState.animateScrollBy(
    value: Float,
    animationSpec: AnimationSpec<Float> = spring()
): Float
```

Scroll by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).animateScrollBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec)` pixels with animation.

Cancels the currently running scroll, if any, and suspends until the cancellation is complete.

| Parameters |
|---|---|
| `value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | number of pixels to scroll by |
| `animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = spring()` | `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec` to be used for this scrolling |

| Returns |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | the amount of scroll consumed |

### Scrollable2DState.animateScrollBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ScrollExtensions.kt+function:animateScrollBy)

```
suspend fun Scrollable2DState.animateScrollBy(
    value: Offset,
    animationSpec: AnimationSpec<Offset> = spring()
): Offset
```

Scroll by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.Scrollable2DState).animateScrollBy(androidx.compose.ui.geometry.Offset,androidx.compose.animation.core.AnimationSpec)` pixels with animation.

Cancels the currently running scroll, if any, and suspends until the cancellation is complete.

| Parameters |
|---|---|
| `value: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | number of pixels to scroll by |
| `animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset> = spring()` | `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec` to be used for this scrolling |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | the amount of scroll consumed |

### AnchoredDraggableState.animateTo

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/AnchoredDraggable.kt+function:animateTo) Added in [1.8.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.8.0)

```
suspend fun <T : Any?> AnchoredDraggableState<T>.animateTo(
    targetValue: T,
    animationSpec: AnimationSpec<Float> = if (usePreModifierChangeBehavior) {
            @Suppress("DEPRECATION") this.snapAnimationSpec
        } else AnchoredDraggableDefaults.SnapAnimationSpec
): Unit
```

Animate to a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateTo(kotlin.Any,androidx.compose.animation.core.AnimationSpec)`. If the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateTo(kotlin.Any,androidx.compose.animation.core.AnimationSpec)` is not in the set of anchors, the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#currentValue()` will be updated to the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateTo(kotlin.Any,androidx.compose.animation.core.AnimationSpec)` without updating the offset.

| Parameters |
|---|---|
| `targetValue: T` | The target value of the animation |
| `animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = if (usePreModifierChangeBehavior) { @Suppress("DEPRECATION") this.snapAnimationSpec } else AnchoredDraggableDefaults.SnapAnimationSpec` | The animation spec used to perform the animation |

| Throws |
|---|---|
| `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-cancellation-exception/index.html` | if the interaction interrupted by another interaction like a gesture interaction or another programmatic interaction like a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateTo(kotlin.Any,androidx.compose.animation.core.AnimationSpec)` or `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).snapTo(kotlin.Any)` call. |

### AnchoredDraggableState.animateToWithDecay

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/AnchoredDraggable.kt+function:animateToWithDecay)

```
suspend fun <T : Any?> AnchoredDraggableState<T>.animateToWithDecay(
    targetValue: T,
    velocity: Float,
    snapAnimationSpec: AnimationSpec<Float> = if (usePreModifierChangeBehavior) {
            @Suppress("DEPRECATION") this.snapAnimationSpec
        } else AnchoredDraggableDefaults.SnapAnimationSpec,
    decayAnimationSpec: DecayAnimationSpec<Float> = if (usePreModifierChangeBehavior) {
            @Suppress("DEPRECATION") this.decayAnimationSpec
        } else AnchoredDraggableDefaults.DecayAnimationSpec
): Float
```

Attempt to animate using decay Animation to a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)`. If the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` is high enough to get to the target offset, we'll use `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` to get to that offset and return the consumed velocity. If the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` is not high enough, we'll use `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` to reach the target offset.

If the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` is not in the set of anchors, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#currentValue()` will be updated ro the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` without updating the offset.

| Parameters |
|---|---|
| `targetValue: T` | The target value of the animation |
| `velocity: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | The velocity the animation should start with, in px/s |
| `snapAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = if (usePreModifierChangeBehavior) { @Suppress("DEPRECATION") this.snapAnimationSpec } else AnchoredDraggableDefaults.SnapAnimationSpec` | The animation spec used if the velocity is not high enough to perform a decay to the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` using the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` |
| `decayAnimationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/DecayAnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = if (usePreModifierChangeBehavior) { @Suppress("DEPRECATION") this.decayAnimationSpec } else AnchoredDraggableDefaults.DecayAnimationSpec` | The animation spec used if the velocity is high enough to perform a decay to the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateToWithDecay(kotlin.Any,kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)` |

| Returns |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | The velocity consumed in the animation |

| Throws |
|---|---|
| `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-cancellation-exception/index.html` | if the interaction interrupted bt another interaction like a gesture interaction or another programmatic interaction like `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateTo(kotlin.Float,androidx.compose.foundation.gestures.AnchoredDragScope,androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Any,androidx.compose.animation.core.AnimationSpec)` or `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).snapTo(kotlin.Any)` call. |

### TransformableState.animateZoomBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:animateZoomBy)

```
suspend fun TransformableState.animateZoomBy(
    zoomFactor: Float,
    animationSpec: AnimationSpec<Float> = SpringSpec(stiffness = Spring.StiffnessLow),
    centroid: Offset = Offset.Unspecified
): Unit
```

Animate zoom by a ratio of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateZoomBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` over the current size and suspend until its finished.

| Parameters |
|---|---|
| `zoomFactor: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | ratio over the current size by which to zoom. For example, if `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).animateZoomBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec,androidx.compose.ui.geometry.Offset)` is `3f`, zoom will be increased 3 fold from the current value. |
| `animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = SpringSpec(stiffness = Spring.StiffnessLow)` | `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec` to be used for animation |
| `centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset = Offset.Unspecified` | the `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` around which the zoom should occur, if any. The default value is `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Unspecified()`, which leaves the behavior up to the implementation of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState`. |

### AwaitPointerEventScope.awaitDragOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitDragOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitDragOrCancellation(pointerId: PointerId): PointerInputChange?
```

Reads pointer input events until a drag is detected or all pointers are up. When the final pointer is raised, the up event is returned. When a drag event is detected, the drag change will be returned. Note that if `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` has been raised, another pointer that is down will be used, if available, so the returned `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#id()` may differ from `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)`. If the position change in the any direction has been consumed by the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEventPass#Main` pass, then the drag is considered canceled and `null` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` is not down when `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` is called, then `null` is returned.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitDragOrCancellation
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitTouchSlopOrCancellation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var size by remember { mutableStateOf(Size.Zero) }
Box(Modifier.fillMaxSize().onSizeChanged { size = it.toSize() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .size(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    var change =
                        awaitTouchSlopOrCancellation(down.id) { change, over ->
                            val original = Offset(offsetX.value, offsetY.value)
                            val summed = original + over
                            val newValue =
                                Offset(
                                    x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                                    y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                                )
                            change.consume()
                            offsetX.value = newValue.x
                            offsetY.value = newValue.y
                        }
                    while (change != null && change.pressed) {
                        change = awaitDragOrCancellation(change.id)
                        if (change != null && change.pressed) {
                            val original = Offset(offsetX.value, offsetY.value)
                            val summed = original + change.positionChange()
                            val newValue =
                                Offset(
                                    x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                                    y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                                )
                            change.consume()
                            offsetX.value = newValue.x
                            offsetY.value = newValue.y
                        }
                    }
                }
            }
    )
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |

### PointerInputScope.awaitEachGesture

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ForEachGesture.kt+function:awaitEachGesture) Added in [1.4.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.4.0)

```
suspend fun PointerInputScope.awaitEachGesture(block: suspend AwaitPointerEventScope.() -> Unit): Unit
```

Repeatedly calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).awaitEachGesture(kotlin.coroutines.SuspendFunction1)` to handle gestures. If there is a `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.coroutines.cancellation/-cancellation-exception/index.html`, it will wait until all pointers are raised before another gesture is detected, or it exits if `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/index.html` is `false`.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).awaitEachGesture(kotlin.coroutines.SuspendFunction1)` is run within `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputScope#awaitPointerEventScope(kotlin.coroutines.SuspendFunction1)` and will loop entirely within the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/AwaitPointerEventScope` so events will not be lost between gestures.

### AwaitPointerEventScope.awaitFirstDown

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TapGestureDetector.kt+function:awaitFirstDown)

```
suspend fun AwaitPointerEventScope.awaitFirstDown(
    requireUnconsumed: Boolean = true,
    pass: PointerEventPass = PointerEventPass.Main
): PointerInputChange
```

Reads events until the first down is received in the given `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitFirstDown(kotlin.Boolean,androidx.compose.ui.input.pointer.PointerEventPass)`. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitFirstDown(kotlin.Boolean,androidx.compose.ui.input.pointer.PointerEventPass)` is `true` and the first down is already consumed in the pass, that gesture is ignored.

### AwaitPointerEventScope.awaitHorizontalDragOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitHorizontalDragOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitHorizontalDragOrCancellation(
    pointerId: PointerId
): PointerInputChange?
```

Reads pointer input events until a horizontal drag is detected or all pointers are up. When the final pointer is raised, the up event is returned. When a drag event is detected, the drag change will be returned. Note that if `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` has been raised, another pointer that is down will be used, if available, so the returned `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#id()` may differ from `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)`. If the position change has been consumed by the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEventPass#Main` pass, then the drag is considered canceled and `null` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` is not down when `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` is called, then `null` is returned.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitHorizontalDragOrCancellation
import androidx.compose.foundation.gestures.awaitHorizontalTouchSlopOrCancellation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var width by remember { mutableStateOf(0f) }
Box(Modifier.fillMaxSize().onSizeChanged { width = it.width.toFloat() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .fillMaxHeight()
            .width(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    var change =
                        awaitHorizontalTouchSlopOrCancellation(down.id) { change, over ->
                            val originalX = offsetX.value
                            val newValue = (originalX + over).coerceIn(0f, width - 50.dp.toPx())
                            change.consume()
                            offsetX.value = newValue
                        }
                    while (change != null && change.pressed) {
                        change = awaitHorizontalDragOrCancellation(change.id)
                        if (change != null && change.pressed) {
                            val originalX = offsetX.value
                            val newValue =
                                (originalX + change.positionChange().x).coerceIn(
                                    0f,
                                    width - 50.dp.toPx(),
                                )
                            change.consume()
                            offsetX.value = newValue
                        }
                    }
                }
            }
    )
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |

### AwaitPointerEventScope.awaitHorizontalPointerSlopOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitHorizontalPointerSlopOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitHorizontalPointerSlopOrCancellation(
    pointerId: PointerId,
    pointerType: PointerType,
    onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
): PointerInputChange?
```

Waits for horizontal drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)`'s touch slop, using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` as the pointer to examine. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` is raised, another pointer from those that are down will be chosen to lead the gesture, and if none are down, `null` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` is not down when `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` is called, then `null` is returned.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` is called after `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)`'s touch slop motion in the horizontal direction with the change that caused the motion beyond touch slop and the pixels beyond touch slop. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` should consume the position change if it accepts the motion. If it does, then the method returns that `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange`. If not, touch slop detection will continue.

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | The `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` that was consumed in `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` or `null` if all pointers are raised before touch slop is detected or another gesture consumed the position change. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |

### AwaitPointerEventScope.awaitHorizontalTouchSlopOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitHorizontalTouchSlopOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitHorizontalTouchSlopOrCancellation(
    pointerId: PointerId,
    onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
): PointerInputChange?
```

Waits for horizontal drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()`, using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` as the pointer to examine. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is raised, another pointer from those that are down will be chosen to lead the gesture, and if none are down, `null` is returned.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is called after `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()` motion in the horizontal direction with the change that caused the motion beyond touch slop and the pixels beyond touch slop. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` should consume the position change if it accepts the motion. If it does, then the method returns that `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange`. If not, touch slop detection will continue. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is not down when `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is called, then `null` is returned.

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitHorizontalDragOrCancellation
import androidx.compose.foundation.gestures.awaitHorizontalTouchSlopOrCancellation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var width by remember { mutableStateOf(0f) }
Box(Modifier.fillMaxSize().onSizeChanged { width = it.width.toFloat() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .fillMaxHeight()
            .width(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    var change =
                        awaitHorizontalTouchSlopOrCancellation(down.id) { change, over ->
                            val originalX = offsetX.value
                            val newValue = (originalX + over).coerceIn(0f, width - 50.dp.toPx())
                            change.consume()
                            offsetX.value = newValue
                        }
                    while (change != null && change.pressed) {
                        change = awaitHorizontalDragOrCancellation(change.id)
                        if (change != null && change.pressed) {
                            val originalX = offsetX.value
                            val newValue =
                                (originalX + change.positionChange().x).coerceIn(
                                    0f,
                                    width - 50.dp.toPx(),
                                )
                            change.consume()
                            offsetX.value = newValue
                        }
                    }
                }
            }
    )
}
```

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | The `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` that was consumed in `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` or `null` if all pointers are raised before touch slop is detected or another gesture consumed the position change. Example Usage: |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |

### AwaitPointerEventScope.awaitLongPressOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitLongPressOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitLongPressOrCancellation(
    pointerId: PointerId
): PointerInputChange?
```

Waits for a long press by examining `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitLongPressOrCancellation(androidx.compose.ui.input.pointer.PointerId)`.

If that `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitLongPressOrCancellation(androidx.compose.ui.input.pointer.PointerId)` is raised (that is, the user lifts their finger), but another finger (`https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerId`) is down at that time, another pointer will be chosen as the lead for the gesture, and if none are down, `null` is returned.

```kotlin
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitLongPressOrCancellation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp

var count by remember { mutableStateOf(0) }

Column {
    Text("Long Press to increase count. Long Press count: $count")
    Box(
        Modifier.fillMaxSize()
            .wrapContentSize(Alignment.Center)
            .size(192.dp)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown(requireUnconsumed = false)
                    awaitLongPressOrCancellation(down.id)?.let { count++ }
                }
            }
            .clipToBounds()
            .background(Color.Blue)
            .border(BorderStroke(2.dp, Color.Black))
    )
}
```

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | The latest `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` associated with a long press or `null` if all pointers are raised before a long press is detected or another gesture consumed the change. Example Usage: |

### AwaitPointerEventScope.awaitTouchSlopOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitTouchSlopOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitTouchSlopOrCancellation(
    pointerId: PointerId,
    onTouchSlopReached: (change: PointerInputChange, overSlop: Offset) -> Unit
): PointerInputChange?
```

Waits for drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()`, using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` as the pointer to examine. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is raised, another pointer from those that are down will be chosen to lead the gesture, and if none are down, `null` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is not down when `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is called, then `null` is returned.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is called after `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()` motion in the any direction with the change that caused the motion beyond touch slop and the `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` beyond touch slop that has passed. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` should consume the position change if it accepts the motion. If it does, then the method returns that `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange`. If not, touch slop detection will continue.

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitDragOrCancellation
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitTouchSlopOrCancellation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var size by remember { mutableStateOf(Size.Zero) }
Box(Modifier.fillMaxSize().onSizeChanged { size = it.toSize() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .size(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    var change =
                        awaitTouchSlopOrCancellation(down.id) { change, over ->
                            val original = Offset(offsetX.value, offsetY.value)
                            val summed = original + over
                            val newValue =
                                Offset(
                                    x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                                    y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                                )
                            change.consume()
                            offsetX.value = newValue.x
                            offsetY.value = newValue.y
                        }
                    while (change != null && change.pressed) {
                        change = awaitDragOrCancellation(change.id)
                        if (change != null && change.pressed) {
                            val original = Offset(offsetX.value, offsetY.value)
                            val summed = original + change.positionChange()
                            val newValue =
                                Offset(
                                    x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                                    y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                                )
                            change.consume()
                            offsetX.value = newValue.x
                            offsetY.value = newValue.y
                        }
                    }
                }
            }
    )
}
```

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | The `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` that was consumed in `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` or `null` if all pointers are raised before touch slop is detected or another gesture consumed the position change. Example Usage: |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |

### AwaitPointerEventScope.awaitVerticalDragOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitVerticalDragOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitVerticalDragOrCancellation(
    pointerId: PointerId
): PointerInputChange?
```

Reads pointer input events until a vertical drag is detected or all pointers are up. When the final pointer is raised, the up event is returned. When a drag event is detected, the drag change will be returned. Note that if `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` has been raised, another pointer that is down will be used, if available, so the returned `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#id()` may differ from `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)`. If the position change has been consumed by the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEventPass#Main` pass, then the drag is considered canceled and `null` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` is not down when `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` is called, then `null` is returned.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitVerticalDragOrCancellation
import androidx.compose.foundation.gestures.awaitVerticalTouchSlopOrCancellation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var height by remember { mutableStateOf(0f) }
Box(Modifier.fillMaxSize().onSizeChanged { height = it.height.toFloat() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .fillMaxWidth()
            .height(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    var change =
                        awaitVerticalTouchSlopOrCancellation(down.id) { change, over ->
                            val originalY = offsetY.value
                            val newValue =
                                (originalY + over).coerceIn(0f, height - 50.dp.toPx())
                            change.consume()
                            offsetY.value = newValue
                        }
                    while (change != null && change.pressed) {
                        change = awaitVerticalDragOrCancellation(change.id)
                        if (change != null && change.pressed) {
                            val originalY = offsetY.value
                            val newValue =
                                (originalY + change.positionChange().y).coerceIn(
                                    0f,
                                    height - 50.dp.toPx(),
                                )
                            change.consume()
                            offsetY.value = newValue
                        }
                    }
                }
            }
    )
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |

### AwaitPointerEventScope.awaitVerticalPointerSlopOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitVerticalPointerSlopOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitVerticalPointerSlopOrCancellation(
    pointerId: PointerId,
    pointerType: PointerType,
    onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
): PointerInputChange?
```

Waits for vertical drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)`'s touch slop using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` as the pointer to examine. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` is raised, another pointer from those that are down will be chosen to lead the gesture, and if none are down, `null` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` is not down when `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` is called, then `null` is returned.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` is called after `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()` motion in the vertical direction with the change that caused the motion beyond touch slop and the pixels beyond touch slop. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` should consume the position change if it accepts the motion. If it does, then the method returns that `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange`. If not, touch slop detection will continue.

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | The `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` that was consumed in `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalPointerSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,androidx.compose.ui.input.pointer.PointerType,kotlin.Function2)` or `null` if all pointers are raised before touch slop is detected or another gesture consumed the position change. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |

### AwaitPointerEventScope.awaitVerticalTouchSlopOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:awaitVerticalTouchSlopOrCancellation)

```
suspend fun AwaitPointerEventScope.awaitVerticalTouchSlopOrCancellation(
    pointerId: PointerId,
    onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
): PointerInputChange?
```

Waits for vertical drag motion to pass `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()`, using `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` as the pointer to examine. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is raised, another pointer from those that are down will be chosen to lead the gesture, and if none are down, `null` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is not down when `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is called, then `null` is returned.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` is called after `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#touchSlop()` motion in the vertical direction with the change that caused the motion beyond touch slop and the pixels beyond touch slop. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` should consume the position change if it accepts the motion. If it does, then the method returns that `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange`. If not, touch slop detection will continue.

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitVerticalDragOrCancellation
import androidx.compose.foundation.gestures.awaitVerticalTouchSlopOrCancellation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var height by remember { mutableStateOf(0f) }
Box(Modifier.fillMaxSize().onSizeChanged { height = it.height.toFloat() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .fillMaxWidth()
            .height(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    var change =
                        awaitVerticalTouchSlopOrCancellation(down.id) { change, over ->
                            val originalY = offsetY.value
                            val newValue =
                                (originalY + over).coerceIn(0f, height - 50.dp.toPx())
                            change.consume()
                            offsetY.value = newValue
                        }
                    while (change != null && change.pressed) {
                        change = awaitVerticalDragOrCancellation(change.id)
                        if (change != null && change.pressed) {
                            val originalY = offsetY.value
                            val newValue =
                                (originalY + change.positionChange().y).coerceIn(
                                    0f,
                                    height - 50.dp.toPx(),
                                )
                            change.consume()
                            offsetY.value = newValue
                        }
                    }
                }
            }
    )
}
```

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange?` | The `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` that was consumed in `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` or `null` if all pointers are raised before touch slop is detected or another gesture consumed the position change. Example Usage: |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |

### PointerEvent.calculateCentroid

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformGestureDetector.kt+function:calculateCentroid) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
fun PointerEvent.calculateCentroid(useCurrent: Boolean = true): Offset
```

Returns the centroid of all pointers that are down and were previously down. If no pointers are down, `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Unspecified()` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerEvent).calculateCentroid(kotlin.Boolean)` is `true`, the centroid of the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#position()` is returned and if `false`, the centroid of the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#previousPosition()` is returned. Only pointers that are down in both the previous and current state are used to calculate the centroid.

Example Usage:

```kotlin
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.calculateCentroid
import androidx.compose.foundation.gestures.calculateCentroidSize
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput

var centroidSize by remember { mutableStateOf(0f) }
var position by remember { mutableStateOf(Offset.Zero) }
Box(
    Modifier.drawBehind {
            // Draw a circle where the gesture is
            drawCircle(Color.Blue, centroidSize, center = position)
        }
        .pointerInput(Unit) {
            awaitEachGesture {
                awaitFirstDown().also { position = it.position }
                do {
                    val event = awaitPointerEvent()
                    val size = event.calculateCentroidSize()
                    if (size != 0f) {
                        centroidSize = event.calculateCentroidSize()
                    }
                    val centroid = event.calculateCentroid()
                    if (centroid != Offset.Unspecified) {
                        position = centroid
                    }
                } while (event.changes.any { it.pressed })
            }
        }
        .fillMaxSize()
)
```

### PointerEvent.calculateCentroidSize

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformGestureDetector.kt+function:calculateCentroidSize) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
fun PointerEvent.calculateCentroidSize(useCurrent: Boolean = true): Float
```

Returns the average distance from the centroid for all pointers that are currently and were previously down. If no pointers are down, `0` is returned. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerEvent).calculateCentroidSize(kotlin.Boolean)` is `true`, the size of the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#position()` is returned and if `false`, the size of `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#previousPosition()` is returned. Only pointers that are down in both the previous and current state are used to calculate the centroid size.

Example Usage:

```kotlin
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.calculateCentroid
import androidx.compose.foundation.gestures.calculateCentroidSize
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput

var centroidSize by remember { mutableStateOf(0f) }
var position by remember { mutableStateOf(Offset.Zero) }
Box(
    Modifier.drawBehind {
            // Draw a circle where the gesture is
            drawCircle(Color.Blue, centroidSize, center = position)
        }
        .pointerInput(Unit) {
            awaitEachGesture {
                awaitFirstDown().also { position = it.position }
                do {
                    val event = awaitPointerEvent()
                    val size = event.calculateCentroidSize()
                    if (size != 0f) {
                        centroidSize = event.calculateCentroidSize()
                    }
                    val centroid = event.calculateCentroid()
                    if (centroid != Offset.Unspecified) {
                        position = centroid
                    }
                } while (event.changes.any { it.pressed })
            }
        }
        .fillMaxSize()
)
```

### PointerEvent.calculatePan

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformGestureDetector.kt+function:calculatePan) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
fun PointerEvent.calculatePan(): Offset
```

Returns the change in the centroid location between the previous and the current pointers that are down. Pointers that are newly down or raised are not considered in the centroid movement.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.calculatePan
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.IntOffset

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
Box(
    Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
        .graphicsLayer()
        .background(Color.Blue)
        .pointerInput(Unit) {
            awaitEachGesture {
                awaitFirstDown()
                do {
                    val event = awaitPointerEvent()
                    val offset = event.calculatePan()
                    offsetX.value += offset.x
                    offsetY.value += offset.y
                } while (event.changes.any { it.pressed })
            }
        }
        .fillMaxSize()
)
```

### PointerEvent.calculateRotation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformGestureDetector.kt+function:calculateRotation) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
fun PointerEvent.calculateRotation(): Float
```

Returns the rotation, in degrees, of the pointers between the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#previousPosition()` and `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#position()` states. Only the pointers that are down in both previous and current states are considered.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.calculateRotation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput

var angle by remember { mutableStateOf(0f) }
Box(
    Modifier.graphicsLayer(rotationZ = angle)
        .background(Color.Blue)
        .pointerInput(Unit) {
            awaitEachGesture {
                awaitFirstDown()
                do {
                    val event = awaitPointerEvent()
                    val rotation = event.calculateRotation()
                    angle += rotation
                } while (event.changes.any { it.pressed })
            }
        }
        .fillMaxSize()
)
```

### PointerEvent.calculateZoom

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformGestureDetector.kt+function:calculateZoom) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
fun PointerEvent.calculateZoom(): Float
```

Uses the change of the centroid size between the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#previousPosition()` and `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#position()` to determine how much zoom was intended.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.calculateZoom
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput

var zoom by remember { mutableStateOf(1f) }
Box(
    Modifier.graphicsLayer(scaleX = zoom, scaleY = zoom)
        .background(Color.Blue)
        .pointerInput(Unit) {
            awaitEachGesture {
                awaitFirstDown()
                do {
                    val event = awaitPointerEvent()
                    zoom *= event.calculateZoom()
                } while (event.changes.any { it.pressed })
            }
        }
        .fillMaxSize()
)
```

### PointerInputScope.detectDragGestures

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:detectDragGestures) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun PointerInputScope.detectDragGestures(
    onDragStart: (Offset) -> Unit = {},
    onDragEnd: () -> Unit = {},
    onDragCancel: () -> Unit = {},
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
): Unit
```

Gesture detector that waits for pointer down and touch slop in any direction and then calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each drag event. It follows the touch slop detection of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` but will consume the position change automatically once the touch slop has been crossed. @see `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` with orientation lock for a fuller set of capabilities.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` called when the touch slop has been passed and includes an `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` representing the last known pointer position relative to the containing element. The `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds if the touch target is smaller than the `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#minimumTouchTargetSize()`.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called after all pointers are up and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called if another gesture has consumed pointer input, canceling this gesture.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var size by remember { mutableStateOf(Size.Zero) }
Box(Modifier.fillMaxSize().onSizeChanged { size = it.toSize() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .size(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                detectDragGestures { _, dragAmount ->
                    val original = Offset(offsetX.value, offsetY.value)
                    val summed = original + dragAmount
                    val newValue =
                        Offset(
                            x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                            y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                        )
                    offsetX.value = newValue.x
                    offsetY.value = newValue.y
                }
            }
    )
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGesturesAfterLongPress(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` | to detect gestures after long press |

### PointerInputScope.detectDragGestures

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:detectDragGestures) Added in [1.9.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.9.0)

```
suspend fun PointerInputScope.detectDragGestures(
    orientationLock: Orientation?,
    onDragStart: (down: PointerInputChange, slopTriggerChange: PointerInputChange, overSlopOffset: Offset) -> Unit = { _, _, _ ->
        },
    onDragEnd: (change: PointerInputChange) -> Unit = {},
    onDragCancel: () -> Unit = {},
    shouldAwaitTouchSlop: () -> Boolean = { true },
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
): Unit
```

A Gesture detector that waits for pointer down and touch slop in the direction specified by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` and then calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each drag event. It follows the touch slop detection of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` but will consume the position change automatically once the touch slop has been crossed, the amount of drag over the touch slop is reported as the first drag event `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` after the slop is crossed. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` returns true the touch slop recognition phase will be ignored and the drag gesture will be recognized immediately.The first `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` in this case will report an `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Zero()`.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called when the touch slop has been passed and includes an `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` representing the last known pointer position relative to the containing element as well as the initial down event that triggered this gesture detection cycle. The `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds if the touch target is smaller than the `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#minimumTouchTargetSize()`.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called after all pointers are up with the event change of the up event and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called if another gesture has consumed pointer input, canceling this gesture.

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var size by remember { mutableStateOf(Size.Zero) }
Box(Modifier.fillMaxSize().onSizeChanged { size = it.toSize() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .size(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                detectDragGestures { _, dragAmount ->
                    val original = Offset(offsetX.value, offsetY.value)
                    val summed = original + dragAmount
                    val newValue =
                        Offset(
                            x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                            y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                        )
                    offsetX.value = newValue.x
                    offsetY.value = newValue.y
                }
            }
    )
}
```

| Parameters |
|---|---|
| `orientationLock: https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/Orientation?` | Optionally locks detection to this orientation, this means, when this is provided, touch slop detection and drag event detection will be conditioned to the given orientation axis. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` will still dispatch events on with information in both axis, but if orientation lock is provided, only events that happen on the given orientation will be considered. This also means that if no event in the orientation is detected we will not dispatch `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(androidx.compose.foundation.gestures.Orientation,kotlin.Function3,kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` calls. If no value is provided (i.e. null) touch slop and drag detection will happen on an "any" orientation basis, that is, touch slop will be detected if crossed in either direction and drag events will be dispatched if present in either direction. |
| `onDragStart: (down: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, slopTriggerChange: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, overSlopOffset: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html = { _, _, _ -> }` | A lambda to be called when the drag gesture starts, it contains information about the last known `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` relative to the containing element and the post slop delta, slopTriggerChange. It also contains information about the down event where this gesture started and the overSlopOffset. |
| `onDragEnd: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html = {}` | A lambda to be called when the gesture ends. It contains information about the up `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` that finished the gesture. |
| `onDragCancel: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html = {}` | A lambda to be called when the gesture is cancelled either by an error or when it was consumed. |
| `shouldAwaitTouchSlop: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = { true }` | Indicates if touch slop detection should be skipped. |
| `onDrag: (change: https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange, dragAmount: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | A lambda to be called for each delta event in the gesture. It contains information about the `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange` and the movement offset. Example Usage: |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGesturesAfterLongPress(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` | to detect gestures after long press |

### PointerInputScope.detectDragGesturesAfterLongPress

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:detectDragGesturesAfterLongPress) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun PointerInputScope.detectDragGesturesAfterLongPress(
    onDragStart: (Offset) -> Unit = {},
    onDragEnd: () -> Unit = {},
    onDragCancel: () -> Unit = {},
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
): Unit
```

Gesture detector that waits for pointer down and long press, after which it calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGesturesAfterLongPress(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each drag event.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGesturesAfterLongPress(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` called when a long press is detected and includes an `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` representing the last known pointer position relative to the containing element. The `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds if the touch target is smaller than the `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#minimumTouchTargetSize()`.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGesturesAfterLongPress(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called after all pointers are up and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGesturesAfterLongPress(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called if another gesture has consumed pointer input, canceling this gesture. This function will automatically consume all the position change after the long press.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var size by remember { mutableStateOf(Size.Zero) }
Box(Modifier.fillMaxSize().onSizeChanged { size = it.toSize() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .size(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                detectDragGesturesAfterLongPress { _, dragAmount ->
                    val original = Offset(offsetX.value, offsetY.value)
                    val summed = original + dragAmount
                    val newValue =
                        Offset(
                            x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                            y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                        )
                    offsetX.value = newValue.x
                    offsetY.value = newValue.y
                }
            }
    )
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |

### PointerInputScope.detectHorizontalDragGestures

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:detectHorizontalDragGestures) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun PointerInputScope.detectHorizontalDragGestures(
    onDragStart: (Offset) -> Unit = {},
    onDragEnd: () -> Unit = {},
    onDragCancel: () -> Unit = {},
    onHorizontalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit
): Unit
```

Gesture detector that waits for pointer down and touch slop in the horizontal direction and then calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each horizontal drag event. It follows the touch slop detection of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)`, but will consume the position change automatically once the touch slop has been crossed.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` called when the touch slop has been passed and includes an `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` representing the last known pointer position relative to the containing element. The `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds if the touch target is smaller than the `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#minimumTouchTargetSize()`.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called after all pointers are up and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called if another gesture has consumed pointer input, canceling this gesture.

This gesture detector will coordinate with `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` to ensure only vertical or horizontal dragging is locked, but not both.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var width by remember { mutableStateOf(0f) }
Box(Modifier.fillMaxSize().onSizeChanged { width = it.width.toFloat() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .fillMaxHeight()
            .width(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                detectHorizontalDragGestures { _, dragAmount ->
                    val originalX = offsetX.value
                    val newValue = (originalX + dragAmount).coerceIn(0f, width - 50.dp.toPx())
                    offsetX.value = newValue
                }
            }
    )
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |

### PointerInputScope.detectTapGestures

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TapGestureDetector.kt+function:detectTapGestures) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun PointerInputScope.detectTapGestures(
    onDoubleTap: ((Offset) -> Unit)? = null,
    onLongPress: ((Offset) -> Unit)? = null,
    onPress: suspend PressGestureScope.(Offset) -> Unit = NoPressGesture,
    onTap: ((Offset) -> Unit)? = null
): Unit
```

Detects tap, double-tap, and long press gestures and calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, respectively, when detected. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)` is called when the press is detected and the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/PressGestureScope#tryAwaitRelease()` and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/PressGestureScope#awaitRelease()` can be used to detect when pointers have released or the gesture was canceled. The first pointer down and final pointer up are consumed, and in the case of long press, all changes after the long press is detected are consumed.

Each function parameter receives an `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` representing the position relative to the containing element. The `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds if the touch target is smaller than the `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#minimumTouchTargetSize()`.

When `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)` is provided, the tap gesture is detected only after the `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#doubleTapMinTimeMillis()` has passed and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)` is called if the second tap is started before `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#doubleTapTimeoutMillis()`. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)` is not provided, then `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)` is called when the pointer up has been received.

After the initial `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, if the pointer moves out of the input area, the position change is consumed, or another gesture consumes the down or up events, the gestures are considered canceled. That means `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`, and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)` will not be called after a gesture has been canceled.

If the first down event is consumed somewhere else, the entire gesture will be skipped, including `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTapGestures(kotlin.Function1,kotlin.Function1,kotlin.coroutines.SuspendFunction2,kotlin.Function1)`.

### PointerInputScope.detectTransformGestures

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformGestureDetector.kt+function:detectTransformGestures) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun PointerInputScope.detectTransformGestures(
    panZoomLock: Boolean = false,
    onGesture: (centroid: Offset, pan: Offset, zoom: Float, rotation: Float) -> Unit
): Unit
```

A gesture detector for rotation, panning, and zoom. Once touch slop has been reached, the user can use rotation, panning and zoom gestures. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTransformGestures(kotlin.Boolean,kotlin.Function4)` will be called when any of the rotation, zoom or pan occurs, passing the rotation angle in degrees, zoom in scale factor and pan as an offset in pixels. Each of these changes is a difference between the previous call and the current gesture. This will consume all position changes after touch slop has been reached. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTransformGestures(kotlin.Boolean,kotlin.Function4)` will also provide centroid of all the pointers that are down.

If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTransformGestures(kotlin.Boolean,kotlin.Function4)` is `true`, rotation is allowed only if touch slop is detected for rotation before pan or zoom motions. If not, pan and zoom gestures will be detected, but rotation gestures will not be. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectTransformGestures(kotlin.Boolean,kotlin.Function4)` is `false`, once touch slop is reached, all three gestures are detected.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput

/**
 * Rotates the given offset around the origin by the given angle in degrees.
 *
 * A positive angle indicates a counterclockwise rotation around the right-handed 2D Cartesian
 * coordinate system.
 *
 * See: [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
 */
fun Offset.rotateBy(angle: Float): Offset {
    val angleInRadians = angle * (PI / 180)
    val cos = cos(angleInRadians)
    val sin = sin(angleInRadians)
    return Offset((x * cos - y * sin).toFloat(), (x * sin + y * cos).toFloat())
}

var offset by remember { mutableStateOf(Offset.Zero) }
var zoom by remember { mutableStateOf(1f) }
var angle by remember { mutableStateOf(0f) }

Box(
    Modifier.pointerInput(Unit) {
            detectTransformGestures(
                onGesture = { centroid, pan, gestureZoom, gestureRotate ->
                    val oldScale = zoom
                    val newScale = zoom * gestureZoom

                    // For natural zooming and rotating, the centroid of the gesture should
                    // be the fixed point where zooming and rotating occurs.
                    // We compute where the centroid was (in the pre-transformed coordinate
                    // space), and then compute where it will be after this delta.
                    // We then compute what the new offset should be to keep the centroid
                    // visually stationary for rotating and zooming, and also apply the pan.
                    offset =
                        (offset + centroid / oldScale).rotateBy(gestureRotate) -
                            (centroid / newScale + pan / oldScale)
                    zoom = newScale
                    angle += gestureRotate
                }
            )
        }
        .graphicsLayer {
            translationX = -offset.x * zoom
            translationY = -offset.y * zoom
            scaleX = zoom
            scaleY = zoom
            rotationZ = angle
            transformOrigin = TransformOrigin(0f, 0f)
        }
        .background(Color.Blue)
        .fillMaxSize()
)
```

### PointerInputScope.detectVerticalDragGestures

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:detectVerticalDragGestures) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun PointerInputScope.detectVerticalDragGestures(
    onDragStart: (Offset) -> Unit = {},
    onDragEnd: () -> Unit = {},
    onDragCancel: () -> Unit = {},
    onVerticalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit
): Unit
```

Gesture detector that waits for pointer down and touch slop in the vertical direction and then calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` for each vertical drag event. It follows the touch slop detection of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)`, but will consume the position change automatically once the touch slop has been crossed.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` called when the touch slop has been passed and includes an `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` representing the last known pointer position relative to the containing element. The `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds if the touch target is smaller than the `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ViewConfiguration#minimumTouchTargetSize()`.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called after all pointers are up and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectVerticalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` is called if another gesture has consumed pointer input, canceling this gesture.

This gesture detector will coordinate with `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` and `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` to ensure only vertical or horizontal dragging is locked, but not both.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectVerticalDragGestures
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var height by remember { mutableStateOf(0f) }
Box(Modifier.fillMaxSize().onSizeChanged { height = it.height.toFloat() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .fillMaxWidth()
            .height(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                detectVerticalDragGestures { _, dragAmount ->
                    val originalY = offsetY.value
                    val newValue = (originalY + dragAmount).coerceIn(0f, height - 50.dp.toPx())
                    offsetY.value = newValue
                }
            }
    )
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectHorizontalDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)` |   |

### AwaitPointerEventScope.drag

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:drag)

```
suspend fun AwaitPointerEventScope.drag(
    pointerId: PointerId,
    onDrag: (PointerInputChange) -> Unit
): Boolean
```

Reads position change events for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` and calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` for every change in position. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` is raised, a new pointer is chosen from those that are down and if none exist, the method returns. This does not wait for touch slop.

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitTouchSlopOrCancellation
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var size by remember { mutableStateOf(Size.Zero) }
Box(Modifier.fillMaxSize().onSizeChanged { size = it.toSize() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .size(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    val change =
                        awaitTouchSlopOrCancellation(down.id) { change, over ->
                            val original = Offset(offsetX.value, offsetY.value)
                            val summed = original + over
                            val newValue =
                                Offset(
                                    x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                                    y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                                )
                            change.consume()
                            offsetX.value = newValue.x
                            offsetY.value = newValue.y
                        }
                    if (change != null) {
                        drag(change.id) {
                            val original = Offset(offsetX.value, offsetY.value)
                            val summed = original + it.positionChange()
                            val newValue =
                                Offset(
                                    x = summed.x.coerceIn(0f, size.width - 50.dp.toPx()),
                                    y = summed.y.coerceIn(0f, size.height - 50.dp.toPx()),
                                )
                            it.consume()
                            offsetX.value = newValue.x
                            offsetY.value = newValue.y
                        }
                    }
                }
            }
    )
}
```

| Returns |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `true` if the drag completed normally or `false` if the drag motion was canceled by another gesture detector consuming position change events. Example Usage: |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |

### DraggableAnchors.forEach

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/AnchoredDraggable.kt+function:forEach) Added in [1.8.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.8.0)

```
inline fun <T : Any?> DraggableAnchors<T>.forEach(block: (key, position: Float) -> Unit): Unit
```

Iterate over all the anchors.

| Parameters |
|---|---|
| `block: (key, position: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | The action to invoke with the key and position |

### PointerInputScope.forEachGesture

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ForEachGesture.kt+function:forEachGesture) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0) Deprecated in [1.4.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.4.0)

```
suspend fun PointerInputScope.[forEachGesture](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).forEachGesture(kotlin.coroutines.SuspendFunction1))(block: suspend PointerInputScope.() -> Unit): Unit
```

> [!CAUTION]
> **This function is deprecated.**   
> Use awaitEachGesture instead. forEachGesture() can drop events between gestures, use this instead:
>
> ```kotlin
> awaitEachGesture(block)
> ```

Repeatedly calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).forEachGesture(kotlin.coroutines.SuspendFunction1)` to handle gestures. If there is a `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.coroutines.cancellation/-cancellation-exception/index.html`, it will wait until all pointers are raised before another gesture is detected, or it exits if `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/index.html` is `false`.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).awaitEachGesture(kotlin.coroutines.SuspendFunction1)` does the same thing without the possibility of missing events between gestures, but also lacks the ability to call arbitrary suspending functions within `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).forEachGesture(kotlin.coroutines.SuspendFunction1)`.

### AwaitPointerEventScope.horizontalDrag

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:horizontalDrag)

```
suspend fun AwaitPointerEventScope.horizontalDrag(
    pointerId: PointerId,
    onDrag: (PointerInputChange) -> Unit
): Boolean
```

Reads horizontal position change events for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` and calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` for every change in position. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` is raised, a new pointer is chosen from those that are down and if none exist, the method returns. This does not wait for touch slop.

Example Usage:

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitHorizontalTouchSlopOrCancellation
import androidx.compose.foundation.gestures.horizontalDrag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var width by remember { mutableStateOf(0f) }
Box(Modifier.fillMaxSize().onSizeChanged { width = it.width.toFloat() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .fillMaxHeight()
            .width(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    val change =
                        awaitHorizontalTouchSlopOrCancellation(down.id) { change, over ->
                            val originalX = offsetX.value
                            val newValue = (originalX + over).coerceIn(0f, width - 50.dp.toPx())
                            change.consume()
                            offsetX.value = newValue
                        }
                    if (change != null) {
                        horizontalDrag(change.id) {
                            val originalX = offsetX.value
                            val newValue =
                                (originalX + it.positionChange().x).coerceIn(
                                    0f,
                                    width - 50.dp.toPx(),
                                )
                            it.consume()
                            offsetX.value = newValue
                        }
                    }
                }
            }
    )
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |

### TransformableState.panBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:panBy)

```
suspend fun TransformableState.panBy(
    offset: Offset,
    centroid: Offset = Offset.Unspecified
): Unit
```

Pan without animation by a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).panBy(androidx.compose.ui.geometry.Offset,androidx.compose.ui.geometry.Offset)` Offset in pixels and suspend until it's set.

| Parameters |
|---|---|
| `offset: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | offset in pixels by which to pan |
| `centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset = Offset.Unspecified` | the `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` around which the pan should occur, if any. The default value is `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Unspecified()`, which leaves the behavior up to the implementation of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState`. |

### TransformableState.rotateBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:rotateBy)

```
suspend fun TransformableState.rotateBy(
    degrees: Float,
    centroid: Offset = Offset.Unspecified
): Unit
```

Rotate without animation by a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).rotateBy(kotlin.Float,androidx.compose.ui.geometry.Offset)` degrees and suspend until it's set.

| Parameters |
|---|---|
| `degrees: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | degrees by which to rotate |
| `centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset = Offset.Unspecified` | the `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` around which the rotation should occur, if any. The default value is `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Unspecified()`, which leaves the behavior up to the implementation of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState`. |

### ScrollableState.scrollBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ScrollExtensions.kt+function:scrollBy)

```
suspend fun ScrollableState.scrollBy(value: Float): Float
```

Jump instantly by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).scrollBy(kotlin.Float)` pixels.

Cancels the currently running scroll, if any, and suspends until the cancellation is complete.

| Parameters |
|---|---|
| `value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | number of pixels to scroll by |

| Returns |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | the amount of scroll consumed |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).animateScrollBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec)` | for an animated version |

### Scrollable2DState.scrollBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ScrollExtensions.kt+function:scrollBy)

```
suspend fun Scrollable2DState.scrollBy(value: Offset): Offset
```

Jump instantly by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.Scrollable2DState).scrollBy(androidx.compose.ui.geometry.Offset)` pixels.

Cancels the currently running scroll, if any, and suspends until the cancellation is complete.

| Parameters |
|---|---|
| `value: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | number of pixels to scroll by |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` | the amount of scroll consumed |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.ScrollableState).animateScrollBy(kotlin.Float,androidx.compose.animation.core.AnimationSpec)` | for an animated version |

### AnchoredDraggableState.snapTo

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/AnchoredDraggable.kt+function:snapTo) Added in [1.6.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.6.0)

```
suspend fun <T : Any?> AnchoredDraggableState<T>.snapTo(targetValue: T): Unit
```

Snap to a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).snapTo(kotlin.Any)` without any animation. If the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).snapTo(kotlin.Any)` is not in the set of anchors, the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#currentValue()` will be updated to the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).snapTo(kotlin.Any)` without updating the offset.

| Parameters |
|---|---|
| `targetValue: T` | The target value of the animation |

| Throws |
|---|---|
| `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-cancellation-exception/index.html` | if the interaction interrupted by another interaction like a gesture interaction or another programmatic interaction like a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).animateTo(kotlin.Float,androidx.compose.foundation.gestures.AnchoredDragScope,androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Any,androidx.compose.animation.core.AnimationSpec)` or `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.AnchoredDraggableState).snapTo(kotlin.Any)` call. |

### ScrollableState.stopScroll

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ScrollExtensions.kt+function:stopScroll) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun ScrollableState.stopScroll(
    scrollPriority: MutatePriority = MutatePriority.Default
): Unit
```

Stop and suspend until any ongoing animation, smooth scrolling, fling, or any other scroll occurring via `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` is terminated.

| Parameters |
|---|---|
| `scrollPriority: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MutatePriority = MutatePriority.Default` | scrolls that run with this priority or lower will be stopped |

### Scrollable2DState.stopScroll

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/ScrollExtensions.kt+function:stopScroll) Added in [1.9.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.9.0)

```
suspend fun Scrollable2DState.stopScroll(
    scrollPriority: MutatePriority = MutatePriority.Default
): Unit
```

Stop and suspend until any ongoing animation, smooth scrolling, fling, or any other scroll occurring via `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` is terminated.

| Parameters |
|---|---|
| `scrollPriority: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MutatePriority = MutatePriority.Default` | scrolls that run with this priority or lower will be stopped |

### TransformableState.stopTransformation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:stopTransformation) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun TransformableState.stopTransformation(
    terminationPriority: MutatePriority = MutatePriority.Default
): Unit
```

Stop and suspend until any ongoing `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState#transform(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` with priority `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).stopTransformation(androidx.compose.foundation.MutatePriority)` or lower is terminated.

| Parameters |
|---|---|
| `terminationPriority: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MutatePriority = MutatePriority.Default` | transformation that runs with this priority or lower will be stopped |

### AwaitPointerEventScope.verticalDrag

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/DragGestureDetector.kt+function:verticalDrag)

```
suspend fun AwaitPointerEventScope.verticalDrag(
    pointerId: PointerId,
    onDrag: (PointerInputChange) -> Unit
): Boolean
```

Reads vertical position change events for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` and calls `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` for every change in position. If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).verticalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` is raised, a new pointer is chosen from those that are down and if none exist, the method returns. This does not wait for touch slop

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitVerticalTouchSlopOrCancellation
import androidx.compose.foundation.gestures.verticalDrag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

val offsetX = remember { mutableStateOf(0f) }
val offsetY = remember { mutableStateOf(0f) }
var height by remember { mutableStateOf(0f) }
Box(Modifier.fillMaxSize().onSizeChanged { height = it.height.toFloat() }) {
    Box(
        Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
            .fillMaxWidth()
            .height(50.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                awaitEachGesture {
                    val down = awaitFirstDown()
                    val change =
                        awaitVerticalTouchSlopOrCancellation(down.id) { change, over ->
                            val originalY = offsetY.value
                            val newValue =
                                (originalY + over).coerceIn(0f, height - 50.dp.toPx())
                            change.consume()
                            offsetY.value = newValue
                        }
                    if (change != null) {
                        verticalDrag(change.id) {
                            val originalY = offsetY.value
                            val newValue =
                                (originalY + it.positionChange().y).coerceIn(
                                    0f,
                                    height - 50.dp.toPx(),
                                )
                            it.consume()
                            offsetY.value = newValue
                        }
                    }
                }
            }
    )
}
```

| Returns |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `true` if the vertical drag completed normally or `false` if the drag motion was canceled by another gesture detector consuming position change events. Example Usage: |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.PointerId,kotlin.Function2)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.PointerId)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).horizontalDrag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).drag(androidx.compose.ui.input.pointer.PointerId,kotlin.Function1)` |   |

### AwaitPointerEventScope.waitForUpOrCancellation

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TapGestureDetector.kt+function:waitForUpOrCancellation)

```
suspend fun AwaitPointerEventScope.waitForUpOrCancellation(
    pass: PointerEventPass = PointerEventPass.Main
): PointerInputChange?
```

Reads events in the given `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.AwaitPointerEventScope).waitForUpOrCancellation(androidx.compose.ui.input.pointer.PointerEventPass)` until all pointers are up or the gesture was canceled. The gesture is considered canceled when a pointer leaves the event region, a position change has been consumed or a pointer down change event was already consumed in the given pass. If the gesture was not canceled, the final up change is returned or `null` if the event was canceled.

### TransformableState.zoomBy

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/TransformableState.kt+function:zoomBy)

```
suspend fun TransformableState.zoomBy(
    zoomFactor: Float,
    centroid: Offset = Offset.Unspecified
): Unit
```

Zoom without animation by a ratio of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.foundation.gestures.TransformableState).zoomBy(kotlin.Float,androidx.compose.ui.geometry.Offset)` over the current size and suspend until it's set.

| Parameters |
|---|---|
| `zoomFactor: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | ratio over the current size by which to zoom |
| `centroid: https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset = Offset.Unspecified` | the `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` around which the zoom should occur, if any. The default value is `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset#Unspecified()`, which leaves the behavior up to the implementation of the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/TransformableState`. |

## Top-level properties

### LocalBringIntoViewSpec

Cmn android Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/gestures/BringIntoViewSpec.+symbol:LocalBringIntoViewSpec)

```
val LocalBringIntoViewSpec: ProvidableCompositionLocal<BringIntoViewSpec>
```

A composition local to customize the focus scrolling behavior used by some scrollable containers. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#LocalBringIntoViewSpec()` has a platform defined default behavior.