├── .nojekyll
├── animate-compose
├── .gitignore
├── consumer-rules.pro
├── src
│ ├── commonMain
│ │ └── kotlin
│ │ │ └── com
│ │ │ └── nomanr
│ │ │ └── animate
│ │ │ └── compose
│ │ │ ├── tokens
│ │ │ └── AnimationTokens.kt
│ │ │ ├── core
│ │ │ ├── ContainerSize.kt
│ │ │ ├── AnimationPreset.kt
│ │ │ ├── KeyframeAnimationUtils.kt
│ │ │ ├── NeedsLayoutInfo.kt
│ │ │ ├── Keyframe.kt
│ │ │ └── Easings.kt
│ │ │ ├── presets
│ │ │ ├── common
│ │ │ │ └── BounceEasing.kt
│ │ │ ├── fadeinentrances
│ │ │ │ ├── FadeIn.kt
│ │ │ │ ├── FadeInUp.kt
│ │ │ │ ├── FadeInLeft.kt
│ │ │ │ ├── FadeInDown.kt
│ │ │ │ ├── FadeInDownBig.kt
│ │ │ │ ├── FadeInLeftBig.kt
│ │ │ │ ├── FadeInRightBig.kt
│ │ │ │ ├── FadeInUpBig.kt
│ │ │ │ ├── FadeInRight.kt
│ │ │ │ ├── FadeInTopLeft.kt
│ │ │ │ ├── FadeInBottomLeft.kt
│ │ │ │ ├── FadeInTopRight.kt
│ │ │ │ └── FadeInBottomRight.kt
│ │ │ ├── fadeoutexits
│ │ │ │ ├── FadeOut.kt
│ │ │ │ ├── FadeOutUp.kt
│ │ │ │ ├── FadeOutDown.kt
│ │ │ │ ├── FadeOutLeft.kt
│ │ │ │ ├── FadeOutRight.kt
│ │ │ │ ├── FadeOutLeftBig.kt
│ │ │ │ ├── FadeOutRightBig.kt
│ │ │ │ ├── FadeOutUpBig.kt
│ │ │ │ ├── FadeOutDownBig.kt
│ │ │ │ ├── FadeOutTopLeft.kt
│ │ │ │ ├── FadeOutTopRight.kt
│ │ │ │ ├── FadeOutBottomLeft.kt
│ │ │ │ └── FadeOutBottomRight.kt
│ │ │ ├── rotatingexits
│ │ │ │ ├── RotateOut.kt
│ │ │ │ ├── RotateOutUpLeft.kt
│ │ │ │ ├── RotateOutDownLeft.kt
│ │ │ │ ├── RotateOutUpRight.kt
│ │ │ │ └── RotateOutDownRight.kt
│ │ │ ├── rotatingentrances
│ │ │ │ ├── RotateIn.kt
│ │ │ │ ├── RotateInDownLeft.kt
│ │ │ │ ├── RotateInUpLeft.kt
│ │ │ │ ├── RotateInUpRight.kt
│ │ │ │ └── RotateInDownRight.kt
│ │ │ ├── specials
│ │ │ │ ├── RollOut.kt
│ │ │ │ ├── RollIn.kt
│ │ │ │ ├── JackInTheBox.kt
│ │ │ │ └── Hinge.kt
│ │ │ ├── slidingexits
│ │ │ │ ├── SlideOutUp.kt
│ │ │ │ ├── SlideOutDown.kt
│ │ │ │ ├── SlideOutLeft.kt
│ │ │ │ └── SlideOutRight.kt
│ │ │ ├── slidingentrances
│ │ │ │ ├── SlideInDown.kt
│ │ │ │ ├── SlideInUp.kt
│ │ │ │ ├── SlideInLeft.kt
│ │ │ │ └── SlideInRight.kt
│ │ │ ├── attentionseekers
│ │ │ │ ├── Pulse.kt
│ │ │ │ ├── Flash.kt
│ │ │ │ ├── HeartBeat.kt
│ │ │ │ ├── Swing.kt
│ │ │ │ └── HeadShake.kt
│ │ │ ├── zoomingextrances
│ │ │ │ └── ZoomIn.kt
│ │ │ ├── bouncingexits
│ │ │ │ ├── BounceOutLeft.kt
│ │ │ │ ├── BounceOutRight.kt
│ │ │ │ ├── defaultEasing.kt
│ │ │ │ ├── BounceOutDown.kt
│ │ │ │ └── BounceOutUp.kt
│ │ │ ├── lightspeed
│ │ │ │ ├── LightSpeedInLeft.kt
│ │ │ │ ├── LightSpeedInRight.kt
│ │ │ │ ├── LightSpeedOutRight.kt
│ │ │ │ └── LightSpeedOutLeft.kt
│ │ │ ├── zooms
│ │ │ │ ├── ZoomOut.kt
│ │ │ │ ├── ZoomOutUp.kt
│ │ │ │ ├── ZoomOutDown.kt
│ │ │ │ ├── ZoomOutLeft.kt
│ │ │ │ └── ZoomOutRight.kt
│ │ │ ├── flippers
│ │ │ │ ├── FlipOutX.kt
│ │ │ │ ├── FlipOutY.kt
│ │ │ │ └── Flip.kt
│ │ │ ├── backentrances
│ │ │ │ └── BackInDown.kt
│ │ │ ├── backexists
│ │ │ │ ├── BackOutDown.kt
│ │ │ │ ├── BackOutUp.kt
│ │ │ │ ├── BackOutLeft.kt
│ │ │ │ └── BackOutRight.kt
│ │ │ └── bouncingentrances
│ │ │ │ ├── BounceInLeft.kt
│ │ │ │ ├── BounceInRight.kt
│ │ │ │ ├── BounceInDown.kt
│ │ │ │ ├── BounceInUp.kt
│ │ │ │ └── BounceIn.kt
│ │ │ └── animated
│ │ │ └── AnimationCallbacks.kt
│ ├── skikoMain
│ │ └── kotlin
│ │ │ └── com
│ │ │ └── nomanr
│ │ │ └── animate
│ │ │ └── compose
│ │ │ └── core
│ │ │ └── ContainerSize.skiko.kt
│ └── androidMain
│ │ └── kotlin
│ │ └── com
│ │ └── nomanr
│ │ └── animate
│ │ └── compose
│ │ └── core
│ │ └── ContainerSize.android.kt
└── proguard-rules.pro
├── images
└── open-graph.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── sample
├── app
│ ├── ios
│ │ ├── iosApp
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── AppIcon.appiconset
│ │ │ │ │ ├── app-icon-1024.png
│ │ │ │ │ └── Contents.json
│ │ │ │ └── AccentColor.colorset
│ │ │ │ │ └── Contents.json
│ │ │ ├── Preview Content
│ │ │ │ └── Preview Assets.xcassets
│ │ │ │ │ └── Contents.json
│ │ │ ├── iOSApp.swift
│ │ │ ├── ContentView.swift
│ │ │ └── Info.plist
│ │ └── .gitignore
│ ├── android
│ │ ├── src
│ │ │ └── main
│ │ │ │ ├── res
│ │ │ │ ├── values
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ ├── themes.xml
│ │ │ │ │ └── colors.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.webp
│ │ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.webp
│ │ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.webp
│ │ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.webp
│ │ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.webp
│ │ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── xml
│ │ │ │ │ ├── backup_rules.xml
│ │ │ │ │ └── data_extraction_rules.xml
│ │ │ │ └── drawable
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── nomanr
│ │ │ │ │ └── animate
│ │ │ │ │ └── compose
│ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── AndroidManifest.xml
│ │ └── build.gradle.kts
│ ├── web
│ │ ├── src
│ │ │ └── jsMain
│ │ │ │ ├── resources
│ │ │ │ ├── styles.css
│ │ │ │ ├── favicon.svg
│ │ │ │ └── index.html
│ │ │ │ └── kotlin
│ │ │ │ └── com
│ │ │ │ └── nomanr
│ │ │ │ └── animate
│ │ │ │ └── compose
│ │ │ │ └── Main.kt
│ │ └── build.gradle.kts
│ ├── common
│ │ └── src
│ │ │ ├── iosMain
│ │ │ └── kotlin
│ │ │ │ └── com
│ │ │ │ └── nomanr
│ │ │ │ └── animate
│ │ │ │ └── compose
│ │ │ │ └── MainViewController.kt
│ │ │ └── commonMain
│ │ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── nomanr
│ │ │ │ └── animate
│ │ │ │ └── compose
│ │ │ │ ├── navigation
│ │ │ │ ├── NavRoute.kt
│ │ │ │ └── SampleAppNavHost.kt
│ │ │ │ ├── SampleAppState.kt
│ │ │ │ ├── playground
│ │ │ │ ├── model
│ │ │ │ │ └── CustomAnimationPreset.kt
│ │ │ │ └── components
│ │ │ │ │ └── configs
│ │ │ │ │ ├── ConfigurationSection.kt
│ │ │ │ │ └── AnimationDuration.kt
│ │ │ │ ├── SampleApp.kt
│ │ │ │ └── sample
│ │ │ │ ├── components
│ │ │ │ ├── AnimationDemoContainer.kt
│ │ │ │ └── AnimatedDemo.kt
│ │ │ │ └── SampleScreen.kt
│ │ │ └── composeResources
│ │ │ └── drawable
│ │ │ ├── x.xml
│ │ │ └── github.xml
│ └── desktop
│ │ ├── src
│ │ └── desktopMain
│ │ │ └── kotlin
│ │ │ └── com
│ │ │ └── nomanr
│ │ │ └── animate
│ │ │ └── compose
│ │ │ └── Main.kt
│ │ └── build.gradle.kts
└── ui-components
│ ├── src
│ └── commonMain
│ │ ├── composeResources
│ │ └── font
│ │ │ ├── poppins_black.ttf
│ │ │ ├── poppins_bold.ttf
│ │ │ ├── poppins_light.ttf
│ │ │ ├── poppins_thin.ttf
│ │ │ ├── poppins_italic.ttf
│ │ │ ├── poppins_medium.ttf
│ │ │ ├── poppins_regular.ttf
│ │ │ ├── poppins_bolditalic.ttf
│ │ │ ├── poppins_extrabold.ttf
│ │ │ ├── poppins_extralight.ttf
│ │ │ ├── poppins_semibold.ttf
│ │ │ ├── poppins_thinitalic.ttf
│ │ │ ├── poppins_blackitalic.ttf
│ │ │ ├── poppins_lightitalic.ttf
│ │ │ ├── poppins_mediumitalic.ttf
│ │ │ ├── poppins_extrabolditalic.ttf
│ │ │ ├── poppins_semibolditalic.ttf
│ │ │ └── poppins_extralightitalic.ttf
│ │ └── kotlin
│ │ └── com
│ │ └── nomanr
│ │ └── animate
│ │ └── compose
│ │ └── ui
│ │ ├── foundation
│ │ ├── SystemBarsDefaultInsets.kt
│ │ └── Providers.kt
│ │ ├── components
│ │ └── Divider.kt
│ │ ├── AdaptiveProvider.kt
│ │ └── Theme.kt
│ └── build.gradle.kts
├── lumo.properties
├── .gitignore
├── .run
├── sample.ios.run.xml
├── sample.web.run.xml
└── sample_web.run.xml
├── settings.gradle.kts
├── gradle.properties
└── .github
└── workflows
└── deploy-to-pages.yml
/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/animate-compose/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/animate-compose/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/open-graph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/images/open-graph.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/sample/app/ios/iosApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "author": "xcode",
4 | "version": 1
5 | }
6 | }
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | animate-compose
3 |
--------------------------------------------------------------------------------
/sample/app/ios/iosApp/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "author": "xcode",
4 | "version": 1
5 | }
6 | }
--------------------------------------------------------------------------------
/sample/app/web/src/jsMain/resources/styles.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | width: 100%;
3 | height: 100%;
4 | margin: 0;
5 | padding: 0;
6 | overflow: hidden;
7 | }
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/sample/app/ios/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/app/ios/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_black.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_bold.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_light.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_thin.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_italic.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_medium.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_regular.ttf
--------------------------------------------------------------------------------
/sample/app/ios/iosApp/iOSApp.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | @main
4 | struct iOSApp: App {
5 | var body: some Scene {
6 | WindowGroup {
7 | ContentView()
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_bolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_bolditalic.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_extrabold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_extrabold.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_extralight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_extralight.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_semibold.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_thinitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_thinitalic.ttf
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/tokens/AnimationTokens.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.tokens
2 |
3 | object AnimationTokens {
4 | const val SlideAnimationDelayOffset = 100
5 | }
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_blackitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_blackitalic.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_lightitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_lightitalic.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_mediumitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_mediumitalic.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_extrabolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_extrabolditalic.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_semibolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_semibolditalic.ttf
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/composeResources/font/poppins_extralightitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomanr/animate-compose/HEAD/sample/ui-components/src/commonMain/composeResources/font/poppins_extralightitalic.ttf
--------------------------------------------------------------------------------
/sample/app/ios/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors": [
3 | {
4 | "idiom": "universal"
5 | }
6 | ],
7 | "info": {
8 | "author": "xcode",
9 | "version": 1
10 | }
11 | }
--------------------------------------------------------------------------------
/sample/app/common/src/iosMain/kotlin/com/nomanr/animate/compose/MainViewController.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose
2 |
3 | import androidx.compose.ui.window.ComposeUIViewController
4 |
5 | fun MainViewController() = ComposeUIViewController { SampleApp() }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/core/ContainerSize.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.core
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.ui.unit.IntSize
5 |
6 | @Composable
7 | expect fun getContainerSize(): IntSize
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Apr 03 21:16:10 BST 2025
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/sample/app/ios/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "filename": "app-icon-1024.png",
5 | "idiom": "universal",
6 | "platform": "ios",
7 | "size": "1024x1024"
8 | }
9 | ],
10 | "info": {
11 | "author": "xcode",
12 | "version": 1
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/common/BounceEasing.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.common
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 |
5 | internal val bounceInEasing = CubicBezierEasing(0.215f, 0.61f, 0.355f, 1f)
6 |
7 | internal val bounceOutEasing = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/navigation/NavRoute.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.navigation
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | sealed class NavRoute {
6 | @Serializable
7 | data object Sample : NavRoute()
8 |
9 | @Serializable
10 | data object Playground : NavRoute()
11 | }
12 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/core/AnimationPreset.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.core
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 |
7 | interface AnimationPreset {
8 | @Composable
9 | fun animate(progress: State): Modifier
10 | }
--------------------------------------------------------------------------------
/lumo.properties:
--------------------------------------------------------------------------------
1 | # Lumo UI Plugin
2 | # This file is used to store configurations for the Lumo UI Plugin
3 | # Do not delete this file
4 | ThemeName=AppTheme
5 | ComponentsDir=sample/ui-components/src/commonMain/kotlin/com/nomanr/animate/compose/ui
6 | PackageName=com.nomanr.animate.compose.ui
7 | # Uncomment this line if you are using Kotlin Multiplatform
8 | KotlinMultiplatform=true
--------------------------------------------------------------------------------
/sample/app/web/src/jsMain/resources/favicon.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/kotlin/com/nomanr/animate/compose/ui/foundation/SystemBarsDefaultInsets.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.ui.foundation
2 |
3 | import androidx.compose.foundation.layout.WindowInsets
4 | import androidx.compose.foundation.layout.systemBars
5 | import androidx.compose.runtime.Composable
6 |
7 | val WindowInsets.Companion.systemBarsForVisualComponents: WindowInsets
8 | @Composable
9 | get() = systemBars
10 |
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | */build/*
12 | **/build/
13 | /captures
14 | .externalNativeBuild
15 | .cxx
16 | local.properties
17 | .kotlin/errors
18 | build/tmp
19 | .idea/
20 | .kotlin/
21 | **/release/
22 | **/bin/
23 |
24 |
25 | !.idea/codeStyles/
26 | !.idea/inspectionProfiles/
27 | !.idea/runConfigurations/
--------------------------------------------------------------------------------
/animate-compose/src/skikoMain/kotlin/com/nomanr/animate/compose/core/ContainerSize.skiko.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.core
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.ui.ExperimentalComposeUiApi
5 | import androidx.compose.ui.platform.LocalWindowInfo
6 | import androidx.compose.ui.unit.IntSize
7 |
8 | @OptIn(ExperimentalComposeUiApi::class)
9 | @Composable
10 | actual fun getContainerSize(): IntSize {
11 | val windowInfo = LocalWindowInfo.current
12 | return windowInfo.containerSize
13 | }
--------------------------------------------------------------------------------
/sample/app/desktop/src/desktopMain/kotlin/com/nomanr/animate/compose/Main.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose
2 |
3 | import androidx.compose.ui.unit.DpSize
4 | import androidx.compose.ui.unit.dp
5 | import androidx.compose.ui.window.WindowState
6 | import androidx.compose.ui.window.singleWindowApplication
7 |
8 | fun main() {
9 | val windowState =
10 | WindowState(
11 | size = DpSize(1000.dp, 974.dp),
12 | )
13 |
14 | singleWindowApplication(windowState) {
15 | SampleApp()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/sample/app/ios/iosApp/ContentView.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import SwiftUI
3 | import ComposeApp
4 |
5 | struct ComposeView: UIViewControllerRepresentable {
6 | func makeUIViewController(context: Context) -> UIViewController {
7 | MainViewControllerKt.MainViewController()
8 | }
9 |
10 | func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
11 | }
12 |
13 | struct ContentView: View {
14 | var body: some View {
15 | ComposeView()
16 | .ignoresSafeArea(.keyboard)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/sample/app/android/src/main/java/com/nomanr/animate/compose/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.activity.enableEdgeToEdge
7 |
8 | class MainActivity : ComponentActivity() {
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | enableEdgeToEdge()
12 | setContent {
13 | SampleApp()
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/.run/sample.ios.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/sample/app/web/src/jsMain/kotlin/com/nomanr/animate/compose/Main.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose
2 |
3 | import androidx.compose.runtime.SideEffect
4 | import androidx.compose.ui.ExperimentalComposeUiApi
5 | import androidx.compose.ui.window.CanvasBasedWindow
6 | import kotlinx.browser.document
7 | import org.jetbrains.skiko.wasm.onWasmReady
8 |
9 | @OptIn(ExperimentalComposeUiApi::class)
10 | fun main() {
11 | onWasmReady {
12 | CanvasBasedWindow("ComposeTarget") {
13 | SideEffect { document.title = "Animated.compose" }
14 | SampleApp()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/core/KeyframeAnimationUtils.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.core
2 |
3 |
4 | /**
5 | * Find a matching keyframe for a given animation progress.
6 | * - Returns a Segment if progress is between start and end
7 | * - Returns a Static if progress is less than or equal to its percent
8 | */
9 | fun List.atProgress(progress: Float): Keyframe? {
10 | return this.findLast {
11 | when (it) {
12 | is Keyframe.Segment -> progress in it.start..it.end
13 | is Keyframe.Static -> progress >= it.percent
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/composeResources/drawable/x.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/animate-compose/src/androidMain/kotlin/com/nomanr/animate/compose/core/ContainerSize.android.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.core
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.ui.platform.LocalConfiguration
5 | import androidx.compose.ui.platform.LocalDensity
6 | import androidx.compose.ui.unit.IntSize
7 | import androidx.compose.ui.unit.dp
8 |
9 | @Composable
10 | actual fun getContainerSize(): IntSize {
11 | val configuration = LocalConfiguration.current
12 | val density = LocalDensity.current
13 | return with(density) {
14 | IntSize(
15 | configuration.screenWidthDp.dp.roundToPx(), configuration.screenHeightDp.dp.roundToPx()
16 | )
17 | }
18 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/animated/AnimationCallbacks.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.animated
2 |
3 | /**
4 | * Callback interface for your composable animation lifecycle.
5 | * Override any combination of these methods
6 | * to get notified when an animation starts
7 | * when it is running
8 | * and when it finishes
9 | */
10 | interface AnimationCallbacks {
11 | /** called once, immediately before the animation to 1f begins */
12 | fun onStart() = Unit
13 |
14 | /** called each time the animated progress value updates */
15 | fun onAnimating(progress: Float) = Unit
16 |
17 | /** called once, as soon as the animation reaches its end */
18 | fun onFinish() = Unit
19 | }
--------------------------------------------------------------------------------
/animate-compose/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/sample/app/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/sample/app/desktop/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.compose.desktop.application.dsl.TargetFormat
2 |
3 | plugins {
4 | alias(libs.plugins.kotlin.multiplatform)
5 | alias(libs.plugins.compose.compiler)
6 | alias(libs.plugins.compose.multiplatform)
7 | }
8 |
9 | kotlin {
10 | jvm("desktop")
11 |
12 | sourceSets {
13 | val desktopMain by getting {
14 | dependencies {
15 | implementation(project(":sample:app:common"))
16 | implementation(compose.desktop.currentOs)
17 | }
18 | }
19 | }
20 | }
21 |
22 | compose.desktop {
23 | application {
24 | mainClass = "com.nomanr.animate.compose.MainKt"
25 |
26 | nativeDistributions {
27 | targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
28 | packageName = "com.nomanr.animate.compose"
29 | packageVersion = "1.0.0"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/SampleAppState.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.Stable
5 | import androidx.navigation.NavHostController
6 | import androidx.navigation.compose.rememberNavController
7 | import com.nomanr.animate.compose.ui.components.snackbar.SnackbarHostState
8 | import com.nomanr.animate.compose.ui.components.snackbar.rememberSnackbarHost
9 |
10 | @Composable
11 | fun rememberSampleAppState(
12 | navController: NavHostController = rememberNavController(),
13 | snackbarHostState: SnackbarHostState = rememberSnackbarHost(),
14 | ): SampleAppState {
15 | return SampleAppState(
16 | navController = navController,
17 | snackbarHostState = snackbarHostState,
18 | )
19 | }
20 |
21 | @Stable
22 | class SampleAppState(
23 | val navController: NavHostController,
24 | val snackbarHostState: SnackbarHostState,
25 | )
26 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/playground/model/CustomAnimationPreset.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.playground.model
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.animateKeyframe
10 |
11 | class CustomAnimationPreset(
12 | private val keyframes: List,
13 | private val transformOrigin: TransformOrigin = TransformOrigin.Center,
14 | ) : AnimationPreset {
15 |
16 |
17 |
18 | @Composable
19 | override fun animate(progress: State): Modifier {
20 | return Modifier.animateKeyframe(
21 | progress = progress,
22 | keyframes = keyframes,
23 | transformOrigin = transformOrigin,
24 | )
25 | }
26 | }
--------------------------------------------------------------------------------
/sample/app/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .AppleDouble
3 | .LSOverride
4 | Icon?
5 | ._*
6 |
7 | ._.Spotlight-V100
8 | .Trashes
9 |
10 | DerivedData/
11 | .idea/
12 | *.xcworkspace
13 | *.xccheckout
14 | *.xcodeproj/project.xcworkspace/
15 | *.xcodeproj/xcuserdata/
16 | *.xcodeproj/xcuserdata/*
17 | xcuserdata/
18 | *.xcodeproj/project.xcworkspace/xcshareddata/
19 | *.xcodeproj/project.xcworkspace/xcuserdata/
20 | *.xcodeproj/*.xcuserdatad/
21 | *.xcodeproj/xcuserdata/
22 | *.xcodeproj/xcuserdatad/
23 | *.xcscmblueprint
24 |
25 | .build/
26 | .swiftpm/
27 | Package.resolved
28 |
29 | Pods/
30 | *.lock
31 | *.xcconfig
32 | *.xcworkspace
33 |
34 | Carthage/Build/
35 | Carthage/Checkouts/
36 | Carthage/Configurations/
37 |
38 | fastlane/report.xml
39 | fastlane/Preview.html
40 | fastlane/screenshots
41 | fastlane/test_output
42 |
43 | *.ipa
44 | *.app
45 | *.dSYM.zip
46 | *.dSYM
47 | *.bcsymbolmap
48 | *.xcarchive
49 |
50 | *.swp
51 | *.swo
52 | *.mode1v3
53 | *.mode2v3
54 | *.perspectivev3
55 | *.xcuserstate
56 | *.xcuserdatad
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/core/NeedsLayoutInfo.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.core
2 |
3 | import androidx.compose.ui.geometry.Offset
4 | import androidx.compose.ui.unit.IntSize
5 |
6 | interface NeedsLayoutInfo {
7 | fun setLayoutInfo(layoutInfo: LayoutInfo)
8 | }
9 |
10 | data class LayoutInfo(
11 | val x: Float,
12 | val y: Float,
13 | val width: Float,
14 | val height: Float,
15 | val containerWidth: Int,
16 | val containerHeight: Int,
17 |
18 | ) {
19 | companion object {
20 | fun create(size: IntSize, position: Offset, containerSize: IntSize): LayoutInfo {
21 | return LayoutInfo(
22 | x = position.x,
23 | y = position.y,
24 | width = size.width.toFloat(),
25 | height = size.height.toFloat(),
26 | containerWidth = containerSize.width,
27 | containerHeight = containerSize.height
28 | )
29 | }
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/SampleApp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose
2 |
3 | import androidx.compose.foundation.layout.fillMaxSize
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.ui.Modifier
6 | import com.nomanr.animate.compose.navigation.SampleAppNavHost
7 | import com.nomanr.animate.compose.ui.AdaptiveProvider
8 | import com.nomanr.animate.compose.ui.AppTheme
9 | import com.nomanr.animate.compose.ui.components.Scaffold
10 | import com.nomanr.animate.compose.ui.components.snackbar.SnackbarHost
11 |
12 |
13 | @Composable
14 | fun SampleApp() {
15 | val appState = rememberSampleAppState()
16 | AppTheme {
17 | AdaptiveProvider(modifier = Modifier.fillMaxSize()) {
18 | Scaffold(
19 | snackbarHost = { SnackbarHost(appState.snackbarHostState) }
20 | ) {
21 | SampleAppNavHost(
22 | appState = appState,
23 | )
24 | }
25 | }
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/sample/components/AnimationDemoContainer.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.sample.components
2 |
3 | import androidx.compose.foundation.layout.BoxWithConstraints
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.LaunchedEffect
6 | import androidx.compose.ui.Alignment
7 | import androidx.compose.ui.Modifier
8 | import androidx.compose.ui.unit.DpSize
9 | import com.nomanr.animate.compose.data.Animation
10 |
11 | @Composable
12 | fun AnimationDemoContainer(
13 | animation: Animation,
14 | onSizeChanged: (DpSize) -> Unit,
15 | modifier: Modifier = Modifier,
16 | contentAlignment: Alignment = Alignment.Center
17 | ) {
18 | BoxWithConstraints(
19 | modifier = modifier,
20 | contentAlignment = contentAlignment
21 | ) {
22 | LaunchedEffect(maxWidth, maxHeight) {
23 | onSizeChanged(DpSize(maxWidth, maxHeight))
24 | }
25 |
26 | AnimatedDemo(animation = animation)
27 | }
28 | }
--------------------------------------------------------------------------------
/sample/app/android/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.application)
3 | alias(libs.plugins.kotlin.android)
4 | alias(libs.plugins.compose.compiler)
5 | }
6 |
7 | android {
8 | namespace = "com.nomanr.animate.compose"
9 | compileSdk = libs.versions.compileSdk.get().toInt()
10 |
11 | defaultConfig {
12 | applicationId = "com.nomanr.animate.compose.sample"
13 | minSdk = libs.versions.minSdk.get().toInt()
14 | targetSdk = libs.versions.targetSdk.get().toInt()
15 | versionCode = 1
16 | versionName = "1.0"
17 | }
18 |
19 | compileOptions {
20 | sourceCompatibility = JavaVersion.VERSION_17
21 | targetCompatibility = JavaVersion.VERSION_17
22 | }
23 | kotlin {
24 | jvmToolchain(17)
25 | }
26 | buildTypes {
27 | getByName("release") {
28 | isMinifyEnabled = false
29 | }
30 | }
31 | }
32 |
33 | dependencies {
34 | implementation(project(":sample:app:common"))
35 | implementation(libs.androidx.activity.compose)
36 | }
37 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/playground/components/configs/ConfigurationSection.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.playground.components.configs
2 |
3 | import androidx.compose.foundation.layout.Column
4 | import androidx.compose.foundation.layout.ColumnScope
5 | import androidx.compose.foundation.layout.Spacer
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.unit.dp
11 | import com.nomanr.animate.compose.ui.AppTheme
12 | import com.nomanr.animate.compose.ui.components.Text
13 | import com.nomanr.animate.compose.ui.components.card.Card
14 |
15 |
16 | @Composable
17 | fun ConfigurationSection(title: String, content: @Composable ColumnScope.() -> Unit) {
18 | Column{
19 | Text(title, style = AppTheme.typography.h4)
20 |
21 | Spacer(modifier = Modifier.height(12.dp))
22 |
23 | Card {
24 | Column(modifier = Modifier.padding(16.dp), content = content)
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | includeBuild("build-logic")
3 |
4 | repositories {
5 | google {
6 | mavenContent {
7 | includeGroupAndSubgroups("androidx")
8 | includeGroupAndSubgroups("com.android")
9 | includeGroupAndSubgroups("com.google")
10 | }
11 | }
12 | mavenCentral()
13 | mavenLocal()
14 | gradlePluginPortal()
15 | }
16 | }
17 | dependencyResolutionManagement {
18 | repositories {
19 | google {
20 | mavenContent {
21 | includeGroupAndSubgroups("androidx")
22 | includeGroupAndSubgroups("com.android")
23 | includeGroupAndSubgroups("com.google")
24 | }
25 | }
26 | mavenCentral()
27 | mavenLocal()
28 | gradlePluginPortal()
29 | }
30 | }
31 |
32 | rootProject.name = "animate-compose"
33 | include(":animate-compose")
34 | include(":sample:app:common")
35 | include(":sample:app:android")
36 | include(":sample:app:desktop")
37 | include(":sample:app:web")
38 | include(":sample:ui-components")
39 |
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/kotlin/com/nomanr/animate/compose/ui/foundation/Providers.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.ui.foundation
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.CompositionLocalProvider
5 | import androidx.compose.ui.graphics.Color
6 | import androidx.compose.ui.text.TextStyle
7 | import com.nomanr.animate.compose.ui.LocalContentColor
8 | import com.nomanr.animate.compose.ui.LocalTextStyle
9 |
10 | @Composable
11 | fun ProvideTextStyle(value: TextStyle, content: @Composable () -> Unit) {
12 | val mergedStyle = LocalTextStyle.current.merge(value)
13 | CompositionLocalProvider(LocalTextStyle provides mergedStyle, content = content)
14 | }
15 |
16 | @Composable
17 | internal fun ProvideContentColorTextStyle(
18 | contentColor: Color,
19 | textStyle: TextStyle,
20 | content: @Composable () -> Unit,
21 | ) {
22 | val mergedStyle = LocalTextStyle.current.merge(textStyle)
23 | CompositionLocalProvider(
24 | LocalContentColor provides contentColor,
25 | LocalTextStyle provides mergedStyle,
26 | content = content,
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/core/Keyframe.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.core
2 |
3 | import androidx.compose.animation.core.Easing
4 |
5 | data class TransformProperties(
6 | val translationX: Float? = null,
7 | val translationY: Float? = null,
8 | val scaleX: Float? = null,
9 | val scaleY: Float? = null,
10 | val rotationX: Float? = null,
11 | val rotationZ: Float? = null,
12 | val rotationY: Float? = null,
13 | val skewX: Float? = null,
14 | val skewY: Float? = null,
15 | val alpha: Float? = null,
16 | val cameraDistance: Float? = null,
17 | )
18 |
19 | sealed class Keyframe {
20 | abstract val easing: Easing?
21 |
22 | data class Static(
23 | val percent: Float,
24 | val transform: TransformProperties,
25 | override val easing: Easing? = null
26 | ) : Keyframe()
27 |
28 | data class Segment(
29 | val start: Float,
30 | val end: Float,
31 | val from: TransformProperties,
32 | val to: TransformProperties,
33 | override val easing: Easing? = null
34 | ) : Keyframe()
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeIn.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import com.nomanr.animate.compose.core.AnimationPreset
7 | import com.nomanr.animate.compose.core.Easings
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeIn : AnimationPreset {
13 |
14 | private val ease = Easings.SoftLanding
15 |
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(alpha = 0f),
20 | to = TransformProperties(alpha = 1f),
21 | easing = ease
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes
30 | )
31 | }
--------------------------------------------------------------------------------
/.run/sample.web.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
17 |
18 |
19 | true
20 | true
21 | false
22 | false
23 |
24 |
25 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOut.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOut : AnimationPreset {
13 |
14 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
15 |
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f,
19 | end = 1f,
20 | from = TransformProperties(alpha = 1f),
21 | to = TransformProperties(alpha = 0f),
22 | easing = ease
23 | )
24 | )
25 |
26 | @Composable
27 | override fun animate(progress: State): Modifier =
28 | Modifier.animateKeyframe(
29 | progress = progress,
30 | keyframes = keyframes
31 | )
32 | }
--------------------------------------------------------------------------------
/.run/sample_web.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | true
20 | true
21 | true
22 | false
23 |
24 |
25 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/composeResources/drawable/github.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInUp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInUp(
13 | private val offsetY: Float = 100f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f, end = 1f,
21 | from = TransformProperties(alpha = 0f, translationY = offsetY),
22 | to = TransformProperties(alpha = 1f, translationY = 0f),
23 | easing = ease
24 | )
25 | )
26 |
27 | @Composable
28 | override fun animate(progress: State): Modifier =
29 | Modifier.animateKeyframe(
30 | progress = progress,
31 | keyframes = keyframes
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInLeft(
13 | private val offsetX: Float = -100f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f, end = 1f,
21 | from = TransformProperties(alpha = 0f, translationX = offsetX),
22 | to = TransformProperties(alpha = 1f, translationX = 0f),
23 | easing = ease
24 | )
25 | )
26 |
27 | @Composable
28 | override fun animate(progress: State): Modifier =
29 | Modifier.animateKeyframe(
30 | progress = progress,
31 | keyframes = keyframes
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInDown(
13 | private val offsetY: Float = -100f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f, end = 1f,
21 | from = TransformProperties(alpha = 0f, translationY = offsetY),
22 | to = TransformProperties(alpha = 1f, translationY = 0f),
23 | easing = ease
24 | )
25 | )
26 |
27 | @Composable
28 | override fun animate(progress: State): Modifier =
29 | Modifier.animateKeyframe(
30 | progress = progress,
31 | keyframes = keyframes
32 | )
33 | }
34 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInDownBig.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInDownBig(
13 | private val offsetY: Float = -1200f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f, end = 1f,
21 | from = TransformProperties(alpha = 0f, translationY = offsetY),
22 | to = TransformProperties(alpha = 1f, translationY = 0f),
23 | easing = ease
24 | )
25 | )
26 |
27 | @Composable
28 | override fun animate(progress: State): Modifier =
29 | Modifier.animateKeyframe(
30 | progress = progress,
31 | keyframes = keyframes
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInLeftBig.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInLeftBig(
13 | private val offsetX: Float = -2000f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f, end = 1f,
21 | from = TransformProperties(alpha = 0f, translationX = offsetX),
22 | to = TransformProperties(alpha = 1f, translationX = 0f),
23 | easing = ease
24 | )
25 | )
26 |
27 | @Composable
28 | override fun animate(progress: State): Modifier =
29 | Modifier.animateKeyframe(
30 | progress = progress,
31 | keyframes = keyframes
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInRightBig.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInRightBig(
13 | private val offsetX: Float = 2000f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f, end = 1f,
21 | from = TransformProperties(alpha = 0f, translationX = offsetX),
22 | to = TransformProperties(alpha = 1f, translationX = 0f),
23 | easing = ease
24 | )
25 | )
26 |
27 | @Composable
28 | override fun animate(progress: State): Modifier =
29 | Modifier.animateKeyframe(
30 | progress = progress,
31 | keyframes = keyframes
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInUpBig.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInUpBig(
13 | private val offsetY: Float = 2000f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f, end = 1f,
21 | from = TransformProperties(alpha = 0f, translationY = offsetY),
22 | to = TransformProperties(alpha = 1f, translationY = 0f),
23 | easing = ease
24 | )
25 | )
26 |
27 | @Composable
28 | override fun animate(progress: State): Modifier =
29 | Modifier.animateKeyframe(
30 | progress = progress,
31 | keyframes = keyframes
32 | )
33 | }
34 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutUp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutUp(
13 | private val offsetY: Float = -100f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 1f, translationY = 0f),
23 | to = TransformProperties(alpha = 0f, translationY = offsetY),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/core/Easings.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.core
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.animation.core.Easing
5 |
6 | object Easings {
7 | /** a smooth ease-in then ease-out for natural motion */
8 | val SmoothComfort: Easing = CubicBezierEasing(0.30f, 0.05f, 0.70f, 0.90f)
9 |
10 | /** a snappy entrance with gentle deceleration */
11 | val QuickRise: Easing = CubicBezierEasing(0.60f, 0.05f, 0.90f, 0.60f)
12 |
13 | /** the classic ease-in-out “standard” (same as EaseInOut) */
14 | val BalancedEase: Easing = CubicBezierEasing(0.42f, 0.00f, 0.58f, 1.00f)
15 |
16 | /** a soft in-and-out for subtle transitions */
17 | val SoftLanding: Easing = CubicBezierEasing(0.25f, 0.10f, 0.25f, 1.00f)
18 |
19 | /** a fast ease-in then slow ease-out for quick motion */
20 | val EaseOut: Easing = CubicBezierEasing(0f, 0f, 0.58f, 1f)
21 |
22 | /** easing Curve that starts slowly, speeds up and then ends slowly.*/
23 | val EaseInOut: Easing = CubicBezierEasing(0.42f, 0.0f, 0.58f, 1.0f)
24 |
25 | /** a fast ease-in then slow ease-out for quick motion */
26 | val FastOutSlowInEasing: Easing = CubicBezierEasing(0.4f, 0.0f, 0.2f, 1.0f)
27 |
28 |
29 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutDown(
13 | private val offsetY: Float = 100f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 1f, translationY = 0f),
23 | to = TransformProperties(alpha = 0f, translationY = offsetY),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutLeft(
13 | private val offsetX: Float = -100f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 1f, translationX = 0f),
23 | to = TransformProperties(alpha = 0f, translationX = offsetX),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutRight(
13 | private val offsetX: Float = 100f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 1f, translationX = 0f),
23 | to = TransformProperties(alpha = 0f, translationX = offsetX),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInRight(
13 | private val offsetX: Float = 100f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 0f, translationX = offsetX),
23 | to = TransformProperties(alpha = 1f, translationX = 0f),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutLeftBig.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutLeftBig(
13 | private val offsetX: Float = -2000f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 1f, translationX = 0f),
23 | to = TransformProperties(alpha = 0f, translationX = offsetX),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutRightBig.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutRightBig(
13 | private val offsetX: Float = 2000f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 1f, translationX = 0f),
23 | to = TransformProperties(alpha = 0f, translationX = offsetX),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutUpBig.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutUpBig(
13 | private val offsetY: Float = -2000f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 1f, translationY = 0f),
23 | to = TransformProperties(alpha = 0f, translationY = offsetY),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
35 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutDownBig.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutDownBig(
13 | private val offsetY: Float = 2000f
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 1f,
22 | from = TransformProperties(alpha = 1f, translationY = 0f),
23 | to = TransformProperties(alpha = 0f, translationY = offsetY),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
35 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingexits/RotateOut.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingexits
2 |
3 | import androidx.compose.animation.core.EaseIn
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateOut(
14 | private val endRotation: Float = 200f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = 0f, alpha = 1f),
20 | to = TransformProperties(rotationZ = endRotation, alpha = 0f),
21 | easing = EaseIn
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin.Center,
31 | clip = false
32 | )
33 | }
34 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingentrances/RotateIn.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingentrances
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateIn(
14 | private val rotationAngle: Float = 200f,
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = rotationAngle, alpha = 0f),
20 | to = TransformProperties(rotationZ = 0f, alpha = 1f),
21 | easing = EaseOut
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin.Center,
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingexits/RotateOutUpLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingexits
2 |
3 | import androidx.compose.animation.core.EaseIn
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateOutUpLeft(
14 | private val endRotation: Float = -45f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = 0f, alpha = 1f),
20 | to = TransformProperties(rotationZ = endRotation, alpha = 0f),
21 | easing = EaseIn
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin(0f, 1f),
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingexits/RotateOutDownLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingexits
2 |
3 | import androidx.compose.animation.core.EaseIn
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateOutDownLeft(
14 | private val endRotation: Float = 45f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = 0f, alpha = 1f),
20 | to = TransformProperties(rotationZ = endRotation, alpha = 0f),
21 | easing = EaseIn
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin(0f, 1f),
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingexits/RotateOutUpRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingexits
2 |
3 | import androidx.compose.animation.core.EaseIn
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateOutUpRight(
14 | private val endRotation: Float = 45f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = 0f, alpha = 1f),
20 | to = TransformProperties(rotationZ = endRotation, alpha = 0f),
21 | easing = EaseIn
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin(1f, 1f),
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingentrances/RotateInDownLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingentrances
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateInDownLeft(
14 | private val rotationAngle: Float = 45f,
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f,
19 | end = 1f,
20 | from = TransformProperties(rotationZ = -rotationAngle, alpha = 0f),
21 | to = TransformProperties(rotationZ = 0f, alpha = 1f),
22 | easing = EaseOut
23 | )
24 | )
25 |
26 |
27 | @Composable
28 | override fun animate(progress: State): Modifier = Modifier.animateKeyframe(
29 | progress = progress,
30 | keyframes = keyframes,
31 | transformOrigin = TransformOrigin(0f, 1f),
32 | clip = false
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingexits/RotateOutDownRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingexits
2 |
3 | import androidx.compose.animation.core.EaseIn
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateOutDownRight(
14 | private val endRotation: Float = -45f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = 0f, alpha = 1f),
20 | to = TransformProperties(rotationZ = endRotation, alpha = 0f),
21 | easing = EaseIn
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin(1f, 1f),
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingentrances/RotateInUpLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingentrances
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateInUpLeft(
14 | private val rotationAngle: Float = 45f,
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = rotationAngle, alpha = 0f),
20 | to = TransformProperties(rotationZ = 0f, alpha = 1f),
21 | easing = EaseOut
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin(0f, 1f),
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingentrances/RotateInUpRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingentrances
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateInUpRight(
14 | private val rotationAngle: Float = 45f,
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = -rotationAngle, alpha = 0f),
20 | to = TransformProperties(rotationZ = 0f, alpha = 1f),
21 | easing = EaseOut
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin(1f, 1f),
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/specials/RollOut.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.specials
2 |
3 | import androidx.compose.animation.core.EaseIn
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RollOut(
14 | private val exitOffsetX: Float = 1000f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = 0f, alpha = 1f, translationX = 0f),
20 | to = TransformProperties(rotationZ = 120f, alpha = 0f, translationX = exitOffsetX),
21 | easing = EaseIn
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin.Center,
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/rotatingentrances/RotateInDownRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.rotatingentrances
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RotateInDownRight(
14 | private val rotationAngle: Float = 45f,
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(rotationZ = rotationAngle, alpha = 0f),
20 | to = TransformProperties(rotationZ = 0f, alpha = 1f),
21 | easing = EaseOut
22 | )
23 | )
24 |
25 | @Composable
26 | override fun animate(progress: State): Modifier =
27 | Modifier.animateKeyframe(
28 | progress = progress,
29 | keyframes = keyframes,
30 | transformOrigin = TransformOrigin(1f, 1f),
31 | clip = false
32 | )
33 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInTopLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInTopLeft(
13 | private val offsetX: Float = -100f,
14 | private val offsetY: Float = -100f
15 | ) : AnimationPreset {
16 |
17 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f, end = 1f,
22 | from = TransformProperties(alpha = 0f, translationX = offsetX, translationY = offsetY),
23 | to = TransformProperties(alpha = 1f, translationX = 0f, translationY = 0f),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInBottomLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInBottomLeft(
13 | private val offsetX: Float = -100f,
14 | private val offsetY: Float = 100f
15 | ) : AnimationPreset {
16 |
17 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f, end = 1f,
22 | from = TransformProperties(alpha = 0f, translationX = offsetX, translationY = offsetY),
23 | to = TransformProperties(alpha = 1f, translationX = 0f, translationY = 0f),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInTopRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInTopRight(
13 | private val offsetX: Float = 100f,
14 | private val offsetY: Float = -100f
15 | ) : AnimationPreset {
16 |
17 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f, end = 1f,
22 | from = TransformProperties(alpha = 0f, translationX = offsetX, translationY = offsetY),
23 | to = TransformProperties(alpha = 1f, translationX = 0f, translationY = 0f),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeinentrances/FadeInBottomRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeinentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeInBottomRight(
13 | private val offsetX: Float = 100f,
14 | private val offsetY: Float = 100f
15 | ) : AnimationPreset {
16 |
17 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f, end = 1f,
22 | from = TransformProperties(alpha = 0f, translationX = offsetX, translationY = offsetY),
23 | to = TransformProperties(alpha = 1f, translationX = 0f, translationY = 0f),
24 | easing = ease
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes
33 | )
34 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutTopLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutTopLeft(
13 | private val offsetX: Float = -100f,
14 | private val offsetY: Float = -100f
15 | ) : AnimationPreset {
16 |
17 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 1f,
23 | from = TransformProperties(alpha = 1f, translationX = 0f, translationY = 0f),
24 | to = TransformProperties(alpha = 0f, translationX = offsetX, translationY = offsetY),
25 | easing = ease
26 | )
27 | )
28 |
29 | @Composable
30 | override fun animate(progress: State): Modifier =
31 | Modifier.animateKeyframe(
32 | progress = progress,
33 | keyframes = keyframes
34 | )
35 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutTopRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutTopRight(
13 | private val offsetX: Float = 100f,
14 | private val offsetY: Float = -100f
15 | ) : AnimationPreset {
16 |
17 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 1f,
23 | from = TransformProperties(alpha = 1f, translationX = 0f, translationY = 0f),
24 | to = TransformProperties(alpha = 0f, translationX = offsetX, translationY = offsetY),
25 | easing = ease
26 | )
27 | )
28 |
29 | @Composable
30 | override fun animate(progress: State): Modifier =
31 | Modifier.animateKeyframe(
32 | progress = progress,
33 | keyframes = keyframes
34 | )
35 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutBottomLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutBottomLeft(
13 | private val offsetX: Float = -100f,
14 | private val offsetY: Float = 100f
15 | ) : AnimationPreset {
16 |
17 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 1f,
23 | from = TransformProperties(alpha = 1f, translationX = 0f, translationY = 0f),
24 | to = TransformProperties(alpha = 0f, translationX = offsetX, translationY = offsetY),
25 | easing = ease
26 | )
27 | )
28 |
29 | @Composable
30 | override fun animate(progress: State): Modifier =
31 | Modifier.animateKeyframe(
32 | progress = progress,
33 | keyframes = keyframes
34 | )
35 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/fadeoutexits/FadeOutBottomRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.fadeoutexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class FadeOutBottomRight(
13 | private val offsetX: Float = 100f,
14 | private val offsetY: Float = 100f
15 | ) : AnimationPreset {
16 |
17 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 1f,
23 | from = TransformProperties(alpha = 1f, translationX = 0f, translationY = 0f),
24 | to = TransformProperties(alpha = 0f, translationX = offsetX, translationY = offsetY),
25 | easing = ease
26 | )
27 | )
28 |
29 | @Composable
30 | override fun animate(progress: State): Modifier =
31 | Modifier.animateKeyframe(
32 | progress = progress,
33 | keyframes = keyframes
34 | )
35 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/slidingexits/SlideOutUp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.slidingexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class SlideOutUp(
14 | private val endOffsetY: Float = -200f
15 | ) : AnimationPreset {
16 | private val exitEasing = CubicBezierEasing(0.325f, 0.81f, 0.45f, 0.945f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.6f,
22 | from = TransformProperties(translationY = 0f),
23 | to = TransformProperties(translationY = endOffsetY),
24 | easing = exitEasing
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes,
33 | transformOrigin = TransformOrigin.Center,
34 | clip = false
35 | )
36 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/slidingexits/SlideOutDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.slidingexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class SlideOutDown(
14 | private val endOffsetY: Float = 200f
15 | ) : AnimationPreset {
16 | private val exitEasing = CubicBezierEasing(0.325f, 0.81f, 0.45f, 0.945f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.6f,
22 | from = TransformProperties(translationY = 0f),
23 | to = TransformProperties(translationY = endOffsetY),
24 | easing = exitEasing
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes,
33 | transformOrigin = TransformOrigin.Center,
34 | clip = false
35 | )
36 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/slidingexits/SlideOutLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.slidingexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class SlideOutLeft(
14 | private val endOffsetX: Float = -200f
15 | ) : AnimationPreset {
16 | private val exitEasing = CubicBezierEasing(0.325f, 0.81f, 0.45f, 0.945f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.6f,
22 | from = TransformProperties(translationX = 0f),
23 | to = TransformProperties(translationX = endOffsetX),
24 | easing = exitEasing
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes,
33 | transformOrigin = TransformOrigin.Center,
34 | clip = false
35 | )
36 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/slidingexits/SlideOutRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.slidingexits
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class SlideOutRight(
14 | private val endOffsetX: Float = 200f
15 | ) : AnimationPreset {
16 | private val exitEasing = CubicBezierEasing(0.325f, 0.81f, 0.45f, 0.945f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.6f,
22 | from = TransformProperties(translationX = 0f),
23 | to = TransformProperties(translationX = endOffsetX),
24 | easing = exitEasing
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes,
33 | transformOrigin = TransformOrigin.Center,
34 | clip = false
35 | )
36 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/slidingentrances/SlideInDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.slidingentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class SlideInDown(
14 | private val startOffsetY: Float = -200f
15 | ) : AnimationPreset {
16 |
17 | private val exitEasing = CubicBezierEasing(0.325f, 0.81f, 0.45f, 0.945f)
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.6f,
22 | from = TransformProperties(translationY = startOffsetY),
23 | to = TransformProperties(translationY = 0f),
24 | easing = exitEasing
25 | )
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes,
33 | transformOrigin = TransformOrigin.Center,
34 | clip = false
35 | )
36 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/slidingentrances/SlideInUp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.slidingentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class SlideInUp(
14 | private val startOffsetY: Float = 200f,
15 | ) : AnimationPreset {
16 |
17 | private val exitEasing = CubicBezierEasing(0.325f, 0.81f, 0.45f, 0.945f)
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.6f,
22 | from = TransformProperties(translationY = startOffsetY),
23 | to = TransformProperties(translationY = 0f),
24 | easing = exitEasing
25 | ),
26 | )
27 |
28 | @Composable
29 | override fun animate(progress: State): Modifier =
30 | Modifier.animateKeyframe(
31 | progress = progress,
32 | keyframes = keyframes,
33 | transformOrigin = TransformOrigin.Center,
34 | clip = false
35 | )
36 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/specials/RollIn.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.specials
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class RollIn(
14 | private val entranceOffsetX: Float = -700f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 1f,
19 | from = TransformProperties(
20 | translationX = entranceOffsetX,
21 | rotationZ = -120f,
22 | alpha = 0f
23 | ),
24 | to = TransformProperties(translationX = 0f, rotationZ = 0f, alpha = 1f),
25 | easing = EaseOut
26 | )
27 | )
28 |
29 | @Composable
30 | override fun animate(progress: State): Modifier =
31 | Modifier.animateKeyframe(
32 | progress = progress,
33 | keyframes = keyframes,
34 | transformOrigin = TransformOrigin.Center,
35 | clip = false
36 | )
37 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/slidingentrances/SlideInLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.slidingentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class SlideInLeft(
14 | private val startOffsetX: Float = -200f
15 | ) : AnimationPreset {
16 |
17 | private val exitEasing = CubicBezierEasing(0.325f, 0.81f, 0.45f, 0.945f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 0.6f,
23 | from = TransformProperties(translationX = startOffsetX),
24 | to = TransformProperties(translationX = 0f),
25 | easing = exitEasing
26 | )
27 | )
28 |
29 | @Composable
30 | override fun animate(progress: State): Modifier =
31 | Modifier.animateKeyframe(
32 | progress = progress,
33 | keyframes = keyframes,
34 | transformOrigin = TransformOrigin.Center,
35 | clip = false
36 | )
37 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/slidingentrances/SlideInRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.slidingentrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class SlideInRight(
14 | private val startOffsetX: Float = 200f
15 | ) : AnimationPreset {
16 |
17 | private val exitEasing = CubicBezierEasing(0.325f, 0.81f, 0.45f, 0.945f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 0.6f,
23 | from = TransformProperties(translationX = startOffsetX),
24 | to = TransformProperties(translationX = 0f),
25 | easing = exitEasing
26 | )
27 | )
28 |
29 | @Composable
30 | override fun animate(progress: State): Modifier =
31 | Modifier.animateKeyframe(
32 | progress = progress,
33 | keyframes = keyframes,
34 | transformOrigin = TransformOrigin.Center,
35 | clip = false
36 | )
37 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/attentionseekers/Pulse.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.attentionseekers
2 |
3 | import androidx.compose.animation.core.EaseInOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class Pulse(maxPulseScale: Float = 1.06f) : AnimationPreset {
13 | private val keyframes = listOf(
14 | Keyframe.Segment(
15 | start = 0f,
16 | end = 0.5f,
17 | from = TransformProperties(scaleX = 1f, scaleY = 1f),
18 | to = TransformProperties(scaleX = maxPulseScale, scaleY = maxPulseScale),
19 | easing = EaseInOut
20 | ),
21 | Keyframe.Segment(
22 | start = 0.5f,
23 | end = 1f,
24 | from = TransformProperties(scaleX = maxPulseScale, scaleY = maxPulseScale),
25 | to = TransformProperties(scaleX = 1f, scaleY = 1f),
26 | easing = EaseInOut
27 | )
28 | )
29 |
30 | @Composable
31 | override fun animate(progress: State): Modifier {
32 | return Modifier.animateKeyframe(
33 | progress = progress,
34 | keyframes = keyframes
35 | )
36 | }
37 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. For more details, visit
12 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
24 | org.jetbrains.compose.experimental.jscanvas.enabled=true
25 | org.jetbrains.compose.experimental.macos.enabled=true
--------------------------------------------------------------------------------
/sample/app/web/src/jsMain/resources/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Animate.compose
7 |
8 |
9 |
10 |
15 |
16 |
17 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
39 |
40 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/sample/SampleScreen.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.foundation.layout.Column
2 | import androidx.compose.foundation.layout.fillMaxSize
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.getValue
5 | import androidx.compose.runtime.mutableStateOf
6 | import androidx.compose.runtime.remember
7 | import androidx.compose.runtime.setValue
8 | import androidx.compose.ui.Modifier
9 | import androidx.compose.ui.unit.DpSize
10 | import com.nomanr.animate.compose.components.AppTopbar
11 | import com.nomanr.animate.compose.data.animationSets
12 | import com.nomanr.animate.compose.sample.components.AdaptiveSampleLayout
13 |
14 | @Composable
15 | fun SampleScreen(
16 | onNavigateToPlayground: (() -> Unit)? = null
17 | ) {
18 | var maxSize by remember { mutableStateOf(DpSize.Zero) }
19 | val animationSetsMap = animationSets(maxSize)
20 |
21 | var currentAnimation by remember { mutableStateOf(animationSetsMap.first().animations.first()) }
22 |
23 | Column(modifier = Modifier.fillMaxSize()) {
24 | AppTopbar(
25 | isPlaygroundScreen = false,
26 | onNavigateToPlayground = onNavigateToPlayground
27 | )
28 |
29 |
30 | AdaptiveSampleLayout(
31 | animationSets = animationSetsMap,
32 | currentAnimation = currentAnimation,
33 | onAnimationSelected = { animation ->
34 | currentAnimation = animation.copy()
35 | },
36 | onSizeChanged = { size ->
37 | maxSize = size
38 | }
39 | )
40 | }
41 | }
--------------------------------------------------------------------------------
/sample/app/web/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
2 | import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
3 |
4 | plugins {
5 | alias(libs.plugins.kotlin.multiplatform)
6 | alias(libs.plugins.compose.compiler)
7 | alias(libs.plugins.compose.multiplatform)
8 | }
9 |
10 | kotlin {
11 | @OptIn(ExperimentalWasmDsl::class)
12 | wasmJs {
13 | moduleName = "composeApp"
14 | browser {
15 | val rootDirPath = project.rootDir.path
16 | val projectDirPath = project.projectDir.path
17 | commonWebpackConfig {
18 | outputFileName = "composeApp.js"
19 | devServer =
20 | (devServer ?: KotlinWebpackConfig.DevServer()).apply {
21 | static =
22 | (static ?: mutableListOf()).apply {
23 | // Serve sources to debug inside browser
24 | add(rootDirPath)
25 | add(projectDirPath)
26 | }
27 | }
28 | }
29 | }
30 | binaries.executable()
31 | }
32 |
33 | js(IR) {
34 | browser {
35 | commonWebpackConfig {
36 | outputFileName = "composeApp.js"
37 | }
38 | }
39 | binaries.executable()
40 | }
41 |
42 | sourceSets {
43 | commonMain.dependencies {
44 | implementation(project(":sample:app:common"))
45 | implementation(compose.runtime)
46 | implementation(compose.foundation)
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/navigation/SampleAppNavHost.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.navigation
2 |
3 | import SampleScreen
4 | import androidx.compose.runtime.Composable
5 | import androidx.navigation.compose.NavHost
6 | import androidx.navigation.compose.composable
7 | import com.nomanr.animate.compose.SampleAppState
8 | import com.nomanr.animate.compose.playground.PlaygroundScreen
9 |
10 | @Composable
11 | fun SampleAppNavHost(
12 | startDestination: NavRoute = NavRoute.Sample,
13 | appState: SampleAppState,
14 | ) {
15 | val navController = appState.navController
16 |
17 |
18 | NavHost(navController = navController, startDestination = startDestination) {
19 | composable {
20 | SampleScreen(
21 | onNavigateToPlayground = {
22 | navController.navigate(NavRoute.Playground)
23 | }
24 | )
25 | }
26 |
27 | composable {
28 | PlaygroundScreen(
29 | onNavigateToSample = {
30 | navController.navigate(NavRoute.Sample) {
31 | popUpTo(NavRoute.Sample) { inclusive = true }
32 | }
33 | },
34 | snackbarHostState = appState.snackbarHostState
35 | )
36 | }
37 |
38 | // composable(
39 | // typeMap = componentIdNavTypeMap,
40 | // ) {
41 | // val args = it.toRoute()
42 | // SampleScreen(componentId = args.componentId, navigateUp = { navController.navigateUp() })
43 | // }
44 |
45 |
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/sample/app/ios/iosApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CADisableMinimumFrameDurationOnPhone
6 |
7 | CFBundleDevelopmentRegion
8 | $(DEVELOPMENT_LANGUAGE)
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIApplicationSceneManifest
26 |
27 | UIApplicationSupportsMultipleScenes
28 |
29 |
30 | UILaunchScreen
31 |
32 | UIRequiredDeviceCapabilities
33 |
34 | armv7
35 |
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UISupportedInterfaceOrientations~ipad
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationPortraitUpsideDown
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/zoomingextrances/ZoomIn.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.zoomingextrances
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class ZoomIn(
14 | ) : AnimationPreset {
15 |
16 | private val ease = CubicBezierEasing(0.25f, 0.10f, 0.25f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.5f,
22 | from = TransformProperties(
23 | alpha = 0.3f,
24 | ),
25 | to = TransformProperties(
26 | alpha = 1f,
27 | ),
28 | easing = ease
29 | ),
30 | Keyframe.Segment(
31 | start = 0f,
32 | end = 1f,
33 | from = TransformProperties(
34 | scaleX = 0.33f,
35 | scaleY = 0.33f
36 | ),
37 | to = TransformProperties(
38 | scaleX = 1f,
39 | scaleY = 1f
40 | ),
41 | easing = ease
42 | ),
43 |
44 | )
45 |
46 | @Composable
47 | override fun animate(progress: State): Modifier =
48 | Modifier.animateKeyframe(
49 | progress = progress,
50 | keyframes = keyframes,
51 | transformOrigin = TransformOrigin(0.5f, 0.5f),
52 | clip = false
53 | )
54 | }
--------------------------------------------------------------------------------
/sample/app/android/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/kotlin/com/nomanr/animate/compose/ui/components/Divider.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.ui.components
2 |
3 | import androidx.compose.foundation.Canvas
4 | import androidx.compose.foundation.layout.fillMaxHeight
5 | import androidx.compose.foundation.layout.fillMaxWidth
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.width
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.geometry.Offset
11 | import androidx.compose.ui.graphics.Color
12 | import androidx.compose.ui.unit.Dp
13 | import androidx.compose.ui.unit.dp
14 | import com.nomanr.animate.compose.ui.AppTheme
15 |
16 | @Composable
17 | fun HorizontalDivider(
18 | modifier: Modifier = Modifier,
19 | thickness: Dp = DividerDefaults.Thickness,
20 | color: Color = DividerDefaults.color,
21 | ) = Canvas(
22 | modifier
23 | .fillMaxWidth()
24 | .height(thickness),
25 | ) {
26 | drawLine(
27 | color = color,
28 | strokeWidth = thickness.toPx(),
29 | start = Offset(0f, thickness.toPx() / 2),
30 | end = Offset(size.width, thickness.toPx() / 2),
31 | )
32 | }
33 |
34 | @Composable
35 | fun VerticalDivider(
36 | modifier: Modifier = Modifier,
37 | thickness: Dp = DividerDefaults.Thickness,
38 | color: Color = DividerDefaults.color,
39 | ) = Canvas(
40 | modifier
41 | .fillMaxHeight()
42 | .width(thickness),
43 | ) {
44 | drawLine(
45 | color = color,
46 | strokeWidth = thickness.toPx(),
47 | start = Offset(thickness.toPx() / 2, 0f),
48 | end = Offset(thickness.toPx() / 2, size.height),
49 | )
50 | }
51 |
52 | object DividerDefaults {
53 | val Thickness: Dp = 3.dp
54 | val color: Color @Composable get() = AppTheme.colors.outline
55 | }
56 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingexits/BounceOutLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingexits
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceOutEasing
12 |
13 | class BounceOutLeft(
14 | private val exitOffsetX: Float = -2000f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Static(
18 | percent = 0f,
19 | transform = TransformProperties(alpha = 1f, translationX = 0f, scaleX = 1f),
20 | easing = bounceOutEasing
21 | ),
22 | Keyframe.Segment(
23 | start = 0f, end = 0.2f,
24 | from = TransformProperties(translationX = 0f, scaleX = 1f),
25 | to = TransformProperties(alpha = 1f, translationX = 20f, scaleX = 0.9f),
26 | easing = bounceOutEasing
27 | ),
28 | Keyframe.Segment(
29 | start = 0.2f, end = 1f,
30 | from = TransformProperties(alpha = 1f, translationX = 20f, scaleX = 0.9f),
31 | to = TransformProperties(alpha = 0f, translationX = exitOffsetX, scaleX = 2f),
32 | easing = bounceOutEasing
33 | )
34 | )
35 |
36 | @Composable
37 | override fun animate(progress: State): Modifier =
38 | Modifier.animateKeyframe(
39 | progress = progress,
40 | keyframes = keyframes,
41 | transformOrigin = TransformOrigin.Center,
42 | clip = false
43 | )
44 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingexits/BounceOutRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingexits
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceOutEasing
12 |
13 | class BounceOutRight(
14 | private val exitOffsetX: Float = 2000f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Static(
18 | percent = 0f,
19 | transform = TransformProperties(alpha = 1f, translationX = 0f, scaleX = 1f),
20 | easing = bounceOutEasing
21 | ),
22 | Keyframe.Segment(
23 | start = 0f, end = 0.2f,
24 | from = TransformProperties(translationX = 0f, scaleX = 1f),
25 | to = TransformProperties(alpha = 1f, translationX = -20f, scaleX = 0.9f),
26 | easing = bounceOutEasing
27 | ),
28 | Keyframe.Segment(
29 | start = 0.2f, end = 1f,
30 | from = TransformProperties(alpha = 1f, translationX = -20f, scaleX = 0.9f),
31 | to = TransformProperties(alpha = 0f, translationX = exitOffsetX, scaleX = 2f),
32 | easing = bounceOutEasing
33 | )
34 | )
35 |
36 | @Composable
37 | override fun animate(progress: State): Modifier =
38 | Modifier.animateKeyframe(
39 | progress = progress,
40 | keyframes = keyframes,
41 | transformOrigin = TransformOrigin.Center,
42 | clip = false
43 | )
44 | }
--------------------------------------------------------------------------------
/.github/workflows/deploy-to-pages.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to GitHub Pages
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | workflow_dispatch:
8 |
9 | permissions:
10 | contents: write
11 | pages: write
12 | id-token: write
13 |
14 | jobs:
15 | deploy-to-pages:
16 | if: github.event_name == 'push' && github.ref == 'refs/heads/main'
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Checkout repository
20 | uses: actions/checkout@v4
21 | with:
22 | token: ${{ secrets.GITHUB_TOKEN }}
23 | fetch-depth: 0
24 |
25 | - name: Set up JDK 17
26 | uses: actions/setup-java@v4
27 | with:
28 | java-version: '17'
29 | distribution: 'temurin'
30 |
31 | - name: Git user configs
32 | run: |
33 | git config --global user.name "github-actions"
34 | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
35 |
36 | - name: Switch to deploy branch and force merge main
37 | run: |
38 | git fetch origin
39 | git checkout -B deploy
40 | git reset --hard origin/main
41 |
42 | - name: Build Sample Web
43 | run: |
44 | ./gradlew :sample:app:web:jsBrowserProductionWebpack
45 |
46 | - name: Move dist to root/docs
47 | run: |
48 | DOCS_DIR=docs
49 | BUILD_DIR=sample/app/web/build/kotlin-webpack/js/productionExecutable
50 |
51 | rm -rf $DOCS_DIR
52 | mkdir -p $DOCS_DIR
53 |
54 | cp -r $BUILD_DIR/* $DOCS_DIR/
55 | cp -r sample/app/web/build/processedResources/js/main/* $DOCS_DIR/
56 |
57 | - name: Add CNAME file
58 | run: echo "animate.nomanr.com" > docs/CNAME
59 |
60 | - name: Force push changes to deploy branch
61 | run: |
62 | git add docs
63 | git commit -m "Deploy to GitHub Pages from commit ${{ github.sha }}"
64 | git push --force origin deploy
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/lightspeed/LightSpeedInLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.lightspeed
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class LightSpeedInLeft(
13 | private val entryOffset: Float = -1000f
14 | ) : AnimationPreset {
15 |
16 | private val easeOut = CubicBezierEasing(0.1f, 0f, 0.3f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.6f,
22 | from = TransformProperties(
23 | translationX = entryOffset,
24 | skewX = 0.65f,
25 | alpha = 0f
26 | ),
27 | to = TransformProperties(
28 | translationX = 0f,
29 | skewX = -0.45f,
30 | alpha = 1f
31 | ),
32 | easing = easeOut
33 | ),
34 | Keyframe.Segment(
35 | start = 0.6f,
36 | end = 0.8f,
37 | from = TransformProperties(skewX = -0.45f),
38 | to = TransformProperties(skewX = 0.15f),
39 | easing = easeOut
40 | ),
41 | Keyframe.Segment(
42 | start = 0.8f,
43 | end = 1f,
44 | from = TransformProperties(skewX = 0.15f),
45 | to = TransformProperties(skewX = 0f),
46 | easing = easeOut
47 | )
48 | )
49 |
50 | @Composable
51 | override fun animate(progress: State): Modifier =
52 | Modifier.animateKeyframe(
53 | progress = progress,
54 | keyframes = keyframes,
55 | )
56 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/lightspeed/LightSpeedInRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.lightspeed
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 |
13 | class LightSpeedInRight(
14 | private val entryOffset: Float = 1000f
15 | ) : AnimationPreset {
16 |
17 | private val easeOut = CubicBezierEasing(0.1f, 0f, 0.3f, 1f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 0.6f,
23 | from = TransformProperties(
24 | translationX = entryOffset,
25 | skewX = -0.65f,
26 | alpha = 0f
27 | ),
28 | to = TransformProperties(
29 | translationX = 0f,
30 | skewX = 0.45f,
31 | alpha = 1f
32 | ),
33 | easing = easeOut
34 | ),
35 | Keyframe.Segment(
36 | start = 0.6f,
37 | end = 0.8f,
38 | from = TransformProperties(skewX = 0.45f),
39 | to = TransformProperties(skewX = -0.15f),
40 | easing = easeOut
41 | ),
42 | Keyframe.Segment(
43 | start = 0.8f,
44 | end = 1f,
45 | from = TransformProperties(skewX = -0.15f),
46 | to = TransformProperties(skewX = 0f),
47 | easing = easeOut
48 | )
49 | )
50 |
51 | @Composable
52 | override fun animate(progress: State): Modifier =
53 | Modifier.animateKeyframe(
54 | progress = progress,
55 | keyframes = keyframes,
56 | )
57 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/attentionseekers/Flash.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.attentionseekers
2 |
3 | import androidx.compose.animation.core.FastOutSlowInEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class Flash(minAlpha: Float = 0f, maxAlpha: Float = 1f) : AnimationPreset {
13 |
14 | private val ease = FastOutSlowInEasing
15 |
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f,
19 | end = 0.25f,
20 | from = TransformProperties(alpha = maxAlpha),
21 | to = TransformProperties(alpha = minAlpha),
22 | easing = ease
23 | ),
24 | Keyframe.Segment(
25 | start = 0.25f,
26 | end = 0.5f,
27 | from = TransformProperties(alpha = minAlpha),
28 | to = TransformProperties(alpha = maxAlpha),
29 | easing = ease
30 | ),
31 | Keyframe.Segment(
32 | start = 0.5f,
33 | end = 0.75f,
34 | from = TransformProperties(alpha = maxAlpha),
35 | to = TransformProperties(alpha = minAlpha),
36 | easing = ease
37 | ),
38 | Keyframe.Segment(
39 | start = 0.75f,
40 | end = 1f,
41 | from = TransformProperties(alpha = minAlpha),
42 | to = TransformProperties(alpha = maxAlpha),
43 | easing = ease
44 | )
45 | )
46 |
47 | @Composable
48 | override fun animate(progress: State): Modifier {
49 | return Modifier.animateKeyframe(
50 | progress = progress,
51 | keyframes = keyframes,
52 | )
53 | }
54 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingexits/defaultEasing.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingexits
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceOutEasing
12 |
13 | class BounceOut : AnimationPreset {
14 | private val keyframes = listOf(
15 | Keyframe.Static(
16 | percent = 0f,
17 | transform = TransformProperties(alpha = 1f, scaleX = 1f, scaleY = 1f),
18 | easing = bounceOutEasing
19 | ),
20 | Keyframe.Segment(
21 | start = 0f, end = 0.2f,
22 | from = TransformProperties(alpha = 1f, scaleX = 1f, scaleY = 1f),
23 | to = TransformProperties(scaleX = 0.9f, scaleY = 0.9f),
24 | easing = bounceOutEasing
25 | ),
26 | Keyframe.Segment(
27 | start = 0.2f, end = 0.55f,
28 | from = TransformProperties(scaleX = 0.9f, scaleY = 0.9f),
29 | to = TransformProperties(alpha = 1f, scaleX = 1.1f, scaleY = 1.1f),
30 | easing = bounceOutEasing
31 | ),
32 | Keyframe.Segment(
33 | start = 0.55f, end = 1f,
34 | from = TransformProperties(alpha = 1f, scaleX = 1.1f, scaleY = 1.1f),
35 | to = TransformProperties(alpha = 0f, scaleX = 0.3f, scaleY = 0.3f),
36 | easing = bounceOutEasing
37 | )
38 | )
39 |
40 | @Composable
41 | override fun animate(progress: State): Modifier =
42 | Modifier.animateKeyframe(
43 | progress = progress,
44 | keyframes = keyframes,
45 | transformOrigin = TransformOrigin.Center,
46 | clip = false
47 | )
48 | }
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/playground/components/configs/AnimationDuration.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.playground.components.configs
2 |
3 | import androidx.compose.foundation.text.KeyboardOptions
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.getValue
6 | import androidx.compose.runtime.mutableStateOf
7 | import androidx.compose.runtime.remember
8 | import androidx.compose.runtime.setValue
9 | import androidx.compose.ui.text.input.KeyboardType
10 | import com.nomanr.animate.compose.playground.LocalPlaygroundState
11 | import com.nomanr.animate.compose.ui.AppTheme
12 | import com.nomanr.animate.compose.ui.components.Text
13 | import com.nomanr.animate.compose.ui.components.textfield.OutlinedTextField
14 |
15 | @Composable
16 | fun AnimationDuration() {
17 | val presetState = LocalPlaygroundState.current
18 | var textValue by remember(presetState.duration) {
19 | mutableStateOf(presetState.duration.toString())
20 | }
21 |
22 | ConfigurationSection(title = "Animation Duration") {
23 | OutlinedTextField(
24 | value = textValue,
25 | onValueChange = { newValue ->
26 | textValue = newValue
27 | newValue.toIntOrNull()?.let { milliseconds ->
28 | if (milliseconds > 0) {
29 | presetState.updateDuration(milliseconds)
30 | }
31 | }
32 | },
33 | suffix = {
34 | Text(
35 | "ms", style = AppTheme.typography.label2, color = AppTheme.colors.text
36 | )
37 | },
38 | textStyle = AppTheme.typography.body2,
39 | keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
40 | singleLine = true,
41 | label = {
42 | Text(
43 | text = "Duration",
44 | style = AppTheme.typography.label2,
45 | color = AppTheme.colors.text
46 | )
47 | })
48 | }
49 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/zooms/ZoomOut.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.zooms
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class ZoomOut : AnimationPreset {
14 |
15 | private val enterEasing = CubicBezierEasing(0.55f, 0.055f, 0.675f, 0.19f)
16 | private val settleEasing = CubicBezierEasing(0.175f, 0.885f, 0.32f, 1f)
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Segment(
20 | start = 0f,
21 | end = 0.5f,
22 | from = TransformProperties(
23 | scaleX = 1f,
24 | scaleY = 1f,
25 | alpha = 1f
26 | ),
27 | to = TransformProperties(
28 | scaleX = 0.3f,
29 | scaleY = 0.3f,
30 | alpha = 0f
31 | ),
32 | easing = enterEasing
33 | ),
34 | Keyframe.Segment(
35 | start = 0.5f,
36 | end = 1f,
37 | from = TransformProperties(
38 | scaleX = 0.3f,
39 | scaleY = 0.3f,
40 | alpha = 0f
41 | ),
42 | to = TransformProperties(
43 | scaleX = 0.1f,
44 | scaleY = 0.1f,
45 | alpha = 0f
46 | ),
47 | easing = settleEasing
48 | )
49 | )
50 |
51 | @Composable
52 | override fun animate(progress: State): Modifier =
53 | Modifier.animateKeyframe(
54 | progress = progress,
55 | keyframes = keyframes,
56 | transformOrigin = TransformOrigin.Center,
57 | clip = false
58 | )
59 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/lightspeed/LightSpeedOutRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.lightspeed
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class LightSpeedOutRight(
14 | private val exitOffset: Float = 1000f
15 | ) : AnimationPreset {
16 |
17 | private val easeIn = CubicBezierEasing(0.55f, 0.055f, 0.675f, 0.19f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 0.65f,
23 | from = TransformProperties(
24 | translationX = 0f,
25 | skewX = 0f,
26 | alpha = 1f
27 | ),
28 | to = TransformProperties(
29 | translationX = exitOffset / 2,
30 | skewX = 0.65f,
31 | alpha = 0f
32 | ),
33 | easing = easeIn
34 | ),
35 | Keyframe.Segment(
36 | start = 0.65f,
37 | end = 1f,
38 | from = TransformProperties(
39 | translationX = exitOffset / 2,
40 | skewX = 0.65f,
41 | alpha = 0f
42 | ),
43 | to = TransformProperties(
44 | translationX = exitOffset,
45 | skewX = 0.65f,
46 | alpha = 0f
47 | ),
48 | easing = easeIn
49 | )
50 | )
51 |
52 | @Composable
53 | override fun animate(progress: State): Modifier =
54 | Modifier.animateKeyframe(
55 | progress = progress,
56 | keyframes = keyframes,
57 | transformOrigin = TransformOrigin(1f, 0f),
58 | clip = false
59 | )
60 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/lightspeed/LightSpeedOutLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.lightspeed
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class LightSpeedOutLeft(
14 | private val exitOffset: Float = -1000f
15 | ) : AnimationPreset {
16 |
17 | private val easeIn = CubicBezierEasing(0.55f, 0.055f, 0.675f, 0.19f)
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 0.65f,
23 | from = TransformProperties(
24 | translationX = 0f,
25 | skewX = 0f,
26 | alpha = 1f
27 | ),
28 | to = TransformProperties(
29 | translationX = exitOffset / 2,
30 | skewX = -0.65f,
31 | alpha = 0f
32 | ),
33 | easing = easeIn
34 | ),
35 | Keyframe.Segment(
36 | start = 0.65f,
37 | end = 1f,
38 | from = TransformProperties(
39 | translationX = exitOffset / 2,
40 | skewX = -0.65f,
41 | alpha = 0f
42 | ),
43 | to = TransformProperties(
44 | translationX = exitOffset,
45 | skewX = -0.65f,
46 | alpha = 0f
47 | ),
48 | easing = easeIn
49 | )
50 | )
51 |
52 | @Composable
53 | override fun animate(progress: State): Modifier =
54 | Modifier.animateKeyframe(
55 | progress = progress,
56 | keyframes = keyframes,
57 | transformOrigin = TransformOrigin(0f, 0f),
58 | clip = false
59 | )
60 | }
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/kotlin/com/nomanr/animate/compose/ui/AdaptiveProvider.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.ui
2 |
3 | import androidx.compose.foundation.layout.BoxWithConstraints
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.CompositionLocalProvider
6 | import androidx.compose.runtime.compositionLocalOf
7 | import androidx.compose.ui.Modifier
8 | import androidx.compose.ui.unit.Dp
9 | import androidx.compose.ui.unit.dp
10 |
11 | /**
12 | * Adaptive screen size configuration
13 | */
14 | data class AdaptiveInfo(
15 | val screenWidth: Dp,
16 | val screenHeight: Dp,
17 | val isCompact: Boolean,
18 | val isMedium: Boolean,
19 | val isExpanded: Boolean
20 | ) {
21 | companion object {
22 | val CompactMaxWidth = 600.dp
23 | val MediumMaxWidth = 840.dp
24 |
25 | fun fromSize(width: Dp, height: Dp): AdaptiveInfo {
26 | return AdaptiveInfo(
27 | screenWidth = width,
28 | screenHeight = height,
29 | isCompact = width < CompactMaxWidth,
30 | isMedium = width >= CompactMaxWidth && width < MediumMaxWidth,
31 | isExpanded = width >= MediumMaxWidth
32 | )
33 | }
34 | }
35 | }
36 |
37 | /**
38 | * CompositionLocal for providing adaptive screen information
39 | */
40 | val LocalAdaptiveInfo = compositionLocalOf {
41 | error("AdaptiveInfo not provided")
42 | }
43 |
44 | /**
45 | * Provider that automatically detects screen size and provides adaptive information
46 | */
47 | @Composable
48 | fun AdaptiveProvider(
49 | modifier: Modifier = Modifier,
50 | content: @Composable () -> Unit
51 | ) {
52 | BoxWithConstraints(modifier = modifier) {
53 | val adaptiveInfo = AdaptiveInfo.fromSize(maxWidth, maxHeight)
54 |
55 | CompositionLocalProvider(
56 | LocalAdaptiveInfo provides adaptiveInfo,
57 | content = content
58 | )
59 | }
60 | }
61 |
62 | /**
63 | * Hook to access current adaptive information
64 | */
65 | @Composable
66 | fun currentAdaptiveInfo(): AdaptiveInfo = LocalAdaptiveInfo.current
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/specials/JackInTheBox.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.specials
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class JackInTheBox(
14 | ) : AnimationPreset {
15 | private val keyframes = listOf(
16 | Keyframe.Segment(
17 | start = 0f, end = 0.5f,
18 | from = TransformProperties(
19 | scaleX = 0.1f,
20 | scaleY = 0.1f,
21 | rotationZ = 30f,
22 | alpha = 0f
23 | ),
24 | to = TransformProperties(
25 | scaleX = 1f,
26 | scaleY = 1f,
27 | rotationZ = -10f,
28 | alpha = 1f
29 | ),
30 | easing = EaseOut
31 | ),
32 | Keyframe.Segment(
33 | start = 0.5f, end = 0.7f,
34 | from = TransformProperties(
35 | rotationZ = -10f,
36 | ),
37 | to = TransformProperties(
38 | rotationZ = 3f,
39 | ),
40 | easing = EaseOut
41 | ),
42 | Keyframe.Segment(
43 | start = 0.7f, end = 1f,
44 | from = TransformProperties(
45 | rotationZ = 3f,
46 | ),
47 | to = TransformProperties(scaleX = 1f, scaleY = 1f, rotationZ = 0f, alpha = 1f),
48 | easing = EaseOut
49 | )
50 | )
51 |
52 | @Composable
53 | override fun animate(progress: State): Modifier =
54 | Modifier.animateKeyframe(
55 | progress = progress,
56 | keyframes = keyframes,
57 | transformOrigin = TransformOrigin(0.5f, 1f),
58 | clip = false
59 | )
60 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingexits/BounceOutDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingexits
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceOutEasing
12 |
13 | class BounceOutDown(
14 | private val exitOffsetY: Float = 2000f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Static(
18 | percent = 0f,
19 | transform = TransformProperties(alpha = 1f, translationY = 0f, scaleY = 1f),
20 | easing = bounceOutEasing
21 | ),
22 | Keyframe.Segment(
23 | start = 0f, end = 0.2f,
24 | from = TransformProperties(translationY = 0f, scaleY = 1f),
25 | to = TransformProperties(translationY = 10f, scaleY = 0.985f),
26 | easing = bounceOutEasing
27 | ),
28 | Keyframe.Segment(
29 | start = 0.2f, end = 0.45f,
30 | from = TransformProperties(translationY = 10f, scaleY = 0.985f),
31 | to = TransformProperties(alpha = 1f, translationY = -20f, scaleY = 0.9f),
32 | easing = bounceOutEasing
33 | ),
34 | Keyframe.Segment(
35 | start = 0.45f, end = 1f,
36 | from = TransformProperties(alpha = 1f, translationY = -20f, scaleY = 0.9f),
37 | to = TransformProperties(alpha = 0f, translationY = exitOffsetY, scaleY = 3f),
38 | easing = bounceOutEasing
39 | )
40 | )
41 |
42 | @Composable
43 | override fun animate(progress: State): Modifier =
44 | Modifier.animateKeyframe(
45 | progress = progress,
46 | keyframes = keyframes,
47 | transformOrigin = TransformOrigin.Center,
48 | clip = false
49 | )
50 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingexits/BounceOutUp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingexits
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceOutEasing
12 |
13 | class BounceOutUp(
14 | private val exitOffsetY: Float = -2000f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Static(
18 | percent = 0f,
19 | transform = TransformProperties(alpha = 1f, translationY = 0f, scaleY = 1f),
20 | easing = bounceOutEasing
21 | ),
22 | Keyframe.Segment(
23 | start = 0f, end = 0.2f,
24 | from = TransformProperties(translationY = 0f, scaleY = 1f),
25 | to = TransformProperties(translationY = -10f, scaleY = 0.985f),
26 | easing = bounceOutEasing
27 | ),
28 | Keyframe.Segment(
29 | start = 0.2f, end = 0.45f,
30 | from = TransformProperties(translationY = -10f, scaleY = 0.985f),
31 | to = TransformProperties(alpha = 1f, translationY = 20f, scaleY = 0.9f),
32 | easing = bounceOutEasing
33 | ),
34 | Keyframe.Segment(
35 | start = 0.45f, end = 1f,
36 | from = TransformProperties(alpha = 1f, translationY = 20f, scaleY = 0.9f),
37 | to = TransformProperties(alpha = 0f, translationY = exitOffsetY, scaleY = 3f),
38 | easing = bounceOutEasing
39 | )
40 | )
41 |
42 | @Composable
43 | override fun animate(progress: State): Modifier =
44 | Modifier.animateKeyframe(
45 | progress = progress,
46 | keyframes = keyframes,
47 | transformOrigin = TransformOrigin.Center,
48 | clip = false
49 | )
50 | }
--------------------------------------------------------------------------------
/sample/ui-components/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | alias(libs.plugins.kotlin.multiplatform)
6 | alias(libs.plugins.android.library)
7 | alias(libs.plugins.compose.compiler)
8 | alias(libs.plugins.compose.multiplatform)
9 | }
10 |
11 | kotlin {
12 | androidTarget {
13 | compilerOptions {
14 | jvmTarget.set(JvmTarget.JVM_11)
15 | }
16 | }
17 |
18 | iosArm64()
19 | iosX64()
20 | iosSimulatorArm64()
21 | macosX64()
22 | macosArm64()
23 |
24 | jvm("desktop")
25 |
26 | @OptIn(ExperimentalWasmDsl::class)
27 | wasmJs {
28 | browser()
29 | }
30 | js(IR)
31 |
32 | sourceSets {
33 |
34 | androidMain.dependencies {
35 | implementation(compose.preview)
36 | implementation(libs.androidx.activity.compose)
37 | implementation(libs.androidx.compose.ui.tooling.preview)
38 | }
39 | commonMain.dependencies {
40 | api(compose.runtime)
41 | api(compose.foundation)
42 | api(compose.material3)
43 | api(compose.materialIconsExtended)
44 | api(compose.ui)
45 | api(libs.nomanr.composables)
46 | api(compose.components.resources)
47 | api(compose.components.uiToolingPreview)
48 | api(libs.androidx.lifecycle.runtime.multiplatform)
49 | }
50 |
51 | }
52 |
53 | }
54 |
55 | android {
56 | namespace = "com.nomanr.animate.compose.ui"
57 | compileSdk = libs.versions.compileSdk.get().toInt()
58 |
59 | defaultConfig {
60 | minSdk = libs.versions.minSdk.get().toInt()
61 | targetSdk = libs.versions.targetSdk.get().toInt()
62 | }
63 | packaging {
64 | resources {
65 | excludes += "/META-INF/{AL2.0,LGPL2.1}"
66 | }
67 | }
68 | buildTypes {
69 | getByName("release") {
70 | isMinifyEnabled = false
71 | }
72 | }
73 | compileOptions {
74 | sourceCompatibility = JavaVersion.VERSION_11
75 | targetCompatibility = JavaVersion.VERSION_11
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/flippers/FlipOutX.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.flippers
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import androidx.compose.ui.platform.LocalDensity
9 | import androidx.compose.ui.unit.Dp
10 | import androidx.compose.ui.unit.dp
11 | import com.nomanr.animate.compose.core.AnimationPreset
12 | import com.nomanr.animate.compose.core.Keyframe
13 | import com.nomanr.animate.compose.core.TransformProperties
14 | import com.nomanr.animate.compose.core.animateKeyframe
15 |
16 | class FlipOutX(
17 | private val cameraDistance: Dp = 8.dp
18 | ) : AnimationPreset {
19 |
20 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
21 |
22 | private val keyframes = listOf(
23 | Keyframe.Segment(
24 | start = 0f,
25 | end = 0.3f,
26 | from = TransformProperties(rotationX = 0f, alpha = 1f),
27 | to = TransformProperties(rotationX = -20f, alpha = 1f),
28 | easing = ease
29 | ),
30 | Keyframe.Segment(
31 | start = 0.3f,
32 | end = 1f,
33 | from = TransformProperties(rotationX = -20f, alpha = 1f),
34 | to = TransformProperties(rotationX = 90f, alpha = 0f),
35 | easing = ease
36 | )
37 | )
38 |
39 | @Composable
40 | override fun animate(progress: State): Modifier {
41 | val density = LocalDensity.current
42 | val cameraDistancePx = with(density) { cameraDistance.toPx() }
43 |
44 | val frames = keyframes.map { keyframe ->
45 | keyframe.copy(
46 | from = keyframe.from.copy(cameraDistance = cameraDistancePx),
47 | to = keyframe.to.copy(cameraDistance = cameraDistancePx)
48 | )
49 | }
50 |
51 | return Modifier.animateKeyframe(
52 | progress = progress,
53 | keyframes = frames,
54 | transformOrigin = TransformOrigin.Center,
55 | clip = false
56 | )
57 | }
58 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/flippers/FlipOutY.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.flippers
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import androidx.compose.ui.platform.LocalDensity
9 | import androidx.compose.ui.unit.Dp
10 | import androidx.compose.ui.unit.dp
11 | import com.nomanr.animate.compose.core.AnimationPreset
12 | import com.nomanr.animate.compose.core.Keyframe
13 | import com.nomanr.animate.compose.core.TransformProperties
14 | import com.nomanr.animate.compose.core.animateKeyframe
15 |
16 | class FlipOutY(
17 | private val cameraDistance: Dp = 8.dp
18 | ) : AnimationPreset {
19 |
20 | private val ease = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
21 |
22 | private val keyframes = listOf(
23 | Keyframe.Segment(
24 | start = 0f,
25 | end = 0.3f,
26 | from = TransformProperties(rotationY = 0f, alpha = 1f),
27 | to = TransformProperties(rotationY = -15f, alpha = 1f),
28 | easing = ease
29 | ),
30 | Keyframe.Segment(
31 | start = 0.3f,
32 | end = 1f,
33 | from = TransformProperties(rotationY = -15f, alpha = 1f),
34 | to = TransformProperties(rotationY = 90f, alpha = 0f),
35 | easing = ease
36 | )
37 | )
38 |
39 | @Composable
40 | override fun animate(progress: State): Modifier {
41 | val density = LocalDensity.current
42 | val cameraDistancePx = with(density) { cameraDistance.toPx() }
43 |
44 | val frames = keyframes.map { keyframe ->
45 | keyframe.copy(
46 | from = keyframe.from.copy(cameraDistance = cameraDistancePx),
47 | to = keyframe.to.copy(cameraDistance = cameraDistancePx)
48 | )
49 | }
50 |
51 | return Modifier.animateKeyframe(
52 | progress = progress,
53 | keyframes = frames,
54 | transformOrigin = TransformOrigin.Center,
55 | clip = false
56 | )
57 | }
58 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/specials/Hinge.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.specials
2 |
3 | import androidx.compose.animation.core.EaseInOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class Hinge(
14 | private val fallDistance: Float = 700f
15 | ) : AnimationPreset {
16 | private val keyframes = listOf(
17 | Keyframe.Segment(
18 | start = 0f, end = 0.2f,
19 | from = TransformProperties(rotationZ = 0f),
20 | to = TransformProperties(rotationZ = 80f),
21 | easing = EaseInOut
22 | ),
23 | Keyframe.Segment(
24 | start = 0.2f, end = 0.4f,
25 | from = TransformProperties(rotationZ = 80f),
26 | to = TransformProperties(rotationZ = 60f),
27 | easing = EaseInOut
28 | ),
29 | Keyframe.Segment(
30 | start = 0.4f, end = 0.6f,
31 | from = TransformProperties(rotationZ = 60f),
32 | to = TransformProperties(rotationZ = 80f),
33 | easing = EaseInOut
34 | ),
35 | Keyframe.Segment(
36 | start = 0.6f, end = 0.8f,
37 | from = TransformProperties(rotationZ = 80f),
38 | to = TransformProperties(rotationZ = 60f),
39 | easing = EaseInOut
40 | ),
41 | Keyframe.Segment(
42 | start = 0.8f, end = 1f,
43 | from = TransformProperties(rotationZ = 60f, translationY = 0f, alpha = 1f),
44 | to = TransformProperties(rotationZ = 10f, translationY = fallDistance, alpha = 0f),
45 | easing = EaseInOut
46 | )
47 | )
48 |
49 | @Composable
50 | override fun animate(progress: State): Modifier =
51 | Modifier.animateKeyframe(
52 | progress = progress,
53 | keyframes = keyframes,
54 | transformOrigin = TransformOrigin(0f, 0f),
55 | clip = false
56 | )
57 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/backentrances/BackInDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.backentrances
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.runtime.getValue
7 | import androidx.compose.runtime.mutableStateOf
8 | import androidx.compose.runtime.setValue
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.graphics.TransformOrigin
11 | import com.nomanr.animate.compose.core.AnimationPreset
12 | import com.nomanr.animate.compose.core.Keyframe
13 | import com.nomanr.animate.compose.core.TransformProperties
14 | import com.nomanr.animate.compose.core.animateKeyframe
15 |
16 | class BackInDown(
17 | private val entranceOffsetY: Float = -1200f,
18 | ) : AnimationPreset {
19 |
20 | private var translationY by mutableStateOf(entranceOffsetY)
21 |
22 | private val keyframes: List
23 | get() = listOf(
24 | Keyframe.Static(
25 | percent = 0f, transform = TransformProperties(
26 | translationY = -translationY, scaleX = 0.7f, scaleY = 0.7f, alpha = 0.7f
27 | ), easing = EaseOut
28 | ), Keyframe.Segment(
29 | start = 0f, end = 0.8f, from = TransformProperties(
30 | translationY = translationY, scaleX = 0.7f, scaleY = 0.7f, alpha = 0.7f
31 | ), to = TransformProperties(
32 | translationY = 0f, scaleX = 0.7f, scaleY = 0.7f, alpha = 0.7f
33 | ), easing = EaseOut
34 | ), Keyframe.Segment(
35 | start = 0.8f, end = 1f, from = TransformProperties(
36 | translationY = 0f, scaleX = 0.7f, scaleY = 0.7f, alpha = 0.7f
37 | ), to = TransformProperties(
38 | translationY = 0f, scaleX = 1f, scaleY = 1f, alpha = 1f
39 | ), easing = EaseOut
40 | )
41 | )
42 |
43 | @Composable
44 | override fun animate(progress: State): Modifier {
45 | return Modifier.animateKeyframe(
46 | progress = progress,
47 | keyframes = keyframes,
48 | transformOrigin = TransformOrigin.Center,
49 | clip = false
50 | )
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/attentionseekers/HeartBeat.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.attentionseekers
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 |
12 | class HeartBeat(heartScale: Float = 1.25f) : AnimationPreset {
13 | private val easing = CubicBezierEasing(0.42f, 0.0f, 0.58f, 1.0f)
14 |
15 | private val keyframes = listOf(
16 | Keyframe.Segment(
17 | start = 0f,
18 | end = 0.14f,
19 | from = TransformProperties(scaleX = 1f, scaleY = 1f),
20 | to = TransformProperties(scaleX = heartScale, scaleY = heartScale),
21 | easing = easing
22 | ),
23 | Keyframe.Segment(
24 | start = 0.14f,
25 | end = 0.28f,
26 | from = TransformProperties(scaleX = heartScale, scaleY = heartScale),
27 | to = TransformProperties(scaleX = 1f, scaleY = 1f),
28 | easing = easing
29 | ),
30 | Keyframe.Segment(
31 | start = 0.28f,
32 | end = 0.42f,
33 | from = TransformProperties(scaleX = 1f, scaleY = 1f),
34 | to = TransformProperties(scaleX = heartScale, scaleY = heartScale),
35 | easing = easing
36 | ),
37 | Keyframe.Segment(
38 | start = 0.42f,
39 | end = 0.70f,
40 | from = TransformProperties(scaleX = heartScale, scaleY = heartScale),
41 | to = TransformProperties(scaleX = 1f, scaleY = 1f),
42 | easing = easing
43 | ),
44 | Keyframe.Segment(
45 | start = 0.70f,
46 | end = 1f,
47 | from = TransformProperties(scaleX = 1f, scaleY = 1f),
48 | to = TransformProperties(scaleX = 1f, scaleY = 1f),
49 | easing = easing
50 | )
51 | )
52 |
53 | @Composable
54 | override fun animate(progress: State): Modifier {
55 | return Modifier.animateKeyframe(progress, keyframes)
56 | }
57 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/zooms/ZoomOutUp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.zooms
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class ZoomOutUp(
14 | private val peakOffsetY: Float = 60f,
15 | private val vanishOffsetY: Float = -400f
16 | ) : AnimationPreset {
17 |
18 | private val enterEasing = CubicBezierEasing(0.55f, 0.055f, 0.675f, 0.19f)
19 | private val settleEasing = CubicBezierEasing(0.175f, 0.885f, 0.32f, 1f)
20 |
21 | private val keyframes = listOf(
22 | Keyframe.Segment(
23 | start = 0f,
24 | end = 0.4f,
25 | from = TransformProperties(
26 | translationY = 0f,
27 | scaleX = 1f,
28 | scaleY = 1f,
29 | alpha = 1f
30 | ),
31 | to = TransformProperties(
32 | translationY = peakOffsetY,
33 | scaleX = 0.475f,
34 | scaleY = 0.475f,
35 | alpha = 1f
36 | ),
37 | easing = enterEasing
38 | ),
39 | Keyframe.Segment(
40 | start = 0.4f,
41 | end = 1f,
42 | from = TransformProperties(
43 | translationY = peakOffsetY,
44 | scaleX = 0.475f,
45 | scaleY = 0.475f,
46 | alpha = 1f
47 | ),
48 | to = TransformProperties(
49 | translationY = vanishOffsetY,
50 | scaleX = 0.1f,
51 | scaleY = 0.1f,
52 | alpha = 0f
53 | ),
54 | easing = settleEasing
55 | )
56 | )
57 |
58 | @Composable
59 | override fun animate(progress: State): Modifier =
60 | Modifier.animateKeyframe(
61 | progress = progress,
62 | keyframes = keyframes,
63 | transformOrigin = TransformOrigin.Center,
64 | clip = false
65 | )
66 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/zooms/ZoomOutDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.zooms
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class ZoomOutDown(
14 | private val peakOffsetY: Float = -60f,
15 | private val vanishOffsetY: Float = 400f
16 | ) : AnimationPreset {
17 |
18 | private val enterEasing = CubicBezierEasing(0.55f, 0.055f, 0.675f, 0.19f)
19 | private val settleEasing = CubicBezierEasing(0.175f, 0.885f, 0.32f, 1f)
20 |
21 | private val keyframes = listOf(
22 | Keyframe.Segment(
23 | start = 0f,
24 | end = 0.4f,
25 | from = TransformProperties(
26 | translationY = 0f,
27 | scaleX = 1f,
28 | scaleY = 1f,
29 | alpha = 1f
30 | ),
31 | to = TransformProperties(
32 | translationY = peakOffsetY,
33 | scaleX = 0.475f,
34 | scaleY = 0.475f,
35 | alpha = 1f
36 | ),
37 | easing = enterEasing
38 | ),
39 | Keyframe.Segment(
40 | start = 0.4f,
41 | end = 1f,
42 | from = TransformProperties(
43 | translationY = peakOffsetY,
44 | scaleX = 0.475f,
45 | scaleY = 0.475f,
46 | alpha = 1f
47 | ),
48 | to = TransformProperties(
49 | translationY = vanishOffsetY,
50 | scaleX = 0.1f,
51 | scaleY = 0.1f,
52 | alpha = 0f
53 | ),
54 | easing = settleEasing
55 | )
56 | )
57 |
58 | @Composable
59 | override fun animate(progress: State): Modifier =
60 | Modifier.animateKeyframe(
61 | progress = progress,
62 | keyframes = keyframes,
63 | transformOrigin = TransformOrigin.Center,
64 | clip = false
65 | )
66 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/zooms/ZoomOutLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.zooms
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class ZoomOutLeft(
14 | private val peakOffsetX: Float = 42f,
15 | private val vanishOffsetX: Float = -400f
16 | ) : AnimationPreset {
17 |
18 | private val enterEasing = CubicBezierEasing(0.55f, 0.055f, 0.675f, 0.19f)
19 | private val settleEasing = CubicBezierEasing(0.175f, 0.885f, 0.32f, 1f)
20 |
21 | private val keyframes = listOf(
22 | Keyframe.Segment(
23 | start = 0f,
24 | end = 0.4f,
25 | from = TransformProperties(
26 | translationX = 0f,
27 | scaleX = 1f,
28 | scaleY = 1f,
29 | alpha = 1f
30 | ),
31 | to = TransformProperties(
32 | translationX = peakOffsetX,
33 | scaleX = 0.475f,
34 | scaleY = 0.475f,
35 | alpha = 1f
36 | ),
37 | easing = enterEasing
38 | ),
39 | Keyframe.Segment(
40 | start = 0.4f,
41 | end = 1f,
42 | from = TransformProperties(
43 | translationX = peakOffsetX,
44 | scaleX = 0.475f,
45 | scaleY = 0.475f,
46 | alpha = 1f
47 | ),
48 | to = TransformProperties(
49 | translationX = vanishOffsetX,
50 | scaleX = 0.1f,
51 | scaleY = 0.1f,
52 | alpha = 0f
53 | ),
54 | easing = settleEasing
55 | )
56 | )
57 |
58 | @Composable
59 | override fun animate(progress: State): Modifier =
60 | Modifier.animateKeyframe(
61 | progress = progress,
62 | keyframes = keyframes,
63 | transformOrigin = TransformOrigin.Center,
64 | clip = false
65 | )
66 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/zooms/ZoomOutRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.zooms
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class ZoomOutRight(
14 | private val peakOffsetX: Float = -42f,
15 | private val vanishOffsetX: Float = 400f
16 | ) : AnimationPreset {
17 |
18 | private val enterEasing = CubicBezierEasing(0.55f, 0.055f, 0.675f, 0.19f)
19 | private val settleEasing = CubicBezierEasing(0.175f, 0.885f, 0.32f, 1f)
20 |
21 | private val keyframes = listOf(
22 | Keyframe.Segment(
23 | start = 0f,
24 | end = 0.4f,
25 | from = TransformProperties(
26 | translationX = 0f,
27 | scaleX = 1f,
28 | scaleY = 1f,
29 | alpha = 1f
30 | ),
31 | to = TransformProperties(
32 | translationX = peakOffsetX,
33 | scaleX = 0.475f,
34 | scaleY = 0.475f,
35 | alpha = 1f
36 | ),
37 | easing = enterEasing
38 | ),
39 | Keyframe.Segment(
40 | start = 0.4f,
41 | end = 1f,
42 | from = TransformProperties(
43 | translationX = peakOffsetX,
44 | scaleX = 0.475f,
45 | scaleY = 0.475f,
46 | alpha = 1f
47 | ),
48 | to = TransformProperties(
49 | translationX = vanishOffsetX,
50 | scaleX = 0.1f,
51 | scaleY = 0.1f,
52 | alpha = 0f
53 | ),
54 | easing = settleEasing
55 | )
56 | )
57 |
58 | @Composable
59 | override fun animate(progress: State): Modifier =
60 | Modifier.animateKeyframe(
61 | progress = progress,
62 | keyframes = keyframes,
63 | transformOrigin = TransformOrigin.Center,
64 | clip = false
65 | )
66 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/backexists/BackOutDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.backexists
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.runtime.getValue
7 | import androidx.compose.runtime.mutableStateOf
8 | import androidx.compose.runtime.setValue
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.graphics.TransformOrigin
11 | import com.nomanr.animate.compose.core.AnimationPreset
12 | import com.nomanr.animate.compose.core.Keyframe
13 | import com.nomanr.animate.compose.core.TransformProperties
14 | import com.nomanr.animate.compose.core.animateKeyframe
15 |
16 | class BackOutDown(
17 | private val exitOffsetY: Float = 1200f
18 | ) : AnimationPreset {
19 |
20 | private var translationY by mutableStateOf(exitOffsetY)
21 |
22 | private val keyframes: List
23 | get() = listOf(
24 | Keyframe.Static(
25 | percent = 0f,
26 | transform = TransformProperties(scaleX = 1f, scaleY = 1f, alpha = 1f),
27 | easing = EaseOut
28 | ), Keyframe.Segment(
29 | start = 0f,
30 | end = 0.2f,
31 | from = TransformProperties(scaleX = 1f, scaleY = 1f, alpha = 1f),
32 | to = TransformProperties(scaleX = 0.7f, scaleY = 0.7f, alpha = 0.7f),
33 | easing = EaseOut
34 | ), Keyframe.Segment(
35 | start = 0.2f,
36 | end = 1f,
37 | from = TransformProperties(
38 | translationY = 0f,
39 | scaleX = 0.7f,
40 | scaleY = 0.7f,
41 | alpha = 0.7f
42 | ),
43 | to = TransformProperties(
44 | translationY = translationY,
45 | scaleX = 0.7f,
46 | scaleY = 0.7f,
47 | alpha = 0.7f
48 | ),
49 | easing = EaseOut
50 | )
51 | )
52 |
53 | @Composable
54 | override fun animate(progress: State): Modifier {
55 | return Modifier.animateKeyframe(
56 | progress = progress,
57 | keyframes = keyframes,
58 | transformOrigin = TransformOrigin.Center,
59 | clip = false
60 | )
61 | }
62 | }
--------------------------------------------------------------------------------
/sample/ui-components/src/commonMain/kotlin/com/nomanr/animate/compose/ui/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.ui
2 |
3 | import androidx.compose.foundation.LocalIndication
4 | import androidx.compose.foundation.isSystemInDarkTheme
5 | import androidx.compose.foundation.text.selection.LocalTextSelectionColors
6 | import androidx.compose.foundation.text.selection.TextSelectionColors
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.runtime.CompositionLocalProvider
9 | import androidx.compose.runtime.ReadOnlyComposable
10 | import androidx.compose.runtime.remember
11 | import androidx.compose.ui.graphics.Color
12 | import com.nomanr.animate.compose.ui.foundation.ripple
13 |
14 | object AppTheme {
15 | val colors: Colors
16 | @ReadOnlyComposable @Composable
17 | get() = LocalColors.current
18 |
19 | val typography: Typography
20 | @ReadOnlyComposable @Composable
21 | get() = LocalTypography.current
22 | }
23 |
24 | @Composable
25 | fun AppTheme(
26 | isDarkTheme: Boolean = isSystemInDarkTheme(),
27 | content: @Composable () -> Unit,
28 | ) {
29 | val rippleIndication = ripple()
30 | val selectionColors = rememberTextSelectionColors(LightColors)
31 | val typography = provideTypography()
32 | val colors = if (isDarkTheme) DarkColors else LightColors
33 |
34 | CompositionLocalProvider(
35 | LocalColors provides colors,
36 | LocalTypography provides typography,
37 | LocalIndication provides rippleIndication,
38 | LocalTextSelectionColors provides selectionColors,
39 | LocalContentColor provides colors.contentColorFor(colors.background),
40 | LocalTextStyle provides typography.body1,
41 | content = content,
42 | )
43 | }
44 |
45 | @Composable
46 | fun contentColorFor(color: Color): Color {
47 | return AppTheme.colors.contentColorFor(color)
48 | }
49 |
50 | @Composable
51 | fun hardShadowColorFor(color: Color): Color {
52 | return AppTheme.colors.hardShadowColorFor(color)
53 | }
54 |
55 | @Composable
56 | internal fun rememberTextSelectionColors(colorScheme: Colors): TextSelectionColors {
57 | val primaryColor = colorScheme.primary
58 | return remember(primaryColor) {
59 | TextSelectionColors(
60 | handleColor = primaryColor,
61 | backgroundColor = primaryColor.copy(alpha = TextSelectionBackgroundOpacity),
62 | )
63 | }
64 | }
65 |
66 | internal const val TextSelectionBackgroundOpacity = 0.4f
67 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/attentionseekers/Swing.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.attentionseekers
2 |
3 | import androidx.compose.animation.core.FastOutSlowInEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.TransformOrigin
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class Swing(
14 | swingAngle: Float = 15f
15 | ) : AnimationPreset {
16 |
17 | private val ease = FastOutSlowInEasing
18 |
19 | private val keyframes = listOf(
20 | Keyframe.Segment(
21 | start = 0f,
22 | end = 0.20f,
23 | from = TransformProperties(rotationZ = 0f),
24 | to = TransformProperties(rotationZ = swingAngle),
25 | easing = ease
26 | ),
27 | Keyframe.Segment(
28 | start = 0.20f,
29 | end = 0.40f,
30 | from = TransformProperties(rotationZ = swingAngle),
31 | to = TransformProperties(rotationZ = -swingAngle * 0.66f),
32 | easing = ease
33 | ),
34 | Keyframe.Segment(
35 | start = 0.40f,
36 | end = 0.60f,
37 | from = TransformProperties(rotationZ = -swingAngle * 0.66f),
38 | to = TransformProperties(rotationZ = swingAngle * 0.33f),
39 | easing = ease
40 | ),
41 | Keyframe.Segment(
42 | start = 0.60f,
43 | end = 0.80f,
44 | from = TransformProperties(rotationZ = swingAngle * 0.33f),
45 | to = TransformProperties(rotationZ = -swingAngle * 0.33f),
46 | easing = ease
47 | ),
48 | Keyframe.Segment(
49 | start = 0.80f,
50 | end = 1f,
51 | from = TransformProperties(rotationZ = -swingAngle * 0.33f),
52 | to = TransformProperties(rotationZ = 0f),
53 | easing = ease
54 | )
55 | )
56 |
57 | @Composable
58 | override fun animate(progress: State): Modifier {
59 | return Modifier.animateKeyframe(
60 | progress = progress,
61 | keyframes = keyframes,
62 | transformOrigin = TransformOrigin(0.5f, 0f)
63 | )
64 | }
65 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/backexists/BackOutUp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.backexists
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.runtime.getValue
7 | import androidx.compose.runtime.mutableStateOf
8 | import androidx.compose.runtime.setValue
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.graphics.TransformOrigin
11 | import com.nomanr.animate.compose.core.AnimationPreset
12 | import com.nomanr.animate.compose.core.Keyframe
13 | import com.nomanr.animate.compose.core.TransformProperties
14 | import com.nomanr.animate.compose.core.animateKeyframe
15 |
16 | class BackOutUp(
17 | private val exitOffsetY: Float = -1200f
18 | ) : AnimationPreset {
19 |
20 | private var translationY by mutableStateOf(exitOffsetY)
21 |
22 | private val keyframes: List
23 | get() = listOf(
24 | Keyframe.Static(
25 | percent = 0f,
26 | transform = TransformProperties(scaleX = 1f, scaleY = 1f, alpha = 1f),
27 | easing = EaseOut
28 | ),
29 | Keyframe.Segment(
30 | start = 0f,
31 | end = 0.2f,
32 | from = TransformProperties(scaleX = 1f, scaleY = 1f, alpha = 1f),
33 | to = TransformProperties(scaleX = 0.7f, scaleY = 0.7f, alpha = 0.7f),
34 | easing = EaseOut
35 | ),
36 | Keyframe.Segment(
37 | start = 0.2f,
38 | end = 1f,
39 | from = TransformProperties(
40 | translationY = 0f,
41 | scaleX = 0.7f,
42 | scaleY = 0.7f,
43 | alpha = 0.7f
44 | ),
45 | to = TransformProperties(
46 | translationY = translationY,
47 | scaleX = 0.7f,
48 | scaleY = 0.7f,
49 | alpha = 0.7f
50 | ),
51 | easing = EaseOut
52 | )
53 | )
54 |
55 | @Composable
56 | override fun animate(progress: State): Modifier {
57 | return Modifier.animateKeyframe(
58 | progress = progress,
59 | keyframes = keyframes,
60 | transformOrigin = TransformOrigin.Center,
61 | clip = false
62 | )
63 | }
64 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/backexists/BackOutLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.backexists
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.runtime.getValue
7 | import androidx.compose.runtime.mutableStateOf
8 | import androidx.compose.runtime.setValue
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.graphics.TransformOrigin
11 | import com.nomanr.animate.compose.core.AnimationPreset
12 | import com.nomanr.animate.compose.core.Keyframe
13 | import com.nomanr.animate.compose.core.TransformProperties
14 | import com.nomanr.animate.compose.core.animateKeyframe
15 |
16 | class BackOutLeft(
17 | private val exitOffsetX: Float = -2000f
18 | ) : AnimationPreset {
19 |
20 | private var translationX by mutableStateOf(exitOffsetX)
21 |
22 | private val keyframes: List
23 | get() = listOf(
24 | Keyframe.Static(
25 | percent = 0f,
26 | transform = TransformProperties(scaleX = 1f, scaleY = 1f, alpha = 1f),
27 | easing = EaseOut
28 | ),
29 | Keyframe.Segment(
30 | start = 0f,
31 | end = 0.2f,
32 | from = TransformProperties(scaleX = 1f, scaleY = 1f, alpha = 1f),
33 | to = TransformProperties(scaleX = 0.7f, scaleY = 0.7f, alpha = 0.7f),
34 | easing = EaseOut
35 | ),
36 | Keyframe.Segment(
37 | start = 0.2f,
38 | end = 1f,
39 | from = TransformProperties(
40 | translationX = 0f,
41 | scaleX = 0.7f,
42 | scaleY = 0.7f,
43 | alpha = 0.7f
44 | ),
45 | to = TransformProperties(
46 | translationX = translationX,
47 | scaleX = 0.7f,
48 | scaleY = 0.7f,
49 | alpha = 0.7f
50 | ),
51 | easing = EaseOut
52 | )
53 | )
54 |
55 | @Composable
56 | override fun animate(progress: State): Modifier {
57 | return Modifier.animateKeyframe(
58 | progress = progress,
59 | keyframes = keyframes,
60 | transformOrigin = TransformOrigin.Center,
61 | clip = false
62 | )
63 | }
64 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/backexists/BackOutRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.backexists
2 |
3 | import androidx.compose.animation.core.EaseOut
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.runtime.getValue
7 | import androidx.compose.runtime.mutableStateOf
8 | import androidx.compose.runtime.setValue
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.graphics.TransformOrigin
11 | import com.nomanr.animate.compose.core.AnimationPreset
12 | import com.nomanr.animate.compose.core.Keyframe
13 | import com.nomanr.animate.compose.core.TransformProperties
14 | import com.nomanr.animate.compose.core.animateKeyframe
15 |
16 | class BackOutRight(
17 | private val exitOffsetX: Float = 2000f
18 | ) : AnimationPreset {
19 |
20 | private var translationX by mutableStateOf(exitOffsetX)
21 |
22 | private val keyframes: List
23 | get() = listOf(
24 | Keyframe.Static(
25 | percent = 0f,
26 | transform = TransformProperties(scaleX = 1f, scaleY = 1f, alpha = 1f),
27 | easing = EaseOut
28 | ),
29 | Keyframe.Segment(
30 | start = 0f,
31 | end = 0.2f,
32 | from = TransformProperties(scaleX = 1f, scaleY = 1f, alpha = 1f),
33 | to = TransformProperties(scaleX = 0.7f, scaleY = 0.7f, alpha = 0.7f),
34 | easing = EaseOut
35 | ),
36 | Keyframe.Segment(
37 | start = 0.2f,
38 | end = 1f,
39 | from = TransformProperties(
40 | translationX = 0f,
41 | scaleX = 0.7f,
42 | scaleY = 0.7f,
43 | alpha = 0.7f
44 | ),
45 | to = TransformProperties(
46 | translationX = translationX,
47 | scaleX = 0.7f,
48 | scaleY = 0.7f,
49 | alpha = 0.7f
50 | ),
51 | easing = EaseOut
52 | )
53 | )
54 |
55 | @Composable
56 | override fun animate(progress: State): Modifier {
57 | return Modifier.animateKeyframe(
58 | progress = progress,
59 | keyframes = keyframes,
60 | transformOrigin = TransformOrigin.Center,
61 | clip = false
62 | )
63 | }
64 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/attentionseekers/HeadShake.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.attentionseekers
2 |
3 | import androidx.compose.animation.core.EaseInOut
4 | import androidx.compose.animation.core.EaseOut
5 | import androidx.compose.runtime.Composable
6 | import androidx.compose.runtime.State
7 | import androidx.compose.ui.Modifier
8 | import com.nomanr.animate.compose.core.AnimationPreset
9 | import com.nomanr.animate.compose.core.Keyframe
10 | import com.nomanr.animate.compose.core.TransformProperties
11 | import com.nomanr.animate.compose.core.animateKeyframe
12 |
13 | class HeadShake(shakeOffset: Float = 1f) : AnimationPreset {
14 |
15 | private val keyframes = listOf(
16 | Keyframe.Segment(
17 | start = 0f,
18 | end = 0.065f,
19 | from = TransformProperties(translationX = 0f, scaleX = 1f),
20 | to = TransformProperties(translationX = -12f * shakeOffset, scaleX = 0.98f),
21 | easing = EaseInOut
22 | ),
23 | Keyframe.Segment(
24 | start = 0.065f,
25 | end = 0.185f,
26 | from = TransformProperties(translationX = -12f * shakeOffset, scaleX = 0.98f),
27 | to = TransformProperties(translationX = 10f * shakeOffset, scaleX = 1f),
28 | easing = EaseInOut
29 | ),
30 | Keyframe.Segment(
31 | start = 0.185f,
32 | end = 0.315f,
33 | from = TransformProperties(translationX = 10f * shakeOffset, scaleX = 1f),
34 | to = TransformProperties(translationX = -6f * shakeOffset, scaleX = 1f),
35 | easing = EaseInOut
36 | ),
37 | Keyframe.Segment(
38 | start = 0.315f,
39 | end = 0.435f,
40 | from = TransformProperties(translationX = -6f * shakeOffset, scaleX = 1f),
41 | to = TransformProperties(translationX = 4f * shakeOffset, scaleX = 1f),
42 | easing = EaseOut
43 | ),
44 | Keyframe.Segment(
45 | start = 0.435f,
46 | end = 0.5f,
47 | from = TransformProperties(translationX = 4f * shakeOffset, scaleX = 1f),
48 | to = TransformProperties(translationX = 0f, scaleX = 1f),
49 | easing = EaseOut
50 | )
51 | )
52 |
53 | @Composable
54 | override fun animate(progress: State): Modifier {
55 | return Modifier.animateKeyframe(
56 | progress = progress,
57 | keyframes = keyframes
58 | )
59 | }
60 | }
--------------------------------------------------------------------------------
/sample/app/common/src/commonMain/kotlin/com/nomanr/animate/compose/sample/components/AnimatedDemo.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.sample.components
2 |
3 | import androidx.compose.foundation.layout.Arrangement
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.foundation.layout.padding
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.runtime.LaunchedEffect
9 | import androidx.compose.runtime.getValue
10 | import androidx.compose.runtime.mutableStateOf
11 | import androidx.compose.runtime.remember
12 | import androidx.compose.runtime.setValue
13 | import androidx.compose.ui.Alignment
14 | import androidx.compose.ui.Modifier
15 | import androidx.compose.ui.draw.clipToBounds
16 | import androidx.compose.ui.graphics.Color
17 | import androidx.compose.ui.text.font.FontWeight
18 | import androidx.compose.ui.unit.dp
19 | import androidx.compose.ui.unit.sp
20 | import com.nomanr.animate.compose.animated.Animated
21 | import com.nomanr.animate.compose.animated.rememberAnimatedState
22 | import com.nomanr.animate.compose.data.Animation
23 | import com.nomanr.animate.compose.ui.AppTheme
24 | import com.nomanr.animate.compose.ui.components.Text
25 |
26 | @Composable
27 | fun AnimatedDemo(animation: Animation) {
28 | val animationState = rememberAnimatedState()
29 | var trigger by remember { mutableStateOf(Pair(0, true)) }
30 |
31 | LaunchedEffect(animation) {
32 | trigger = Pair(trigger.first + 1, true)
33 | animationState.animate()
34 | }
35 |
36 | LaunchedEffect(animationState.isAnimationFinished.value) {
37 | if (animationState.isAnimationFinished.value == true) {
38 | trigger = Pair(trigger.first + 1, false)
39 | }
40 | }
41 |
42 | Column(
43 | modifier = Modifier.fillMaxSize().clipToBounds(),
44 | horizontalAlignment = Alignment.CenterHorizontally,
45 | verticalArrangement = Arrangement.Center
46 | ) {
47 | if (trigger.second) {
48 | Animated(
49 | preset = animation.preset,
50 | state = animationState,
51 | ) {
52 | AnimatedContent()
53 | }
54 | } else {
55 | AnimatedContent()
56 | }
57 | }
58 | }
59 |
60 | @Composable
61 | fun AnimatedContent() {
62 | Text(
63 | text = "Animated",
64 | modifier = Modifier.padding(16.dp),
65 | color = Color.Black,
66 | style = AppTheme.typography.h1.copy(fontWeight = FontWeight.Black, fontSize = 50.sp)
67 | )
68 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingentrances/BounceInLeft.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingentrances
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceInEasing
12 |
13 | class BounceInLeft(
14 | private val entranceOffsetX: Float = -3000f
15 | ) : AnimationPreset {
16 |
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Static(
20 | percent = 0f,
21 | transform = TransformProperties(
22 | alpha = 0f,
23 | translationX = entranceOffsetX,
24 | scaleX = 3f
25 | ),
26 | easing = bounceInEasing
27 | ),
28 | Keyframe.Segment(
29 | start = 0f,
30 | end = 0.6f,
31 | from = TransformProperties(translationX = entranceOffsetX, scaleX = 3f),
32 | to = TransformProperties(alpha = 1f, translationX = 25f, scaleX = 1f),
33 | easing = bounceInEasing
34 | ),
35 | Keyframe.Segment(
36 | start = 0.6f,
37 | end = 0.75f,
38 | from = TransformProperties(alpha = 1f, translationX = 25f, scaleX = 1f),
39 | to = TransformProperties(translationX = -10f, scaleX = 0.98f),
40 | easing = bounceInEasing
41 | ),
42 | Keyframe.Segment(
43 | start = 0.75f,
44 | end = 0.9f,
45 | from = TransformProperties(translationX = -10f, scaleX = 0.98f),
46 | to = TransformProperties(translationX = 5f, scaleX = 0.995f),
47 | easing = bounceInEasing
48 | ),
49 | Keyframe.Segment(
50 | start = 0.9f,
51 | end = 1f,
52 | from = TransformProperties(translationX = 5f, scaleX = 0.995f),
53 | to = TransformProperties(translationX = 0f, scaleX = 1f),
54 | easing = bounceInEasing
55 | )
56 | )
57 |
58 | @Composable
59 | override fun animate(progress: State): Modifier {
60 | return Modifier.animateKeyframe(
61 | progress = progress,
62 | keyframes = keyframes,
63 | transformOrigin = TransformOrigin.Center,
64 | clip = false
65 | )
66 | }
67 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingentrances/BounceInRight.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingentrances
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceInEasing
12 |
13 | class BounceInRight(
14 | private val entranceOffsetX: Float = 3000f
15 | ) : AnimationPreset {
16 |
17 | private val keyframes = listOf(
18 | Keyframe.Static(
19 | percent = 0f,
20 | transform = TransformProperties(
21 | alpha = 0f,
22 | translationX = entranceOffsetX,
23 | scaleX = 3f
24 | ),
25 | easing = bounceInEasing
26 | ),
27 | Keyframe.Segment(
28 | start = 0f,
29 | end = 0.6f,
30 | from = TransformProperties(translationX = entranceOffsetX, scaleX = 3f),
31 | to = TransformProperties(alpha = 1f, translationX = -25f, scaleX = 1f),
32 | easing = bounceInEasing
33 | ),
34 | Keyframe.Segment(
35 | start = 0.6f,
36 | end = 0.75f,
37 | from = TransformProperties(alpha = 1f, translationX = -25f, scaleX = 1f),
38 | to = TransformProperties(translationX = 10f, scaleX = 0.98f),
39 | easing = bounceInEasing
40 | ),
41 | Keyframe.Segment(
42 | start = 0.75f,
43 | end = 0.9f,
44 | from = TransformProperties(translationX = 10f, scaleX = 0.98f),
45 | to = TransformProperties(translationX = -5f, scaleX = 0.995f),
46 | easing = bounceInEasing
47 | ),
48 | Keyframe.Segment(
49 | start = 0.9f,
50 | end = 1f,
51 | from = TransformProperties(translationX = -5f, scaleX = 0.995f),
52 | to = TransformProperties(translationX = 0f, scaleX = 1f),
53 | easing = bounceInEasing
54 | )
55 | )
56 |
57 | @Composable
58 | override fun animate(progress: State): Modifier {
59 | return Modifier.animateKeyframe(
60 | progress = progress,
61 | keyframes = keyframes,
62 | transformOrigin = TransformOrigin.Center,
63 | clip = false
64 | )
65 | }
66 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingentrances/BounceInDown.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingentrances
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceInEasing
12 |
13 |
14 | class BounceInDown(
15 | private val entranceOffsetY: Float = -3000f
16 | ) : AnimationPreset {
17 |
18 | private val keyframes = listOf(
19 | Keyframe.Static(
20 | percent = 0f,
21 | transform = TransformProperties(
22 | alpha = 0f,
23 | translationY = entranceOffsetY,
24 | scaleY = 3f
25 | ),
26 | easing = bounceInEasing
27 | ),
28 | Keyframe.Segment(
29 | start = 0f,
30 | end = 0.6f,
31 | from = TransformProperties(translationY = entranceOffsetY, scaleY = 3f),
32 | to = TransformProperties(alpha = 1f, translationY = 25f, scaleY = 0.9f),
33 | easing = bounceInEasing
34 | ),
35 | Keyframe.Segment(
36 | start = 0.6f,
37 | end = 0.75f,
38 | from = TransformProperties(alpha = 1f, translationY = 25f, scaleY = 0.9f),
39 | to = TransformProperties(translationY = -10f, scaleY = 0.95f),
40 | easing = bounceInEasing
41 | ),
42 | Keyframe.Segment(
43 | start = 0.75f,
44 | end = 0.9f,
45 | from = TransformProperties(translationY = -10f, scaleY = 0.95f),
46 | to = TransformProperties(translationY = 5f, scaleY = 0.985f),
47 | easing = bounceInEasing
48 | ),
49 | Keyframe.Segment(
50 | start = 0.9f,
51 | end = 1f,
52 | from = TransformProperties(translationY = 5f, scaleY = 0.985f),
53 | to = TransformProperties(translationY = 0f, scaleY = 1f),
54 | easing = bounceInEasing
55 | )
56 | )
57 |
58 | @Composable
59 | override fun animate(progress: State): Modifier {
60 | return Modifier.animateKeyframe(
61 | progress = progress,
62 | keyframes = keyframes,
63 | transformOrigin = TransformOrigin.Center,
64 | clip = false
65 | )
66 | }
67 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingentrances/BounceInUp.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingentrances
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceInEasing
12 |
13 | class BounceInUp(
14 | private val entranceOffsetY: Float = 3000f
15 | ) : AnimationPreset {
16 |
17 | private val keyframes = listOf(
18 | Keyframe.Static(
19 | percent = 0f,
20 | transform = TransformProperties(
21 | alpha = 0f,
22 | translationY = entranceOffsetY,
23 | scaleY = 5f
24 | ),
25 | easing = bounceInEasing
26 | ),
27 | Keyframe.Segment(
28 | start = 0f,
29 | end = 0.6f,
30 | from = TransformProperties(translationY = entranceOffsetY, scaleY = 5f),
31 | to = TransformProperties(alpha = 1f, translationY = -20f, scaleY = 0.9f),
32 | easing = bounceInEasing
33 | ),
34 | Keyframe.Segment(
35 | start = 0.6f,
36 | end = 0.75f,
37 | from = TransformProperties(alpha = 1f, translationY = -20f, scaleY = 0.9f),
38 | to = TransformProperties(translationY = 10f, scaleY = 0.95f),
39 | easing = bounceInEasing
40 | ),
41 | Keyframe.Segment(
42 | start = 0.75f,
43 | end = 0.9f,
44 | from = TransformProperties(translationY = 10f, scaleY = 0.95f),
45 | to = TransformProperties(translationY = -5f, scaleY = 0.985f),
46 | easing = bounceInEasing
47 | ),
48 | Keyframe.Segment(
49 | start = 0.9f,
50 | end = 1f,
51 | from = TransformProperties(translationY = -5f, scaleY = 0.985f),
52 | to = TransformProperties(translationY = 0f, scaleY = 1f),
53 | easing = bounceInEasing
54 | )
55 | )
56 |
57 | @Composable
58 | override fun animate(progress: State): Modifier {
59 | return Modifier.animateKeyframe(
60 | progress = progress,
61 | keyframes = keyframes,
62 | transformOrigin = TransformOrigin.Center,
63 | clip = false
64 | )
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/bouncingentrances/BounceIn.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.bouncingentrances
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.State
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.TransformOrigin
7 | import com.nomanr.animate.compose.core.AnimationPreset
8 | import com.nomanr.animate.compose.core.Keyframe
9 | import com.nomanr.animate.compose.core.TransformProperties
10 | import com.nomanr.animate.compose.core.animateKeyframe
11 | import com.nomanr.animate.compose.presets.common.bounceInEasing
12 |
13 | class BounceIn : AnimationPreset {
14 |
15 | private val keyframes = listOf(
16 | Keyframe.Static(
17 | percent = 0f,
18 | transform = TransformProperties(alpha = 0f, scaleX = 0.3f, scaleY = 0.3f),
19 | easing = bounceInEasing
20 | ),
21 | Keyframe.Segment(
22 | start = 0f,
23 | end = 0.2f,
24 | from = TransformProperties(scaleX = 0.3f, scaleY = 0.3f),
25 | to = TransformProperties(scaleX = 1.1f, scaleY = 1.1f),
26 | easing = bounceInEasing
27 | ),
28 | Keyframe.Segment(
29 | start = 0.2f,
30 | end = 0.4f,
31 | from = TransformProperties(scaleX = 1.1f, scaleY = 1.1f),
32 | to = TransformProperties(scaleX = 0.9f, scaleY = 0.9f),
33 | easing = bounceInEasing
34 | ),
35 | Keyframe.Segment(
36 | start = 0.4f,
37 | end = 0.6f,
38 | from = TransformProperties(scaleX = 0.9f, scaleY = 0.9f),
39 | to = TransformProperties(alpha = 1f, scaleX = 1.03f, scaleY = 1.03f),
40 | easing = bounceInEasing
41 | ),
42 | Keyframe.Segment(
43 | start = 0.6f,
44 | end = 0.8f,
45 | from = TransformProperties(alpha = 1f, scaleX = 1.03f, scaleY = 1.03f),
46 | to = TransformProperties(scaleX = 0.97f, scaleY = 0.97f),
47 | easing = bounceInEasing
48 | ),
49 | Keyframe.Segment(
50 | start = 0.8f,
51 | end = 1f,
52 | from = TransformProperties(scaleX = 0.97f, scaleY = 0.97f),
53 | to = TransformProperties(alpha = 1f, scaleX = 1f, scaleY = 1f),
54 | easing = bounceInEasing
55 | )
56 | )
57 |
58 | @Composable
59 | override fun animate(progress: State): Modifier {
60 | return Modifier.animateKeyframe(
61 | progress = progress,
62 | keyframes = keyframes,
63 | transformOrigin = TransformOrigin.Center,
64 | clip = false
65 | )
66 | }
67 | }
--------------------------------------------------------------------------------
/animate-compose/src/commonMain/kotlin/com/nomanr/animate/compose/presets/flippers/Flip.kt:
--------------------------------------------------------------------------------
1 | package com.nomanr.animate.compose.presets.flippers
2 |
3 | import androidx.compose.animation.core.CubicBezierEasing
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.State
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.platform.LocalDensity
8 | import androidx.compose.ui.unit.Dp
9 | import androidx.compose.ui.unit.dp
10 | import com.nomanr.animate.compose.core.AnimationPreset
11 | import com.nomanr.animate.compose.core.Keyframe
12 | import com.nomanr.animate.compose.core.TransformProperties
13 | import com.nomanr.animate.compose.core.animateKeyframe
14 |
15 | class Flip(
16 | private val cameraDistance: Dp = 5.dp
17 | ) : AnimationPreset {
18 |
19 | private val easeOut = CubicBezierEasing(0f, 0f, 0.58f, 1f)
20 | private val easeIn = CubicBezierEasing(0.42f, 0f, 1f, 1f)
21 |
22 | private val rawKeyframes = listOf(
23 | Keyframe.Segment(
24 | start = 0f, end = 0.4f, from = TransformProperties(
25 | rotationY = 0f,
26 | ), to = TransformProperties(
27 | rotationY = 180f,
28 | ), easing = easeOut
29 | ), Keyframe.Segment(
30 | start = 0.4f, end = 0.5f, from = TransformProperties(
31 | rotationY = 180f,
32 | ), to = TransformProperties(
33 | rotationY = 190f,
34 | ), easing = easeIn
35 | ), Keyframe.Segment(
36 | start = 0.5f, end = 0.8f, from = TransformProperties(
37 | rotationY = 190f,
38 | ), to = TransformProperties(
39 | rotationY = 360f,
40 | ), easing = easeIn
41 | ), Keyframe.Segment(
42 | start = 0.8f, end = 1f, from = TransformProperties(
43 | rotationY = 360f,
44 | ), to = TransformProperties(
45 | rotationY = 360f,
46 | ), easing = easeIn
47 | )
48 | )
49 |
50 | @Composable
51 | override fun animate(progress: State): Modifier {
52 | val density = LocalDensity.current
53 | val cameraDistancePx = with(density) {
54 | cameraDistance.toPx()
55 | }
56 |
57 | val frames = rawKeyframes.map { keyframe ->
58 | keyframe.copy(
59 | from = keyframe.from.copy(
60 | cameraDistance = cameraDistancePx
61 | ), to = keyframe.to.copy(
62 | cameraDistance = cameraDistancePx
63 | )
64 | )
65 | }
66 |
67 | return Modifier.animateKeyframe(
68 | progress = progress, keyframes = frames
69 | )
70 | }
71 | }
--------------------------------------------------------------------------------