Jetpack Compose animation playgrounds. Tweak literals at the top of any file, save, and watch the motion morph in front of you.
This project was built to tune and demonstrate Jetpack Compose animations on a real Android device, using Compose HotSwan as the live editing loop. Animations are physical: a damping ratio of 0.6 versus 0.8, an easing of FastOutSlowIn versus EaseOutBack, a particle gravity of 1100 vs. 1800. None of those choices reads off the page. You feel them on the device, and the only way to find the right number is to keep changing it and looking at the result.
Every example here is a single composable file with its tunable values named as vals at the top of the function: durations, easings, stiffness, color palettes, particle counts. You change a number, save the file, and the running app picks up the new value within milliseconds, without rebuilding the project or losing your place in the navigation stack. The thinking behind this loop and how it changes the way you author animations is covered in Compose Animation: Hot Reload.
You can also run this app as a regular Compose project without Compose HotSwan, but the per parameter tuning loop is what the examples are designed around. In this repository, you'll find multiple self contained examples covering core animation APIs (animate*AsState, AnimatedContent, AnimatedVisibility, Animatable, rememberInfiniteTransition, updateTransition, SharedTransitionLayout), gesture driven motion, Canvas simulations, and physical effects.
To edit values and see changes live without rebuilding:
- Install the Compose HotSwan plugin following the install guides, or expand the section below for the same steps inline.
- Run this project, and start Compose HotSwan.
- Open any animation example file and edit the constants near the top of the function.
- Save the file. Done. You will see the Compose UI is changing on a running Android app without re-compiling, re-installing, or re-navigating, just in ~100ms.
Or follow the below instructions
1. Install the IDE Plugin
Open your JetBrains IDE (Android Studio or IntelliJ IDEA), go to Settings → Plugins → Marketplace, and search for "Compose HotSwan". Click Install and restart the IDE.
You can also install it directly from the JetBrains Marketplace.
Kotlin Multiplatform? If your project uses Kotlin Multiplatform, see the Kotlin Multiplatform guide for KMP specific setup and module configuration.
2. Configure Gradle
Add the HotSwan compiler plugin to your project. Three files need to be updated.
libs.versions.toml:
[plugins]
hotswan-compiler = { id = "com.github.skydoves.compose.hotswan.compiler", version = "1.3.0" }Root build.gradle.kts:
alias(libs.plugins.hotswan.compiler) apply falseApp module build.gradle.kts:
alias(libs.plugins.hotswan.compiler)IDE and Gradle versions must match. The Gradle plugin version must match the IDE plugin version. When you update the IDE plugin, update the version in
libs.versions.tomlas well.
3. Build and Run Your App
Build and run your app normally with the Run button. The Gradle plugin auto configures everything needed for hot reload in debug builds, no additional setup required.
4. Start HotSwan
Open the HotSwan panel via View → Tool Windows → HotSwan. Select your target device and click Start. The status will change to READY.
Once your app is running on the device, HotSwan connects automatically and the status changes to WATCHING.
5. Start Hot Reloading
Edit any Kotlin file and save (Cmd+S / Ctrl+S). HotSwan detects the change, compiles only the modified code, and applies the update to your running app. Your UI updates instantly without losing any state.
If you skip step 1, the app still runs as a normal Compose app.
Every animation here has a written walkthrough at doveletter.dev/docs/compose-animations. The page covers every entry in the gallery below, with the underlying APIs, the constants you can tune, and the reasoning behind each spec.
Each example below is a single file. Open the source link to see the constants you can tweak.
Expandable card that morphs height between two Dp values. Uses animateDpAsState with tween so the unfold timing reads as a single curve.
- Try tweaking:
EXPAND_DURATION_MS,EXPAND_EASING,COLLAPSED_HEIGHT,EXPANDED_HEIGHT. - Source:
AnimationExample1.kt - Article: Animate Content Size. Demonstrates how
animateDpAsStatewith a tween spec drives an expandable card's height transition, comparingFastOutSlowInEasingandLinearEasingto shape perceived motion between two fixedDpendpoints.
Enter and exit transitions composed from slideIn, fadeIn, scaleIn. A toggle flips the visibility, the spec defines the choreography.
- Try tweaking:
ANIM_DURATION_MS,SLIDE_FROM_RIGHT, the chosenslideIn/fadeIn/scaleIncombinators. - Source:
AnimationExample2.kt - Article: Animated Visibility. Explores how the
+operator composesslideInHorizontally,fadeIn, andscaleIninto parallel enter transitions insideAnimatedVisibility, with shared duration and direction giving synchronized choreography across multiple effects.
animateColorAsState walking through a palette of named theme colors. Pick a swatch, the background and accents follow.
- Try tweaking:
COLOR_TRANSITION_MS, the entries insidePALETTE. - Source:
AnimationExample3.kt - Article: Color State Morph. Uses
animateColorAsStateto interpolate between palette colors via color-space-aware conversion, with transitions triggered purely by state updates rather than explicit animation control.
A floating action button that grows, rotates, and shifts color when toggled. Scale, corner radius, rotation, and color all run through animateAsState with spring.
- Try tweaking:
springStiffness,springDampingRatio, target sizes and corners. - Source:
AnimationExample4.kt - Article: FAB Spring Morph. Applies spring physics with
Spring.StiffnessMediumLowandSpring.DampingRatioMediumBouncyacross four independentanimateAsStatechannels, morphing a FAB's size, rotation, corner radius, and color in lockstep.
A number counter that slides and fades between values using AnimatedContent. The transition direction follows whether the count went up or down.
- Try tweaking:
slideOffsetDivisor, slide and fade durations, theSizeTransformeasing. - Source:
AnimationExample5.kt - Article: Animated Counter. Reads direction from
targetStateandinitialStateinsideAnimatedContent'stransitionSpec, composingslideInVerticallyandfadeInper direction so digit swaps feel like climbing or falling.
Crossfade between three selectable panels. The animation spec controls how snappy or lazy the swap feels.
- Try tweaking: the
animationSpecpassed toCrossfade, the panel content. - Source:
AnimationExample6.kt - Article: Crossfade Switcher. Treats
Crossfadeas the simplest opacity-only content swap and shows how a singleanimationSpecargument controls the entire perceptual weight of the swap without geometric complications.
rememberInfiniteTransition driving scale and alpha at the same time. The result is a soft heartbeat with a bright on, dim off rhythm.
- Try tweaking:
PULSE_MIN_SCALE,PULSE_MAX_SCALE,PULSE_DURATION_MS,RepeatMode. - Source:
AnimationExample7.kt - Article: Pulsing Heart. Builds synchronized infinite motion through
rememberInfiniteTransitionandanimateFloatcalls withRepeatMode.Reverse, letting two properties (scale and alpha) pulse in lockstep without any state changes.
A loading indicator built from infinite rotation plus a color sweep. Shows how to layer two infinite transitions on the same graphicsLayer.
- Try tweaking: rotation duration, color list, sweep keyframes.
- Source:
AnimationExample8.kt - Article: Custom Loading Spinner. Composes two infinite animations (rotation and color sweep) on a single
rememberInfiniteTransitionwith intentionally mismatched durations to prevent visual repetition while keeping the cost in the draw phase.
A box you can drag with pointerInput, then release to spring back to origin via Animatable.animateTo. Tuning stiffness flips the feel between snap and wobble.
- Try tweaking:
SPRING_STIFFNESS,SPRING_DAMPING, the target position on release. - Source:
AnimationExample9.kt - Article: Spring Drag Box. Pairs
Animatable.snapTofor one-to-one gesture tracking withanimateTousing spring physics for the release rebound, letting the same state holder bridge manual writes and physics-driven motion.
Six runners race side by side, each using a different Easing. The strip makes the difference between linear, ease in, ease out, fast out slow in, anticipate, overshoot visible at a glance.
- Try tweaking: swap any
Easingfunction in the entries list, changeRACE_DURATION_MS. - Source:
AnimationExample10.kt - Article: Easing Showcase. Races six
animateFloatAsStateanimations with identical targets but differentEasingcurves (LinearEasing,FastOutSlowInEasing,CubicBezierEasing) to isolate how easing defines perceived motion character independent of duration.
A play triangle that morphs into a pause pair through Path interpolation on a Canvas. The shape itself is the animation, no sprite swap.
- Try tweaking:
MORPH_DURATION_MS, the source and target path coordinates, fill colors. - Source:
AnimationExample11.kt - Article: Play / Pause Morph. Treats icon morphing as geometry interpolation using
Canvasand per-vertexlerpon matched point lists, driving both the shape and the background color from a singleanimateFloatAsStatefraction.
Tap a card and watch it expand into a detail view through SharedTransitionLayout. Matching keys on the source and destination tie their bounds together.
- Try tweaking:
BOUNDS_DURATION_MS,BOUNDS_EASING,DETAIL_HEIGHT_DP, the card list. - Source:
AnimationExample12.kt - Article: Shared Bounds Expansion. Uses
SharedTransitionLayoutwithrememberSharedContentStateto correlate source and destination cards by key, then letsBoundsTransforminterpolate the rectangles between list and detail states with synchronized timing.
A Tinder style card stack. Drag past the threshold and the card flings off, tilted by a rotation factor proportional to the offset.
- Try tweaking:
SWIPE_THRESHOLD_FRACTION,ROTATION_FACTOR,FLING_STIFFNESS,FLING_DURATION_MS. - Source:
AnimationExample13.kt - Article: Swipeable Cards. Combines
Animatable.snapToduring drag for one-to-one pointer tracking withanimateTousing spring or tween on release, coupling rotation as agraphicsLayerfunction of the same offset for visual coherence.
A floating action button that explodes into satellite buttons along an arc. Each satellite has its own Animatable, animated through a spring with a per index stagger delay so the menu unfurls and refolds.
- Try tweaking:
ITEM_COUNT,RADIUS_DP,STAGGER_MS,SPRING_STIFFNESS,SPRING_DAMPING,ARC_DEG. - Source:
AnimationExample14.kt - Article: Radial FAB Menu. Distributes satellites along a polar coordinate arc using
cosandsin, with per-itemAnimatableinstances staggered throughLaunchedEffectdelays so the menu unfurls and refolds symmetrically.
A card that flips in 3D using graphicsLayer.rotationY with a tuned cameraDistance. The front and back swap content at 90 degrees.
- Try tweaking:
FLIP_DURATION_MS,CAMERA_DISTANCE, the front and back colors. - Source:
AnimationExample15.kt - Article: 3D Card Flip. Applies
rotationYongraphicsLayerwithcameraDistancescaled by density to create perspective projection, swapping content at 90 degrees when the layer becomes edge on.
Tap anywhere in the canvas and a one shot burst of rotating paper rectangles erupts from that point. Each piece carries its own velocity, rotation speed, lateral wobble, lifetime, and color. Multiple bursts stack on top of each other.
- Try tweaking:
BURST_COUNT,GRAVITY,SPEED_MIN/MAX,SPREAD_DEG,LAUNCH_ANGLE_DEG,AIR_DRAG,WOBBLE_AMP,ROT_SPEED_MAX,PALETTE. - Source:
AnimationExample16.kt - Article: Confetti Burst. Models particles as mutable class instances updated in a
withFrameNanosloop, integrating gravity and exponential drag frame-rate independently whileCanvasrenders all pieces in a single pass with per-particle alpha fade.
Multiple sine wave layers stacked for parallax, each driven by its own phase, frequency, and amplitude ramps. Looks like a calm sea or a storm depending on the constants.
- Try tweaking:
BASE_AMPLITUDE_DP,BASE_PHASE_SPEED,FREQ_RAMP,AMPL_FALLOFF,LAYER_COUNT. - Source:
AnimationExample17.kt - Article: Wave Field. Stacks multiple sine wave layers with per-layer ramps for frequency, amplitude, and phase speed to create parallax depth, with
withFrameNanosdriving time and awaveYhelper sampling positions into aPath.
Drifting blobs that fuse into a single liquid mass when they overlap. The fusion comes from additive blend on stacked radial gradients.
- Try tweaking:
ballCount,ballRadiusMin/MaxDp,glowRadiusMult,maxSpeedDpPerSec,driftNoise. - Source:
AnimationExample18.kt - Article: Metaball Liquid. Blends drifting balls using
Brush.radialGradientwithBlendMode.Pluson an offscreengraphicsLayer, so overlapping alpha values create the illusion of a fused liquid mass.
Color orbs orbit on elliptical paths, additive blended into a living mesh gradient. Hue rotation cycles the entire palette over time.
- Try tweaking:
ORB_COUNT,ORB_GLOW_RADIUS_DP,ORBIT_RADIUS_MIN/MAX_DP,HUE_ROTATION_SPEED,PALETTE. - Source:
AnimationExample19.kt - Article: Mesh Aurora. Composes orbiting color orbs along elliptical parametric paths while HSV hue rotation cycles each palette entry independently, with additive blending on an offscreen layer producing a living gradient mesh.
N pendulums with progressively shorter periods. They start in phase, drift apart into apparent chaos, and resync at the period boundary.
- Try tweaking:
PENDULUM_COUNT,BASE_PERIOD_SEC,SYNC_PERIOD_SEC, the bob colors. - Source:
AnimationExample20.kt - Article: Pendulum Wave. Computes each pendulum's angle as
cos(omega * time)with periods chosen so all pendulums resync at a fixedSYNC_PERIOD_SECboundary, creating traveling waves and apparent chaos that cycle predictably.
Continuous rain streaks falling at an angle, with depth based parallax and optional ground splash marks.
- Try tweaking:
DROP_COUNT,ANGLE_DEG,SPEED_MIN/MAX_DP_PER_SEC,STREAK_LENGTH,SPLASH_ENABLED. - Source:
AnimationExample21.kt - Article: Rainy. Recycles a fixed pool of
Dropobjects advanced byvelocity * dt, with per-drop speed encoding depth parallax, direction taken fromcos/sinof a singleANGLE_DEG, and optional splash circles marking ground contact.
With Compose hot reload, you change the value, save, and the animation plays with the new value on your running device in under a second. No rebuild. No restart. No navigating back. You stay on the exact screen, the exact state, and see the exact difference between the old value and the new one. This turns animation tuning from a guessing game into a visual, iterative process.
In this article, you will explore four real world examples of animation development with hot reload: content size transitions, grid item animations, custom wave motion, and animation spec tuning.
Each entry in the gallery above has a focused walkthrough on the Compose Animations hub. The page collects every animation as a self contained card with the title, a one line description, and a preview of the source, so you can scan the catalog and jump straight into whichever motion you want to read about.
Inside each article the full composable file is annotated section by section: which constants drive the timing, why a given spring or tween was chosen, what the geometry is doing on the Canvas, and how to twist the same code into a different shape. Use the gallery here to browse, and the hub to read end to end.
Support it by joining stargazers for this repository. ⭐
Also, follow me on GitHub for my next creations.
Designed and developed by 2026 skydoves (Jaewoong Eum)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
























