├── app ├── .gitignore ├── 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-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ │ └── dev │ │ │ │ └── omkartenkale │ │ │ │ └── composeanimationshowcase │ │ │ │ ├── ui │ │ │ │ └── theme │ │ │ │ │ ├── Color.kt │ │ │ │ │ ├── Shape.kt │ │ │ │ │ ├── Type.kt │ │ │ │ │ └── Theme.kt │ │ │ │ ├── samples │ │ │ │ └── android14logo │ │ │ │ │ ├── Util.kt │ │ │ │ │ ├── Android14LogoAnimation.kt │ │ │ │ │ ├── AndroidHead.kt │ │ │ │ │ ├── SpaceBackground.kt │ │ │ │ │ ├── Rocket.kt │ │ │ │ │ └── OrangeRibbon.kt │ │ │ │ └── MainActivity.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── dev │ │ │ └── omkartenkale │ │ │ └── composeanimationshowcase │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── dev │ │ └── omkartenkale │ │ └── composeanimationshowcase │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── .idea ├── .gitignore ├── compiler.xml ├── vcs.xml ├── misc.xml ├── deploymentTargetDropDown.xml └── gradle.xml ├── .gitattributes ├── art └── Android14LogoAnimation.webp ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle ├── README.md ├── LICENSE ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ComposeAnimationShowcase 3 | -------------------------------------------------------------------------------- /art/Android14LogoAnimation.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/art/Android14LogoAnimation.webp -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Feb 11 09:31:55 IST 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.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 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple200 = Color(0xFFBB86FC) 6 | val Purple500 = Color(0xFF6200EE) 7 | val Purple700 = Color(0xFF3700B3) 8 | val Teal200 = Color(0xFF03DAC5) -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | google() 5 | mavenCentral() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | rootProject.name = "ComposeAnimationShowcase" 16 | include ':app' 17 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/ui/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.ui.theme 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material.Shapes 5 | import androidx.compose.ui.unit.dp 6 | 7 | val Shapes = Shapes( 8 | small = RoundedCornerShape(4.dp), 9 | medium = RoundedCornerShape(4.dp), 10 | large = RoundedCornerShape(0.dp) 11 | ) -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | -------------------------------------------------------------------------------- /app/src/test/java/dev/omkartenkale/composeanimationshowcase/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/res/xml/backup_rules.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/samples/android14logo/Util.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.samples.android14logo 2 | 3 | 4 | typealias UnitProgress = Float 5 | 6 | fun UnitProgress.mapInRange(start: UnitProgress, end: UnitProgress): UnitProgress { 7 | if (this < start) { 8 | return 0f 9 | } 10 | if (this > end) { 11 | return 1f 12 | } 13 | val value = this 14 | val outMin = 0f 15 | val outMax = 1f 16 | return outMin + (((value - start) / (end - start)) * (outMax - outMin)) 17 | } 18 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Jetpack Compose Animation Showcase 2 | Some cool animations I wrote while learning compose 3 | 4 | ### 1. Android 14 Logo Animation 5 | ![Android 14 Logo Animation](https://raw.githubusercontent.com/omkar-tenkale/JetpackComposeAnimationShowcase/master/art/Android14LogoAnimation.webp) 6 | - [Tweet by @davey_burke ](https://twitter.com/davey_burke/status/1623401847623909376) 7 | 8 | 9 | ### Discuss 💬 10 | 11 | Have any questions, doubts or want to present your opinions, views? You're always welcome. You can [start a discussion](https://github.com/omkar-tenkale/JetpackComposeAnimationShowcase/discussions) 12 | -------------------------------------------------------------------------------- /app/src/main/res/xml/data_extraction_rules.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /app/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 -------------------------------------------------------------------------------- /app/src/androidTest/java/dev/omkartenkale/composeanimationshowcase/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("dev.omkartenkale.composeanimationshowcase", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.foundation.layout.Box 7 | import androidx.compose.foundation.layout.fillMaxSize 8 | import androidx.compose.ui.Alignment 9 | import androidx.compose.ui.Modifier 10 | import dev.omkartenkale.composeanimationshowcase.samples.android14logo.Android14LogoAnimation 11 | 12 | class MainActivity : ComponentActivity() { 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContent { 16 | Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { 17 | Android14LogoAnimation() 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.ui.theme 2 | 3 | import androidx.compose.material.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | // Set of Material typography styles to start with 10 | val Typography = Typography( 11 | body1 = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp 15 | ) 16 | /* Other default text styles to override 17 | button = TextStyle( 18 | fontFamily = FontFamily.Default, 19 | fontWeight = FontWeight.W500, 20 | fontSize = 14.sp 21 | ), 22 | caption = TextStyle( 23 | fontFamily = FontFamily.Default, 24 | fontWeight = FontWeight.Normal, 25 | fontSize = 12.sp 26 | ) 27 | */ 28 | ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.ui.theme 2 | 3 | import androidx.compose.foundation.isSystemInDarkTheme 4 | import androidx.compose.material.MaterialTheme 5 | import androidx.compose.material.darkColors 6 | import androidx.compose.material.lightColors 7 | import androidx.compose.runtime.Composable 8 | 9 | private val DarkColorPalette = darkColors( 10 | primary = Purple200, 11 | primaryVariant = Purple700, 12 | secondary = Teal200 13 | ) 14 | 15 | private val LightColorPalette = lightColors( 16 | primary = Purple500, 17 | primaryVariant = Purple700, 18 | secondary = Teal200 19 | 20 | /* Other default colors to override 21 | background = Color.White, 22 | surface = Color.White, 23 | onPrimary = Color.White, 24 | onSecondary = Color.Black, 25 | onBackground = Color.Black, 26 | onSurface = Color.Black, 27 | */ 28 | ) 29 | 30 | @Composable 31 | fun ComposeAnimationShowcaseTheme( 32 | darkTheme: Boolean = isSystemInDarkTheme(), 33 | content: @Composable () -> Unit 34 | ) { 35 | val colors = if (darkTheme) { 36 | DarkColorPalette 37 | } else { 38 | LightColorPalette 39 | } 40 | 41 | MaterialTheme( 42 | colors = colors, 43 | typography = Typography, 44 | shapes = Shapes, 45 | content = content 46 | ) 47 | } -------------------------------------------------------------------------------- /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. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec: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 -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/samples/android14logo/Android14LogoAnimation.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.samples.android14logo 2 | 3 | import androidx.compose.animation.core.Animatable 4 | import androidx.compose.animation.core.FastOutSlowInEasing 5 | import androidx.compose.animation.core.tween 6 | import androidx.compose.foundation.layout.Box 7 | import androidx.compose.foundation.layout.height 8 | import androidx.compose.foundation.layout.width 9 | import androidx.compose.runtime.* 10 | import androidx.compose.ui.Modifier 11 | import androidx.compose.ui.draw.scale 12 | import androidx.compose.ui.tooling.preview.Preview 13 | import androidx.compose.ui.unit.dp 14 | import kotlinx.coroutines.delay 15 | 16 | 17 | @Composable 18 | fun Android14LogoAnimation() { 19 | val logoAnimationProgress = remember { 20 | Animatable(0f) 21 | } 22 | var reverseAnimation by remember { 23 | mutableStateOf(false) 24 | } 25 | LaunchedEffect(Unit) { 26 | delay(2000) 27 | logoAnimationProgress.animateTo( 28 | 1f, animationSpec = tween(2000, easing = FastOutSlowInEasing) 29 | ) 30 | delay(6000) 31 | reverseAnimation = true 32 | logoAnimationProgress.animateTo( 33 | 0f, animationSpec = tween(durationMillis = 1000, easing = FastOutSlowInEasing) 34 | ) 35 | } 36 | Android14AnimatedLogo(logoAnimationProgress.value, reverseAnimation) 37 | } 38 | 39 | @Composable 40 | private fun Android14AnimatedLogo(unitProgress: UnitProgress, reverseAnimation: Boolean) { 41 | Box( 42 | modifier = Modifier 43 | .width(256.dp) 44 | .height(256.dp) 45 | .scale(if (reverseAnimation) unitProgress else unitProgress.mapInRange(0f, 0.25f)) 46 | ) { 47 | SpaceBackground() 48 | AndroidHead(unitProgress) 49 | Rocket(unitProgress) 50 | OrangeRibbon(unitProgress, reverseAnimation) 51 | } 52 | } 53 | 54 | @Preview(showBackground = false) 55 | @Composable 56 | fun Android14VectorAnimationPreview() { 57 | Android14AnimatedLogo(1f, false) 58 | } -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/samples/android14logo/AndroidHead.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.samples.android14logo 2 | 3 | import androidx.compose.foundation.Canvas 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.foundation.shape.CircleShape 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.ui.Modifier 8 | import androidx.compose.ui.draw.clip 9 | import androidx.compose.ui.geometry.Offset 10 | import androidx.compose.ui.geometry.Size 11 | import androidx.compose.ui.graphics.Color 12 | import androidx.compose.ui.graphics.StrokeCap 13 | import androidx.compose.ui.unit.dp 14 | 15 | 16 | @Composable 17 | fun AndroidHead(unitProgress: UnitProgress) { 18 | Canvas( 19 | modifier = Modifier 20 | .fillMaxSize() 21 | .clip(CircleShape) 22 | ) { 23 | drawArc( 24 | color = Color.White, 25 | startAngle = 0f, 26 | sweepAngle = 180f, 27 | useCenter = false, 28 | topLeft = Offset( 29 | 28.dp.toPx(), 30 | (-110).dp.toPx() + 12.dp.toPx() - (110.dp.toPx() - (110.dp.toPx()) * unitProgress.mapInRange( 31 | 0f, 0.5f 32 | )) 33 | ), 34 | size = Size(200.dp.toPx(), 200.dp.toPx()) 35 | ) 36 | val translatePx = 110.dp.toPx() - 110.dp.toPx() * unitProgress.mapInRange(0f, 0.5f) 37 | drawLine( 38 | color = Color.White, 39 | start = Offset(x = 80f.dp.toPx() + translatePx / 2, y = 90f.dp.toPx() - translatePx), 40 | end = Offset(x = 62f.dp.toPx() + translatePx / 2, y = 122.dp.toPx() - translatePx), 41 | strokeWidth = 7.dp.toPx(), 42 | cap = StrokeCap.Round 43 | ) 44 | drawLine( 45 | color = Color.White, 46 | start = Offset(x = 174f.dp.toPx() - translatePx / 2, y = 90f.dp.toPx() - translatePx), 47 | end = Offset(x = 192f.dp.toPx() - translatePx / 2, y = 122.dp.toPx() - translatePx), 48 | strokeWidth = 7.dp.toPx(), 49 | cap = StrokeCap.Round 50 | ) 51 | } 52 | } -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | } 5 | 6 | android { 7 | namespace 'dev.omkartenkale.composeanimationshowcase' 8 | compileSdk 32 9 | 10 | defaultConfig { 11 | applicationId "dev.omkartenkale.composeanimationshowcase" 12 | minSdk 21 13 | targetSdk 32 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | vectorDrawables { 19 | useSupportLibrary true 20 | } 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | kotlinOptions { 34 | jvmTarget = '1.8' 35 | } 36 | buildFeatures { 37 | compose true 38 | } 39 | composeOptions { 40 | kotlinCompilerExtensionVersion '1.1.1' 41 | } 42 | packagingOptions { 43 | resources { 44 | excludes += '/META-INF/{AL2.0,LGPL2.1}' 45 | } 46 | } 47 | } 48 | 49 | dependencies { 50 | 51 | implementation 'androidx.core:core-ktx:1.7.0' 52 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' 53 | implementation 'androidx.activity:activity-compose:1.3.1' 54 | implementation "androidx.compose.ui:ui:$compose_ui_version" 55 | implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version" 56 | implementation 'androidx.compose.material:material:1.1.1' 57 | testImplementation 'junit:junit:4.13.2' 58 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 59 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 60 | androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version" 61 | debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version" 62 | debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version" 63 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/samples/android14logo/SpaceBackground.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.samples.android14logo 2 | 3 | import androidx.compose.animation.core.* 4 | import androidx.compose.foundation.Canvas 5 | import androidx.compose.foundation.layout.fillMaxSize 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.runtime.getValue 8 | import androidx.compose.ui.Modifier 9 | import androidx.compose.ui.geometry.Offset 10 | import androidx.compose.ui.geometry.Size 11 | import androidx.compose.ui.graphics.Color 12 | import androidx.compose.ui.graphics.drawscope.DrawScope 13 | import androidx.compose.ui.unit.dp 14 | 15 | 16 | @Composable 17 | fun randomStarOpacity(): Float { 18 | val infiniteTransition = rememberInfiniteTransition() 19 | val fadeAmount by infiniteTransition.animateFloat( 20 | initialValue = 0f, targetValue = 1f, animationSpec = infiniteRepeatable( 21 | animation = tween( 22 | durationMillis = 2000, easing = FastOutSlowInEasing 23 | ), repeatMode = RepeatMode.Reverse, initialStartOffset = StartOffset((0..4000).random()) 24 | ) 25 | ) 26 | return fadeAmount 27 | } 28 | 29 | @Composable 30 | fun SpaceBackground() { 31 | Canvas(modifier = Modifier.fillMaxSize()) { 32 | drawCircle(Color(0xFF073042)) 33 | } 34 | 35 | val star1Opacity = randomStarOpacity() 36 | val star2Opacity = randomStarOpacity() 37 | val star3Opacity = randomStarOpacity() 38 | val star4Opacity = randomStarOpacity() 39 | val star5Opacity = randomStarOpacity() 40 | val star6Opacity = randomStarOpacity() 41 | val star7Opacity = randomStarOpacity() 42 | val star8Opacity = randomStarOpacity() 43 | val star9Opacity = randomStarOpacity() 44 | val star10Opacity = randomStarOpacity() 45 | val star11Opacity = randomStarOpacity() 46 | val star12Opacity = randomStarOpacity() 47 | val star13Opacity = randomStarOpacity() 48 | val star14Opacity = randomStarOpacity() 49 | 50 | Canvas(modifier = Modifier.fillMaxSize()) { 51 | drawStar(63, 176, 4.5f, star1Opacity) 52 | drawStar(76, 138, 4.5f, star2Opacity) 53 | drawStar(82, 116, 3f, star3Opacity) 54 | drawStar(91, 149, 3f, star4Opacity) 55 | drawStar(91, 162, 3f, star5Opacity) 56 | drawStar(109, 129, 4.5f, star6Opacity) 57 | drawStar(137, 173, 5f, star7Opacity) 58 | drawStar(149, 189, 5f, star8Opacity) 59 | drawStar(144, 136, 3f, star9Opacity) 60 | drawStar(149, 156, 3f, star10Opacity) 61 | drawStar(169, 148, 5f, star11Opacity) 62 | drawStar(163, 118, 2f, star12Opacity) 63 | drawStar(190, 183, 3f, star13Opacity) 64 | drawStar(196, 103, 4.5f, star14Opacity) 65 | } 66 | } 67 | 68 | fun DrawScope.drawStar(xOffset: Int, yOffset: Int, sizeDp: Float, alpha: Float) { 69 | drawRect( 70 | Color.White, 71 | topLeft = Offset(xOffset.dp.toPx(), yOffset.dp.toPx()), 72 | size = Size(sizeDp.dp.toPx(), sizeDp.dp.toPx()), 73 | alpha = alpha 74 | ) 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/samples/android14logo/Rocket.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.samples.android14logo 2 | 3 | import androidx.compose.foundation.Canvas 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.foundation.layout.offset 6 | import androidx.compose.foundation.shape.GenericShape 7 | import androidx.compose.runtime.Composable 8 | import androidx.compose.ui.Modifier 9 | import androidx.compose.ui.draw.clip 10 | import androidx.compose.ui.geometry.Size 11 | import androidx.compose.ui.graphics.* 12 | import androidx.compose.ui.graphics.vector.ImageVector 13 | import androidx.compose.ui.graphics.vector.group 14 | import androidx.compose.ui.graphics.vector.path 15 | import androidx.compose.ui.graphics.vector.rememberVectorPainter 16 | import androidx.compose.ui.platform.LocalDensity 17 | import androidx.compose.ui.unit.LayoutDirection 18 | import androidx.compose.ui.unit.dp 19 | 20 | 21 | @Composable 22 | fun Rocket(unitProgress: UnitProgress) { 23 | fun Path.rocketPath(size: Size, unitProgress: UnitProgress, dpToPx20: Float) { 24 | val part1UnitProgress = (unitProgress * 2).coerceIn(0f, 1f) 25 | val part2UnitProgress = (unitProgress - 0.3f).coerceIn(0f, 1f) * 2 26 | moveTo(0f, 0f) 27 | lineTo(0f, (size.height) * part1UnitProgress) 28 | relativeLineTo(size.width / 2 - dpToPx20, 0f) 29 | lineTo(size.width / 2 - dpToPx20, 0f) 30 | addPath(Path().apply { 31 | moveTo(0f, size.height) 32 | lineTo(size.width, size.height) 33 | relativeLineTo(0f, -size.height * part2UnitProgress) 34 | relativeLineTo(-size.width, 0f) 35 | close() 36 | }) 37 | close() 38 | } 39 | 40 | val vector = ImageVector.Builder( 41 | defaultWidth = 256.dp, defaultHeight = 256.dp, viewportWidth = 512f, viewportHeight = 512f 42 | ).apply { 43 | group { 44 | //Rocket Head 45 | path( 46 | fill = SolidColor(Color(0xFF3ddc84)), 47 | strokeLineCap = StrokeCap.Butt, 48 | strokeLineJoin = StrokeJoin.Miter, 49 | strokeLineMiter = 4.0f, 50 | pathFillType = PathFillType.NonZero 51 | ) { 52 | moveToRelative(256.22f, 126.56f) 53 | curveToRelative(-6.69f, 0.0f, -12.12f, 5.27f, -12.12f, 11.77f) 54 | verticalLineToRelative(14.519f) 55 | curveToRelative(0.0f, 1.25f, 1.01f, 2.27f, 2.27f, 2.27f) 56 | horizontalLineToRelative(0.0f) 57 | curveToRelative(1.25f, 0.0f, 2.27f, -1.01f, 2.27f, -2.27f) 58 | verticalLineToRelative(-3.914f) 59 | curveToRelative(0.0f, -2.51f, 2.03f, -4.54f, 4.54f, -4.54f) 60 | horizontalLineToRelative(6.06f) 61 | curveToRelative(2.51f, 0.0f, 4.54f, 2.03f, 4.54f, 4.54f) 62 | verticalLineToRelative(3.914f) 63 | curveToRelative(0.0f, 1.25f, 1.01f, 2.27f, 2.27f, 2.27f) 64 | reflectiveCurveToRelative(2.27f, -1.01f, 2.27f, -2.27f) 65 | verticalLineToRelative(-14.51f) 66 | curveToRelative(0.0f, -6.50f, -5.42f, -11.77f, -12.12f, -11.77f) 67 | close() 68 | } 69 | //Rocket path 1 70 | path( 71 | fill = SolidColor(Color(0xFF3ddc84)), 72 | strokeLineCap = StrokeCap.Butt, 73 | strokeLineJoin = StrokeJoin.Miter, 74 | strokeLineMiter = 4.0f, 75 | pathFillType = PathFillType.NonZero 76 | ) { 77 | moveTo(250.11f, 170.28f) 78 | lineTo(262.32f, 170.28f) 79 | arcTo(1.97f, 1.97f, 0.0f, false, true, 264.3f, 172.26f) 80 | lineTo(264.3f, 176.39f) 81 | arcTo(1.97f, 1.97f, 0.0f, false, true, 262.32f, 178.36f) 82 | lineTo(250.11f, 178.36f) 83 | arcTo(1.97f, 1.97f, 0.0f, false, true, 248.14f, 176.39f) 84 | lineTo(248.14f, 172.26f) 85 | arcTo(1.97f, 1.97f, 0.0f, false, true, 250.11f, 170.28f) 86 | close() 87 | } 88 | //Rocket path 2 89 | path( 90 | fill = SolidColor(Color(0xFF3ddc84)), 91 | strokeLineCap = StrokeCap.Butt, 92 | strokeLineJoin = StrokeJoin.Miter, 93 | strokeLineMiter = 4.0f, 94 | pathFillType = PathFillType.NonZero 95 | ) { 96 | moveTo(250.26f, 187.65f) 97 | lineTo(262.17f, 187.65f) 98 | arcTo(2.12f, 2.12f, 0.0f, false, true, 264.3f, 189.78f) 99 | lineTo(264.3f, 217.85f) 100 | arcTo(2.12f, 2.12f, 0.0f, false, true, 262.17f, 219.97f) 101 | lineTo(250.26f, 219.97f) 102 | arcTo(2.12f, 2.12f, 0.0f, false, true, 248.14f, 217.85f) 103 | lineTo(248.14f, 189.78f) 104 | arcTo(2.12f, 2.12f, 0.0f, false, true, 250.26f, 187.65f) 105 | close() 106 | } 107 | //Rocket tail 108 | path( 109 | fill = SolidColor(Color(0xFF3ddc84)), 110 | strokeLineCap = StrokeCap.Butt, 111 | strokeLineJoin = StrokeJoin.Miter, 112 | strokeLineMiter = 4.0f, 113 | pathFillType = PathFillType.NonZero 114 | ) { 115 | moveToRelative(195.27f, 187.64f) 116 | lineToRelative(2.25f, -6.68f) 117 | curveToRelative(13.91f, 78.12f, 50.84f, 284.38f, 50.84f, 50.33f) 118 | curveToRelative(0.0f, -0.97f, 0.72f, -1.81f, 1.61f, -1.81f) 119 | horizontalLineToRelative(12.69f) 120 | curveToRelative(0.89f, 0.0f, 1.62f, 0.82f, 1.62f, 1.80f) 121 | curveToRelative(-0.20f, 409.90f, -69.03f, -43.63f, -69.03f, -43.63f) 122 | close() 123 | } 124 | } 125 | }.build() 126 | val painter = rememberVectorPainter(image = vector) 127 | val dpToPx20 = with(LocalDensity.current) { 8.dp.toPx() } 128 | Canvas( 129 | modifier = Modifier 130 | .fillMaxSize() 131 | .offset(y = 6.dp) 132 | .clip(GenericShape { size: Size, _: LayoutDirection -> 133 | rocketPath(size, unitProgress.mapInRange(0.2f, 1f), dpToPx20) 134 | }) 135 | ) { 136 | with(painter) { 137 | draw(intrinsicSize) 138 | } 139 | } 140 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /app/src/main/java/dev/omkartenkale/composeanimationshowcase/samples/android14logo/OrangeRibbon.kt: -------------------------------------------------------------------------------- 1 | package dev.omkartenkale.composeanimationshowcase.samples.android14logo 2 | 3 | import android.graphics.RectF 4 | import android.graphics.Typeface 5 | import androidx.compose.foundation.Canvas 6 | import androidx.compose.foundation.layout.fillMaxSize 7 | import androidx.compose.runtime.Composable 8 | import androidx.compose.ui.Modifier 9 | import androidx.compose.ui.draw.alpha 10 | import androidx.compose.ui.draw.rotate 11 | import androidx.compose.ui.draw.scale 12 | import androidx.compose.ui.graphics.* 13 | import androidx.compose.ui.graphics.drawscope.DrawScope 14 | import androidx.compose.ui.graphics.drawscope.Stroke 15 | import androidx.compose.ui.graphics.drawscope.drawIntoCanvas 16 | import androidx.compose.ui.graphics.vector.ImageVector 17 | import androidx.compose.ui.graphics.vector.group 18 | import androidx.compose.ui.graphics.vector.path 19 | import androidx.compose.ui.graphics.vector.rememberVectorPainter 20 | import android.graphics.Paint as AndroidPaint 21 | import android.graphics.Path as AndroidPath 22 | import androidx.compose.ui.unit.Dp 23 | import androidx.compose.ui.unit.dp 24 | 25 | @Composable 26 | fun OrangeRibbon(unitProgress: UnitProgress, reverseAnimation: Boolean) { 27 | Canvas(modifier = Modifier.fillMaxSize()) { 28 | drawCircle( 29 | color = Color(0xFFf86734), 30 | radius = size.width / 2 - (16.dp.toPx() * unitProgress.mapInRange(0f, 0.25f)), 31 | style = Stroke(width = 32.dp.toPx() * unitProgress.mapInRange(0f, 0.25f)) 32 | ) 33 | } 34 | 35 | val vector = ImageVector.Builder( 36 | defaultWidth = 256.dp, defaultHeight = 256.dp, viewportWidth = 512f, viewportHeight = 512f 37 | ).apply { 38 | //Text 'ANDROID 14' 39 | group { 40 | path( 41 | fill = SolidColor(Color.White), 42 | strokeLineCap = StrokeCap.Butt, 43 | strokeLineJoin = StrokeJoin.Miter, 44 | strokeLineMiter = 4.0f, 45 | pathFillType = PathFillType.NonZero 46 | ) { 47 | moveToRelative(93.33f, 116.36f) 48 | lineToRelative(3.84f, -4.36f) 49 | lineToRelative(29.63f, 9.75f) 50 | lineToRelative(-4.43f, 5.03f) 51 | lineToRelative(-6.22f, -2.09f) 52 | lineToRelative(-7.85f, 8.90f) 53 | lineToRelative(2.86f, 5.91f) 54 | lineToRelative(-4.43f, 5.03f) 55 | lineToRelative(-13.39f, -28.18f) 56 | close() 57 | moveTo(110.42f, 122.75f) 58 | lineToRelative(-8.86f, -3.02f) 59 | lineToRelative(4.10f, 8.41f) 60 | lineToRelative(4.75f, -5.39f) 61 | close() 62 | } 63 | path( 64 | fill = SolidColor(Color.White), 65 | strokeLineCap = StrokeCap.Butt, 66 | strokeLineJoin = StrokeJoin.Miter, 67 | strokeLineMiter = 4.0f, 68 | pathFillType = PathFillType.NonZero 69 | ) { 70 | moveToRelative(153.62f, 100.85f) 71 | lineToRelative(-21.71f, -6.20f) 72 | lineToRelative(10.37f, 14.38f) 73 | lineToRelative(-5.20f, 3.75f) 74 | lineToRelative(-16.78f, -23.26f) 75 | lineToRelative(4.48f, -3.23f) 76 | lineToRelative(21.65f, 6.19f) 77 | lineToRelative(-10.35f, -14.34f) 78 | lineToRelative(5.24f, -3.78f) 79 | lineToRelative(16.78f, 23.26f) 80 | lineToRelative(-4.48f, 3.23f) 81 | close() 82 | } 83 | path( 84 | fill = SolidColor(Color.White), 85 | strokeLineCap = StrokeCap.Butt, 86 | strokeLineJoin = StrokeJoin.Miter, 87 | strokeLineMiter = 4.0f, 88 | pathFillType = PathFillType.NonZero 89 | ) { 90 | moveToRelative(161.46f, 63.14f) 91 | lineToRelative(8.99f, -3.84f) 92 | curveToRelative(7.43f, -3.17f, 15.96f, 0.12f, 19.09f, 7.43f) 93 | curveToRelative(3.12f, 7.31f, -0.38f, 15.76f, -7.81f, 18.94f) 94 | lineToRelative(-8.99f, 3.84f) 95 | lineToRelative(-11.27f, -26.38f) 96 | close() 97 | moveTo(179.41f, 80.25f) 98 | curveToRelative(4.45f, -1.90f, 5.95f, -6.72f, 4.14f, -10.95f) 99 | curveToRelative(-1.81f, -4.23f, -6.32f, -6.47f, -10.78f, -4.57f) 100 | lineToRelative(-3.08f, 1.31f) 101 | lineToRelative(6.64f, 15.53f) 102 | lineToRelative(3.08f, -1.31f) 103 | close() 104 | } 105 | path( 106 | fill = SolidColor(Color.White), 107 | strokeLineCap = StrokeCap.Butt, 108 | strokeLineJoin = StrokeJoin.Miter, 109 | strokeLineMiter = 4.0f, 110 | pathFillType = PathFillType.NonZero 111 | ) { 112 | moveToRelative(204.22f, 47.57f) 113 | lineToRelative(11.09f, -2.19f) 114 | curveToRelative(5.31f, -1.05f, 9.47f, 2.07f, 10.39f, 6.75f) 115 | curveToRelative(0.72f, 3.64f, -0.75f, 6.36f, -4.07f, 8.34f) 116 | lineToRelative(12.40f, 10.43f) 117 | lineToRelative(-7.56f, 1.49f) 118 | lineToRelative(-11.65f, -9.76f) 119 | lineToRelative(-1.03f, 0.20f) 120 | lineToRelative(2.29f, 11.61f) 121 | lineToRelative(-6.30f, 1.24f) 122 | lineToRelative(-5.56f, -28.13f) 123 | close() 124 | moveTo(216.78f, 56.7f) 125 | curveToRelative(1.86f, -0.36f, 2.99f, -1.70f, 2.67f, -3.33f) 126 | curveToRelative(-0.33f, -1.70f, -1.88f, -2.42f, -3.74f, -2.06f) 127 | lineToRelative(-4.04f, 0.80f) 128 | lineToRelative(1.06f, 5.38f) 129 | lineToRelative(4.04f, -0.8f) 130 | close() 131 | } 132 | path( 133 | fill = SolidColor(Color.White), 134 | strokeLineCap = StrokeCap.Butt, 135 | strokeLineJoin = StrokeJoin.Miter, 136 | strokeLineMiter = 4.0f, 137 | pathFillType = PathFillType.NonZero 138 | ) { 139 | moveToRelative(244.29f, 55.6f) 140 | curveToRelative(0.13f, -8.15f, 6.86f, -14.71f, 15.06f, -14.58f) 141 | curveToRelative(8.15f, 0.13f, 14.71f, 6.90f, 14.58f, 15.06f) 142 | reflectiveCurveToRelative(-6.90f, 14.71f, -15.06f, 14.58f) 143 | curveToRelative(-8.19f, -0.13f, -14.71f, -6.90f, -14.58f, -15.06f) 144 | close() 145 | moveTo(267.43f, 55.97f) 146 | curveToRelative(0.07f, -4.64f, -3.53f, -8.66f, -8.18f, -8.73f) 147 | curveToRelative(-4.68f, -0.07f, -8.42f, 3.82f, -8.5f, 8.46f) 148 | curveToRelative(-0.07f, 4.64f, 3.53f, 8.66f, 8.22f, 8.73f) 149 | curveToRelative(4.64f, 0.07f, 8.38f, -3.82f, 8.46f, -8.46f) 150 | close() 151 | } 152 | path( 153 | fill = SolidColor(Color.White), 154 | strokeLineCap = StrokeCap.Butt, 155 | strokeLineJoin = StrokeJoin.Miter, 156 | strokeLineMiter = 4.0f, 157 | pathFillType = PathFillType.NonZero 158 | ) { 159 | moveToRelative(294.38f, 44.83f) 160 | lineToRelative(6.30f, 1.23f) 161 | lineToRelative(-5.49f, 28.15f) 162 | lineToRelative(-6.30f, -1.23f) 163 | lineToRelative(5.49f, -28.15f) 164 | close() 165 | } 166 | path( 167 | fill = SolidColor(Color.White), 168 | strokeLineCap = StrokeCap.Butt, 169 | strokeLineJoin = StrokeJoin.Miter, 170 | strokeLineMiter = 4.0f, 171 | pathFillType = PathFillType.NonZero 172 | ) { 173 | moveToRelative(321.93f, 51.41f) 174 | lineToRelative(9.13f, 3.48f) 175 | curveToRelative(7.55f, 2.87f, 11.39f, 11.17f, 8.55f, 18.61f) 176 | curveToRelative(-2.83f, 7.43f, -11.22f, 11.07f, -18.77f, 8.19f) 177 | lineToRelative(-9.13f, -3.48f) 178 | lineToRelative(10.21f, -26.80f) 179 | close() 180 | moveTo(322.95f, 76.18f) 181 | curveToRelative(4.53f, 1.72f, 8.95f, -0.69f, 10.59f, -4.99f) 182 | curveToRelative(1.64f, -4.30f, -0.05f, -9.05f, -4.58f, -10.78f) 183 | lineToRelative(-3.13f, -1.19f) 184 | lineToRelative(-6.01f, 15.77f) 185 | lineToRelative(3.13f, 1.19f) 186 | close() 187 | } 188 | path( 189 | fill = SolidColor(Color.White), 190 | strokeLineCap = StrokeCap.Butt, 191 | strokeLineJoin = StrokeJoin.Miter, 192 | strokeLineMiter = 4.0f, 193 | pathFillType = PathFillType.NonZero 194 | ) { 195 | moveToRelative(381.40f, 89.23f) 196 | lineToRelative(-4.20f, -3.21f) 197 | lineToRelative(3.65f, -4.78f) 198 | lineToRelative(9.05f, 6.91f) 199 | lineToRelative(-17.39f, 22.80f) 200 | lineToRelative(-4.85f, -3.7f) 201 | lineToRelative(13.74f, -18.01f) 202 | close() 203 | } 204 | path( 205 | fill = SolidColor(Color.White), 206 | strokeLineCap = StrokeCap.Butt, 207 | strokeLineJoin = StrokeJoin.Miter, 208 | strokeLineMiter = 4.0f, 209 | pathFillType = PathFillType.NonZero 210 | ) { 211 | moveToRelative(397.95f, 126.37f) 212 | lineToRelative(-9.55f, -10.25f) 213 | lineToRelative(3.60f, -3.36f) 214 | lineToRelative(22.79f, -1.25f) 215 | lineToRelative(3.74f, 4.02f) 216 | lineToRelative(-12.35f, 11.51f) 217 | lineToRelative(2.50f, 2.68f) 218 | lineToRelative(-4.07f, 3.80f) 219 | lineToRelative(-2.50f, -2.68f) 220 | lineToRelative(-4.55f, 4.24f) 221 | lineToRelative(-4.15f, -4.46f) 222 | lineToRelative(4.55f, -4.24f) 223 | close() 224 | moveTo(407.82f, 117.17f) 225 | lineToRelative(-10.28f, 0.58f) 226 | lineToRelative(4.48f, 4.81f) 227 | lineToRelative(5.79f, -5.39f) 228 | close() 229 | } 230 | } 231 | }.build() 232 | val painter = rememberVectorPainter(image = vector) 233 | Canvas( 234 | modifier = Modifier 235 | .fillMaxSize() 236 | .scale(1.11f) 237 | .alpha(unitProgress.mapInRange(0f, 0.25f)) 238 | .rotate( 239 | (if (reverseAnimation) { 240 | 45 - 45 * unitProgress 241 | } else { 242 | -45 + 45 * unitProgress.mapInRange(0.25f, 1f) 243 | }) 244 | ) 245 | ) { 246 | with(painter) { 247 | draw(intrinsicSize) 248 | } 249 | } 250 | } 251 | 252 | //Legacy method 253 | private fun DrawScope.drawAndroid14Text(canvasSize: Dp) { 254 | drawIntoCanvas { 255 | it.nativeCanvas.apply { 256 | drawTextOnPath( 257 | /* text = */ "ANDROID 14", 258 | /* path = */ AndroidPath().apply { 259 | addArc( 260 | RectF( 261 | 18.dp.toPx(), 262 | 18.dp.toPx(), 263 | canvasSize.toPx() - 18.dp.toPx(), 264 | canvasSize.toPx() - 18.dp.toPx() 265 | ), 180f, 180f 266 | ) 267 | }, 268 | /* hOffset = */ 0f, 269 | /* vOffset = */ 2.dp.toPx(), 270 | /* paint = */ AndroidPaint().apply { 271 | letterSpacing = 0.25f 272 | textSize = 24.dp.toPx() 273 | textAlign = AndroidPaint.Align.CENTER 274 | color = android.graphics.Color.WHITE 275 | typeface = Typeface.DEFAULT_BOLD 276 | } 277 | ) 278 | } 279 | } 280 | } --------------------------------------------------------------------------------