Skip to content

meetOzan/Springy

Repository files navigation

Sqringy - Quick Animation Extensions

Beautiful, reusable micro-animation extensions for Jetpack Compose.

This repository contains:

  • quick-animation-ext — main animation library (Modifier extensions + composables)
  • app — sample app demonstrating all effects

License


1. Installation

1.1 Repository

Add JitPack (e.g. in settings.gradle.kts):

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven(url = "https://jitpack.io")
    }
}

1.2 Dependency

Kotlin DSL:

dependencies {
    implementation(platform("androidx.compose:compose-bom:<version>"))
    implementation("com.github.meetOzan:Springy:<release-version>")
}

Groovy:

implementation platform("androidx.compose:compose-bom:<version>")
implementation "com.github.meetOzan:Springy:<release-version>"

Replace <version> with your Compose BOM version and <release-version> with the library version (e.g. 0.1.1).


2. API overview

All APIs live in package com.meetozan.quick_animation_ext.

Category API Description
Press feedback Modifier.clickBounceEffect Scale bounce on press (for buttons / clickable)
Shake Modifier.shakeHorizontal Horizontal shake (e.g. form error)
Shake Modifier.shakeVertical Vertical shake
Scale Modifier.scaleUpDown One-off scale up/down (e.g. star, badge)
Scale Modifier.heartBeatEffect Heartbeat-style scale (e.g. like button)
Rotation Modifier.wiggle Small rotation wiggle (CTA attention)
Rotation Modifier.spin Full rotation (refresh, loading)
Enter/exit SlideInRightFadeIn Content slides in from right + fade
Enter/exit SlideInLeftFadeIn Content slides in from left + fade
Loading Modifier.shimmerEffect Skeleton shimmer (fade out with endTrigger)
Scroll Modifier.elasticOverscroll Rubber-band overscroll (e.g. pull-to-refresh)
Scroll Modifier.parallax Parallax offset from scroll position
Reveal Modifier.circularReveal Circular clip expand/collapse
Touch Modifier.touchWaveEffect Expanding circle from touch point
Flip FlipSide 3D flip composable (front/back)
Layout Modifier.expandCollapse Animated height/width expand/collapse
Ambient Modifier.floatingEffect Gentle back-and-forth float

3. Demo GIFs


clickBounceEffect

clickBounceVideo (1)


shakeHorizontal

Shake Horizontal Video


shakeVertical

shakeVertical


scaleUpDown

scaleUpDown


heartBeatEffect

heartBeatEffect


wiggle

wiggle


spin

spin


SlideInLeftFadeIn & SlideInRightFadeIn

SlideInFadeIn


shimmerEffect

shimmerEffect


elasticOverscroll

elasticOverscroll


parallax

parallax


circularReveal

circularReveal


touchWaveEffect

touchWaveEffect


FlipSide

FlipSide


expandCollapse

expandCollapse


floatingEffect

floatingEffect


4. Quick usage examples

clickBounceEffect (recommended on clickable components)

Button(modifier = Modifier.clickBounceEffect(), onClick = { ... }) { Text("Submit") }
IconButton(modifier = Modifier.clickBounceEffect(scaleDown = 0.92f), onClick = { ... }) { ... }

shakeHorizontal / shakeVertical (error feedback)

OutlinedTextField(
    modifier = Modifier.shakeHorizontal(trigger = showError, onAnimationEnd = { showError = false }),
    ...
)
Card(modifier = Modifier.shakeVertical(trigger = denyKey)) { ... }

scaleUpDown / heartBeatEffect (pulse, like)

Icon(..., modifier = Modifier.scaleUpDown(trigger = liked, scaleUp = 1.3f))
Icon(..., modifier = Modifier.heartBeatEffect(trigger = loved))

wiggle / spin

Button(modifier = Modifier.wiggle(enabled = wiggle), ...)
Icon(..., modifier = Modifier.spin(trigger = refreshKey, durationMillis = 500))
Icon(..., modifier = Modifier.spin(trigger = Unit, isInfinite = true))

SlideInRightFadeIn / SlideInLeftFadeIn

SlideInRightFadeIn(durationMillis = 400, delayMillis = 100) { Text("Welcome") }
SlideInLeftFadeIn(trigger = showDrawer, isHaveExitAnimation = true) { DrawerContent() }

shimmerEffect (skeleton)

Box(Modifier.fillMaxWidth().height(120.dp).shimmerEffect(endTrigger = loaded))

elasticOverscroll / parallax

Column(Modifier.verticalScroll(state).elasticOverscroll(overscrollAction = { refresh() })) { ... }
Image(Modifier.parallax(scrollState.value, ratio = 0.4f), ...)

circularReveal / touchWaveEffect

Box(Modifier.circularReveal(trigger = show, isClose = !show)) { FullScreenContent() }
Card(Modifier.clickable { }.touchWaveEffect()) { ... }

FlipSide / expandCollapse / floatingEffect

FlipSide(trigger = flipped, front = { Text("Q") }, back = { Text("A") })
Column(Modifier.expandCollapse(expanded)) { ... }
Icon(Modifier.floatingEffect(offset = 8f), ...)

5. Design goals

  • Composable-first — Modifier extensions and small composables; no heavy wrappers.
  • Sane defaults — Most parameters have defaults; override when needed.
  • Extensible — Shared internals (e.g. baseShake, baseHeartBeat) allow new variants.

6. License

QuickAnimationExt is licensed under the Apache License, Version 2.0.

Copyright 2026 The Android Open Source Project

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.

About

Jetpack Compose Quick Animation Library

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages