Skip to content
Kapow
Esc
↑↓navigate↵open⌘Jpreview
On this page

Change: rise

A label such as +1 floats up from an element when a value changes.

Rise floats one particle, usually a short label, up from the element. It suits counters: a score that gained points, a cart that gained an item.

Usage

The sample floats a +1 in green each time the cart count changes.

import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.jantursky.kapow.ChangeEffect
import com.jantursky.kapow.ParticleContent
import com.jantursky.kapow.changeEffect

@Composable
fun CartCount(items: Int) {
    BasicText(
        text = "Cart: $items",
        modifier = Modifier.changeEffect(
            value = items,
            effect = ChangeEffect.rise(
                ParticleContent.text(
                    "+1",
                    TextStyle(color = Color(0xFF7EE2A8), fontSize = 18.sp, fontWeight = FontWeight.SemiBold),
                ),
            ),
        ),
    )
}

Parameters

Parameter Default Description
particles ParticleContent.text("+1") What floats up. ParticleContent.text(text, style) draws a label, and the default style is 16 sp semibold amber. ParticleContent.painter(...) draws an icon. ParticleContent.shape(...) also works.
distance Dp.Unspecified About how far the particle floats before it expires. Unspecified keeps the standard 44 dp. Must be positive.
duration 1200.milliseconds How long the particle lives. Must be positive.
drift 0f The heading in degrees away from straight up. Positive leans right.
wobble 4.dp How far the particle sways from side to side. Must not be negative.
startOffset DpOffset.Zero Where the particle starts, measured from anchor.
scaleIn 0.4f The size the particle is born at, as a fraction of its full size. It grows to full size over the first 15 % of its life. From 0 to 1.
scaleOut 1f The size factor at the end of its life: 1 stays full size, 0.5 shrinks to half.
fade null An Easing that maps life progress to how faded the particle is. Null keeps it opaque for the first half of its life, then fades it out.
label null Builds the text for each change from the value that changed, for example { "+$it" }. It applies when particles is ParticleContent.text. Remember the lambda: a new instance makes the effect unequal.
anchor TransformOrigin(0.5f, 0f) Where the particle starts, as fractions of the element’s width and height. The default is the middle of the top edge.

Reduced motion

No label floats. The element brightens briefly. With reducedMotion(ReducedMotionMode.EndState) nothing shows at all, since the effect ends at rest.

Notes

  • Particles draw through a particle layer when one is above the element, so a clipping parent does not cut them off. Without one they draw around the element.
  • Each change emits one particle. Two quick changes float two labels, each on its own.
  • The label drifts up with a slight horizontal wobble and fades out.
  • The label is measured once per emission.
  • To show a different text for each change, pass label, for example label = { "+$it" }. It receives the value that changed.

Live example

Was this page helpful?