# InProgressStrokes

## Functions summary

|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/InProgressStrokes.composable#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)( defaultBrush: https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush?, nextBrush: () -> https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush?, pointerEventToWorldTransform: https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Matrix, strokeToWorldTransform: https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Matrix, maskPath: https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Path?, textureBitmapStore: https://developer.android.com/reference/kotlin/androidx/ink/brush/TextureBitmapStore, onStrokesFinished: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html<https://developer.android.com/reference/kotlin/androidx/ink/strokes/Stroke>) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable` that displays in-progress ink strokes as it receives user pointer input. |

## Functions

### InProgressStrokes

Artifact: [androidx.ink:ink-authoring-compose](https://developer.android.com/jetpack/androidx/releases/ink) [View Source](https://cs.android.com/search?q=file:androidx/ink/authoring/compose/InProgressStrokes.kt+function:InProgressStrokes)

```
@Composable
fun InProgressStrokes(
    defaultBrush: Brush?,
    nextBrush: () -> Brush? = { defaultBrush },
    pointerEventToWorldTransform: Matrix = IDENTITY_MATRIX,
    strokeToWorldTransform: Matrix = IDENTITY_MATRIX,
    maskPath: Path? = null,
    textureBitmapStore: TextureBitmapStore = TextureBitmapStore { null },
    onStrokesFinished: (List<Stroke>) -> Unit
): Unit
```

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable` that displays in-progress ink strokes as it receives user pointer input.

Multiple simultaneous strokes are supported. This implementation handles all best practices for the fastest, lowest latency rendering of real-time user input. For an alternative compatible with Android Views, see `https://developer.android.com/reference/kotlin/androidx/ink/authoring/InProgressStrokesView`.

For performance reasons, it is recommended to only have one `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable` on screen at a time, and to avoid unnecessarily resizing it or changing whether it is present on screen.

This will process pointers (and display the resulting strokes) that are not already consumed by an earlier touch listener - when `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerInputChange#isConsumed()` is `false`. If a pointer's down event arrives to this composable already consumed, it will not be drawn, even if later events for that pointer arrive unconsumed. If a pointer's initial events are not consumed by arrival, then it will be drawn, but if its later events have been consumed by arrival then the stroke for that pointer will be canceled and removed from this composable's UI. If all of a pointer's events from down through moves through up arrive to this composable unconsumed, then the entire stroke will be drawn and finished, and the finished stroke will be made available by a call to `https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/package-summary#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)`. All strokes that were in progress simultaneously will be delivered in the same callback, running on the UI thread. To avoid visual flicker when transitioning rendering from this composable to another composable, during this callback the finished strokes must be added to some mutable state that triggers a recomposition that will render those strokes, typically using `https://developer.android.com/reference/kotlin/androidx/ink/rendering/android/canvas/CanvasStrokeRenderer`.

| Parameters |
|---|---|
| `defaultBrush: https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush?` | `https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush` specification for the stroke being started. If this is `null`, nothing will be drawn, but the internal rendering resources will be preserved to avoid paying the cost for reinitialization when drawing is needed again. If different `https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush` values are needed for different simultaneous strokes, use `https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/package-summary#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)` to return a different `https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush` each time. Note that the overall scaling factor of `https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/package-summary#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)` and `https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/package-summary#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)` combined should be related to the value of `https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush#epsilon()` - in general, the larger the combined `pointerEventToStrokeTransform` scaling factor is, the smaller on screen the stroke units are, so `https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush#epsilon()` should be a larger quantity of stroke units to maintain a similar screen size. |
| `nextBrush: () -> https://developer.android.com/reference/kotlin/androidx/ink/brush/Brush? = { defaultBrush }` | A way to override `https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/package-summary#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)`, which will be called at the start of each pointer. |
| `pointerEventToWorldTransform: https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Matrix = IDENTITY_MATRIX` | The matrix that transforms `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/PointerEvent` coordinates into the caller's "world" coordinates, which typically is defined by how the caller's document is panned/zoomed/rotated. This defaults to the identity matrix, in which case the world coordinate space is the same as the input event coordinates, but the caller should pass in their own value reflecting a coordinate system that is independent of the device's pixel density (e.g. scaled by 1 / `https://developer.android.com/reference/android/util/DisplayMetrics.html#density`) and any pan/zoom/rotate gestures that have been applied to the "camera" which portrays the "world" on the device screen. This matrix must be invertible. |
| `strokeToWorldTransform: https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Matrix = IDENTITY_MATRIX` | Allows an object-specific (stroke-specific) coordinate space to be defined in relation to the caller's "world" coordinate space. This defaults to the identity matrix, which is typical for many use cases at the time of stroke construction. In typical use cases, stroke coordinates and world coordinates may start to differ from one another only after stroke authoring as a finished stroke is manipulated within the world, e.g. it may be moved, scaled, or rotated relative to other content within an app's document. This matrix must be invertible. |
| `maskPath: https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Path? = null` | An area of this composable where no ink will be visible. A value of `null` indicates that strokes will be visible anywhere they are drawn. This is useful for UI elements that float on top of (in Z order) the drawing surface - without this, a user would be able to draw in-progress ("wet") strokes on top of those UI elements, but then when the stroke is finished, it will appear as a dry stroke underneath of the UI element. If this mask is set to the shape and position of the floating UI element, then the ink will never be rendered in that area, making it appear as if it's being drawn underneath the UI element. This technique is most convincing when the UI element is opaque. Often there are parts of the UI element that are translucent, such as drop shadows, or anti-aliasing along the edges. The result will look a little different between wet and dry strokes for those cases, but it can be a worthwhile tradeoff compared to the alternative of drawing wet strokes on top of that UI element. Note that this parameter does not affect the contents of the strokes at all, nor how they appear when drawn in a separate composable after `https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/package-summary#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)` is called - just how the strokes appear when they are still in progress in this composable. |
| `textureBitmapStore: https://developer.android.com/reference/kotlin/androidx/ink/brush/TextureBitmapStore = TextureBitmapStore { null }` | Allows texture asset images to be loaded, corresponding to texture layers that may be specified by `https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/package-summary#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)` or `https://developer.android.com/reference/kotlin/androidx/ink/authoring/compose/package-summary#InProgressStrokes(androidx.ink.brush.Brush,kotlin.Function0,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Matrix,androidx.compose.ui.graphics.Path,androidx.ink.brush.TextureBitmapStore,kotlin.Function1)`. |
| `onStrokesFinished: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html<https://developer.android.com/reference/kotlin/androidx/ink/strokes/Stroke>) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | Called when there are no longer any in-progress strokes for a short period. All strokes that were in progress simultaneously will be delivered in the same callback, running on the UI thread. The callback should pass the strokes to another `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable`, triggering its recomposition within the same UI thread run loop as the callback being received, for that other `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable` to render the strokes without any brief rendering errors (flickers). These flickers may come from a gap where a stroke is drawn in neither this `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable` nor the app's `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable` during a frame, or a double draw where the stroke is drawn twice and translucent strokes appear more opaque than they should. Be careful about passing strokes to asynchronous frameworks during this callback, as they may switch threads during the handoff from producer to consumer, and even if the final consumer is on the UI thread, it may not be in the same UI thread run loop and lead to a flicker. |