---
title: "keyframesWithSpline"
description: "Creates a [KeyframesWithSplineSpec] animation, initialized with [init].

For more details on implementation, see [KeyframesWithSplineSpec].

Use overload that takes a [Float] parameter to use periodic splines."
type: "function"
---

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


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


```kotlin
public fun <T> keyframesWithSpline(
    init: KeyframesWithSplineSpec.KeyframesWithSplineSpecConfig<T>.() -> Unit
): KeyframesWithSplineSpec<T>
```


Creates a `KeyframesWithSplineSpec` animation, initialized with `init`.

For more details on implementation, see `KeyframesWithSplineSpec`.

Use overload that takes a `Float` parameter to use periodic splines.

#### Parameters

| | |
| --- | --- |
| init | Initialization function for the `KeyframesWithSplineSpec` animation |




<div class='sourceset sourceset-common'>Common</div>


```kotlin
public fun <T> keyframesWithSpline(
    @FloatRange(0.0, 1.0) periodicBias: Float,
    init: KeyframesWithSplineSpec.KeyframesWithSplineSpecConfig<T>.() -> Unit,
): KeyframesWithSplineSpec<T>
```


Creates a *periodic* `KeyframesWithSplineSpec` animation, initialized with `init`.

Use overload without `periodicBias` parameter for the non-periodic implementation.

A periodic spline is one such that the starting and ending velocities are equal. This makes them
useful to create smooth repeatable animations. Such as an infinite pulsating animation:


The `periodicBias` value (from 0.0 to 1.0) indicates how much of the original starting and final
velocity are modified to achieve periodicity:
- 0f: Modifies only the starting velocity to match the final velocity
- 1f: Modifies only the final velocity to match the starting velocity
- 0.5f: Modifies both velocities equally, picking the average between the two

#### Parameters

| | |
| --- | --- |
| periodicBias | A value from 0f to 1f, indicating how much the starting or ending velocities are modified respectively to achieve periodicity. |
| init | Initialization function for the `KeyframesWithSplineSpec` animation |




## Code Examples
### KeyframesBuilderForDpOffsetWithSplines
```kotlin
@OptIn(ExperimentalAnimationSpecApi::class)
fun KeyframesBuilderForDpOffsetWithSplines() {
    keyframesWithSpline {
        durationMillis = 200
        DpOffset(0.dp, 0.dp) at 0
        DpOffset(500.dp, 100.dp) at 100
        DpOffset(400.dp, 50.dp) at 150
    }
}
```
### KeyframesBuilderForIntOffsetWithSplines
```kotlin
@OptIn(ExperimentalAnimationSpecApi::class)
fun KeyframesBuilderForIntOffsetWithSplines() {
    keyframesWithSpline {
        durationMillis = 200
        IntOffset(0, 0) at 0
        IntOffset(500, 100) at 100
        IntOffset(400, 50) at 150
    }
}
```
### KeyframesBuilderForOffsetWithSplines
```kotlin
@OptIn(ExperimentalAnimationSpecApi::class)
fun KeyframesBuilderForOffsetWithSplines() {
    keyframesWithSpline {
        durationMillis = 200
        Offset(0f, 0f) at 0
        Offset(500f, 100f) at 100
        Offset(400f, 50f) at 150
    }
}
```
### PeriodicKeyframesWithSplines
```kotlin
@OptIn(ExperimentalAnimationSpecApi::class)
@Composable
fun PeriodicKeyframesWithSplines() {
    var alpha by remember { mutableFloatStateOf(0f) }
    LaunchedEffect(Unit) {
        animate(
            initialValue = 0f,
            targetValue = 0f,
            animationSpec =
                infiniteRepeatable(
                    // With a periodicBias of 0.5f it creates a similar animation to a sinusoidal
                    // curve
                    // so the transition as the animation repeats is completely seamless
                    animation =
                        keyframesWithSpline(periodicBias = 0.5f) {
                            durationMillis = 2000
                            1f at 1000 using LinearEasing
                        },
                    repeatMode = RepeatMode.Restart,
                ),
        ) { value, _ ->
            alpha = value
        }
    }
    Image(
        imageVector = Icons.Filled.Favorite,
        contentDescription = null,
        modifier = Modifier.size(150.dp).graphicsLayer { this.alpha = alpha },
        colorFilter = ColorFilter.tint(Color.Red),
    )
}
```

