---
title: "awaitDragOrCancellation"
description: "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 [pointerId] has been raised, another pointer that is down will be used,
if available, so the returned [PointerInputChange.id] may differ from [pointerId]. If the
position change in the any direction has been consumed by the [PointerEventPass.Main] pass, then
the drag is considered canceled and `null` is returned. If [pointerId] is not down when
[awaitDragOrCancellation] is called, then `null` is returned.

Example Usage:"
type: "function"
---

<div class='type'>Function</div>


<a id='references'></a>
<div class='sourceset sourceset-common'>Common</div>


```kotlin
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 `pointerId` has been raised, another pointer that is down will be used,
if available, so the returned `PointerInputChange.id` may differ from `pointerId`. If the
position change in the any direction has been consumed by the `PointerEventPass.Main` pass, then
the drag is considered canceled and `null` is returned. If `pointerId` is not down when
`awaitDragOrCancellation` is called, then `null` is returned.

Example Usage:



## Code Examples
### AwaitDragOrCancellationSample
```kotlin
@Composable
fun AwaitDragOrCancellationSample() {
    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
                            }
                        }
                    }
                }
        )
    }
}
```

