
Enhance apps with vibrant, customizable confetti animations using a lightweight library. Features include adjustable speed, direction, colors, shapes, and seamless integration with Compose.
A lightweight Kotlin/Compose Multiplatform library to add vibrant, customizable confetti animations to your apps.
Installation • Quick start • Documentation • Recipes • Sample project
This library is based on the incredible work of @DanielMartinus on his Android Konfetti library and has been adapted for Kotlin Multiplatform and Compose Multiplatform.
dependencies {
implementation("io.github.vinceglb:confettikit:0.8.0")
}ConfettiKit requires Kotlin 2.1.0 or higher.
The simplest way to get the party started is:
ConfettiKit(
modifier = Modifier.fillMaxSize(),
parties = listOf(
Party(emitter = Emitter(duration = 5.seconds).perSecond(30))
)
)That's it! You've got confetti! 🎊
A Party configuration object controls every aspect of your confetti animation. While you only need an Emitter to get started, understanding each property helps you create exactly the effect you want.
Party(
angle = 90, // Straight up
spread = 45, // 45-degree spread
)The direction and spread of your confetti is controlled by several properties:
angle
Angle.TOP, Angle.RIGHT, Angle.BOTTOM, Angle.LEFT
spread
Spread.SMALL, Spread.WIDE and Spread.ROUND
Party(
speed = 20f, // Base speed
maxSpeed = 30f, // Maximum speed
damping = 0.95f // Speed decay
)Control how fast your confetti moves and how it slows down:
speed
maxSpeed
speed and maxSpeed
damping
Party(
colors = listOf(0xfce18a, 0xff726d, 0xf4306d),
shapes = listOf(Shape.Square, Shape.Circle),
size = listOf(Size.SMALL, Size.MEDIUM)
)Customize how your confetti looks:
colors
shapes
Shape.Circle, Shape.Square, and Shape.Rectangle(heightRatio)
Shape.CustomShape(shape) for any Compose shapeShape.Image(imageBitmap) for bitmap images as confettiShape.Vector(vectorPainter) for vector graphics as confettisizes
Size.SMALL, Size.MEDIUM and Size.LARGE
Party(
timeToLive = 3000, // 3 seconds lifetime
fadeOutEnabled = true, // Fade out at end
delay = 500, // Start after 500ms
position = Position.Relative(0.5, 0.5),
rotation = Rotation.enabled()
)Control the timing and behavior of your confetti:
timeToLive
fadeOutEnabled
delay
position
rotation
Rotation.enabled() to enable rotationRotation.disabled() to disable rotationThe Emitter controls how many pieces of confetti are created and how often:
// Burst of 100 pieces over 100ms
Emitter(duration = 100, TimeUnit.MILLISECONDS).max(100)
// Continuous stream of 30 pieces per second for 5 seconds
Emitter(duration = 5, TimeUnit.SECONDS).perSecond(30)ConfettiKit is designed to work seamlessly with Compose. You can use it as a Composable function in your UI:
ConfettiKit(
modifier = Modifier.fillMaxSize(),
parties = parties,
onParticleSystemStarted = { system, activeSystems ->
// Called when a party animation starts
},
onParticleSystemEnded = { system, activeSystems ->
// Called when a party animation ends
}
)onParticleSystemStarted
PartySystem that started and the count of currently active systemsonParticleSystemEnded
PartySystem that ended and the count of remaining active systemsCreate a burst of confetti that explodes from a single point:
fun explode(): List<Party> {
return listOf(
Party(
speed = 0f,
maxSpeed = 30f,
damping = 0.9f,
spread = 360,
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
emitter = Emitter(duration = 100.milliseconds).max(100),
)
)
}Create a parade of confetti that moves from one side of the screen to the other:
fun parade(): List<Party> {
val party = Party(
speed = 10f,
maxSpeed = 30f,
damping = 0.9f,
angle = Angle.RIGHT - 45,
spread = Spread.SMALL,
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
emitter = Emitter(duration = 5.seconds).perSecond(30),
position = Position.Relative(0.0, 0.5)
)
return listOf(
party,
party.copy(
angle = party.angle - 90, // flip angle from right to left
position = Position.Relative(1.0, 0.5)
),
)
}Create a gentle rain of confetti that falls from the top of the screen:
fun rain(): List<Party> {
return listOf(
Party(
speed = 0f,
maxSpeed = 15f,
damping = 0.9f,
angle = Angle.BOTTOM,
spread = Spread.ROUND,
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
emitter = Emitter(duration = 3.5.seconds).perSecond(100),
position = Position.Relative(0.0, 0.0).between(Position.Relative(1.0, 0.0))
)
)
}Create confetti with custom shapes, images, or vectors:
fun customShapes(): List<Party> {
return listOf(
Party(
speed = 15f,
maxSpeed = 25f,
damping = 0.9f,
spread = 360,
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
shapes = listOf(
// Custom Compose shapes
Shape.CustomShape(RoundedCornerShape(8.dp)),
Shape.CustomShape(CircleShape),
// Images as confetti
Shape.Image(imageBitmap),
// Vector graphics
Shape.Vector(vectorPainter)
),
emitter = Emitter(duration = 3.seconds).perSecond(50),
)
)
}Check out the sample project for a complete example of how to use ConfettiKit in your app.
Made with ❤️ by Vince
A lightweight Kotlin/Compose Multiplatform library to add vibrant, customizable confetti animations to your apps.
Installation • Quick start • Documentation • Recipes • Sample project
This library is based on the incredible work of @DanielMartinus on his Android Konfetti library and has been adapted for Kotlin Multiplatform and Compose Multiplatform.
dependencies {
implementation("io.github.vinceglb:confettikit:0.8.0")
}ConfettiKit requires Kotlin 2.1.0 or higher.
The simplest way to get the party started is:
ConfettiKit(
modifier = Modifier.fillMaxSize(),
parties = listOf(
Party(emitter = Emitter(duration = 5.seconds).perSecond(30))
)
)That's it! You've got confetti! 🎊
A Party configuration object controls every aspect of your confetti animation. While you only need an Emitter to get started, understanding each property helps you create exactly the effect you want.
Party(
angle = 90, // Straight up
spread = 45, // 45-degree spread
)The direction and spread of your confetti is controlled by several properties:
angle
Angle.TOP, Angle.RIGHT, Angle.BOTTOM, Angle.LEFT
spread
Spread.SMALL, Spread.WIDE and Spread.ROUND
Party(
speed = 20f, // Base speed
maxSpeed = 30f, // Maximum speed
damping = 0.95f // Speed decay
)Control how fast your confetti moves and how it slows down:
speed
maxSpeed
speed and maxSpeed
damping
Party(
colors = listOf(0xfce18a, 0xff726d, 0xf4306d),
shapes = listOf(Shape.Square, Shape.Circle),
size = listOf(Size.SMALL, Size.MEDIUM)
)Customize how your confetti looks:
colors
shapes
Shape.Circle, Shape.Square, and Shape.Rectangle(heightRatio)
Shape.CustomShape(shape) for any Compose shapeShape.Image(imageBitmap) for bitmap images as confettiShape.Vector(vectorPainter) for vector graphics as confettisizes
Size.SMALL, Size.MEDIUM and Size.LARGE
Party(
timeToLive = 3000, // 3 seconds lifetime
fadeOutEnabled = true, // Fade out at end
delay = 500, // Start after 500ms
position = Position.Relative(0.5, 0.5),
rotation = Rotation.enabled()
)Control the timing and behavior of your confetti:
timeToLive
fadeOutEnabled
delay
position
rotation
Rotation.enabled() to enable rotationRotation.disabled() to disable rotationThe Emitter controls how many pieces of confetti are created and how often:
// Burst of 100 pieces over 100ms
Emitter(duration = 100, TimeUnit.MILLISECONDS).max(100)
// Continuous stream of 30 pieces per second for 5 seconds
Emitter(duration = 5, TimeUnit.SECONDS).perSecond(30)ConfettiKit is designed to work seamlessly with Compose. You can use it as a Composable function in your UI:
ConfettiKit(
modifier = Modifier.fillMaxSize(),
parties = parties,
onParticleSystemStarted = { system, activeSystems ->
// Called when a party animation starts
},
onParticleSystemEnded = { system, activeSystems ->
// Called when a party animation ends
}
)onParticleSystemStarted
PartySystem that started and the count of currently active systemsonParticleSystemEnded
PartySystem that ended and the count of remaining active systemsCreate a burst of confetti that explodes from a single point:
fun explode(): List<Party> {
return listOf(
Party(
speed = 0f,
maxSpeed = 30f,
damping = 0.9f,
spread = 360,
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
emitter = Emitter(duration = 100.milliseconds).max(100),
)
)
}Create a parade of confetti that moves from one side of the screen to the other:
fun parade(): List<Party> {
val party = Party(
speed = 10f,
maxSpeed = 30f,
damping = 0.9f,
angle = Angle.RIGHT - 45,
spread = Spread.SMALL,
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
emitter = Emitter(duration = 5.seconds).perSecond(30),
position = Position.Relative(0.0, 0.5)
)
return listOf(
party,
party.copy(
angle = party.angle - 90, // flip angle from right to left
position = Position.Relative(1.0, 0.5)
),
)
}Create a gentle rain of confetti that falls from the top of the screen:
fun rain(): List<Party> {
return listOf(
Party(
speed = 0f,
maxSpeed = 15f,
damping = 0.9f,
angle = Angle.BOTTOM,
spread = Spread.ROUND,
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
emitter = Emitter(duration = 3.5.seconds).perSecond(100),
position = Position.Relative(0.0, 0.0).between(Position.Relative(1.0, 0.0))
)
)
}Create confetti with custom shapes, images, or vectors:
fun customShapes(): List<Party> {
return listOf(
Party(
speed = 15f,
maxSpeed = 25f,
damping = 0.9f,
spread = 360,
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
shapes = listOf(
// Custom Compose shapes
Shape.CustomShape(RoundedCornerShape(8.dp)),
Shape.CustomShape(CircleShape),
// Images as confetti
Shape.Image(imageBitmap),
// Vector graphics
Shape.Vector(vectorPainter)
),
emitter = Emitter(duration = 3.seconds).perSecond(50),
)
)
}Check out the sample project for a complete example of how to use ConfettiKit in your app.
Made with ❤️ by Vince