diff --git a/.idea/misc.xml b/.idea/misc.xml index 0fc7958..309a2d3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,11 +5,14 @@ + + + + - diff --git a/app/build.gradle b/app/build.gradle index 0a936d8..e7edea2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -54,6 +54,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.7.0' coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") implementation "com.google.accompanist:accompanist-insets:0.24.2-alpha" + implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0" implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.material:material:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" diff --git a/app/src/main/java/dev/baseio/composeplayground/MainActivity.kt b/app/src/main/java/dev/baseio/composeplayground/MainActivity.kt index 4418d87..8447a86 100644 --- a/app/src/main/java/dev/baseio/composeplayground/MainActivity.kt +++ b/app/src/main/java/dev/baseio/composeplayground/MainActivity.kt @@ -7,19 +7,35 @@ import android.view.View import android.view.WindowManager import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.* +import com.google.accompanist.insets.ProvideWindowInsets import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.HorizontalPager import com.google.accompanist.pager.HorizontalPagerIndicator import com.google.accompanist.pager.rememberPagerState -import dev.baseio.composeplayground.ui.animations.* +import dev.baseio.composeplayground.ui.animations.AndroidMadSkills +import dev.baseio.composeplayground.ui.animations.BellAnimation +import dev.baseio.composeplayground.ui.animations.ChatMessageReactions +import dev.baseio.composeplayground.ui.animations.Github404 +import dev.baseio.composeplayground.ui.animations.GlowingRingLoader +import dev.baseio.composeplayground.ui.animations.IOSSleepSchedule +import dev.baseio.composeplayground.ui.animations.LikeAnimation +import dev.baseio.composeplayground.ui.animations.MenuToClose +import dev.baseio.composeplayground.ui.animations.NetflixIntroAnimation +import dev.baseio.composeplayground.ui.animations.ScalingRotatingLoader +import dev.baseio.composeplayground.ui.animations.ShootingStarsAnimation +import dev.baseio.composeplayground.ui.animations.TwitterSplashAnimation +import dev.baseio.composeplayground.ui.animations.YahooWeatherAndSun +import dev.baseio.composeplayground.ui.animations.copyfile.CopyFile +import dev.baseio.composeplayground.ui.animations.copyfile.CopyFile2 import dev.baseio.composeplayground.ui.animations.planetarysystem.PlanetarySystem import dev.baseio.composeplayground.ui.animations.pulltorefresh.PullToRefreshOne import dev.baseio.composeplayground.ui.theme.ComposePlaygroundTheme @@ -62,7 +78,7 @@ class MainActivity : ComponentActivity() { ) { HorizontalPager( modifier = Modifier.fillMaxSize(), - count = 15, state = pagerState, + count = 17, state = pagerState, ) { page -> // Our page content when (page) { @@ -93,6 +109,16 @@ class MainActivity : ComponentActivity() { 14 -> { ShootingStarsAnimation() } + 15 -> { + Box(modifier = Modifier.fillMaxSize()) { + CopyFile() + } + } + 16 -> { + Box(modifier = Modifier.fillMaxSize()) { + CopyFile2() + } + } 6 -> { NetflixIntroAnimation() } diff --git a/app/src/main/java/dev/baseio/composeplayground/contributors/PushpalRoy.kt b/app/src/main/java/dev/baseio/composeplayground/contributors/PushpalRoy.kt new file mode 100644 index 0000000..e42adf6 --- /dev/null +++ b/app/src/main/java/dev/baseio/composeplayground/contributors/PushpalRoy.kt @@ -0,0 +1,48 @@ +package dev.baseio.composeplayground.contributors + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import dev.baseio.composeplayground.R +import dev.baseio.composeplayground.ui.theme.Typography + +const val pushpalRoyImageUrl = "https://ca.slack-edge.com/T02TLUWLZ-US7QYGQL9-2bba9d14df28-512" + +@Composable +fun PushpalRoy(modifier: Modifier = Modifier) { + Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier.padding(4.dp)) { + CoilImageBox(Modifier.size(64.dp), pushpalRoyImageUrl) + Column(verticalArrangement = Arrangement.Center, modifier = Modifier.padding(8.dp)) { + Text( + modifier = Modifier.padding(bottom = 6.dp), + text = stringResource(id = R.string.emp_mmh0230), + style = Typography.h6.copy(MaterialTheme.colors.onSurface), + ) + Text( + text = stringResource(id = R.string.emp_mmh0230_email), + style = Typography.body2.copy(MaterialTheme.colors.onSurface), + color = Color(0xFFCACACA) + ) + } + } +} + +@Preview("Pushpal Roy Preview") +@Composable +fun PreviewPushpalRoy() { + Surface { + PushpalRoy() + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/baseio/composeplayground/ui/animations/copyfile/CopyFile.kt b/app/src/main/java/dev/baseio/composeplayground/ui/animations/copyfile/CopyFile.kt new file mode 100644 index 0000000..b9d3ab7 --- /dev/null +++ b/app/src/main/java/dev/baseio/composeplayground/ui/animations/copyfile/CopyFile.kt @@ -0,0 +1,334 @@ +package dev.baseio.composeplayground.ui.animations.copyfile + +import androidx.compose.animation.core.FastOutLinearInEasing +import androidx.compose.animation.core.LinearOutSlowInEasing +import androidx.compose.animation.core.RepeatMode.Restart +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.keyframes +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.layoutId +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.constraintlayout.compose.ExperimentalMotionApi +import androidx.constraintlayout.compose.MotionLayout +import androidx.constraintlayout.compose.MotionLayoutDebugFlags +import androidx.constraintlayout.compose.MotionScene +import dev.baseio.composeplayground.R.drawable +import dev.baseio.composeplayground.contributors.PushpalRoy +import dev.baseio.composeplayground.ui.theme.Typography +import java.util.EnumSet + +// Inspiration: https://github.com/amosgyamfi/swiftui-animation-library/blob/master/C/copying_files.gif +@OptIn(ExperimentalMotionApi::class) +@Preview(group = "Copy File") +@Composable +fun CopyFile() { + + val infiniteTransition = rememberInfiniteTransition() + val progressA by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 1f, + animationSpec = infiniteRepeatable( + animation = keyframes { + delayMillis = 100 + durationMillis = 1800 + 0.0f at 0 with LinearOutSlowInEasing + 0.3f at 600 with FastOutLinearInEasing + 1f at 1800 with LinearOutSlowInEasing + }, + repeatMode = Restart + ) + ) + val progressB by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 1f, + animationSpec = infiniteRepeatable( + animation = keyframes { + delayMillis = 500 + durationMillis = 2000 + 0.0f at 0 with LinearOutSlowInEasing + 0.4f at 800 with FastOutLinearInEasing + 1f at 2000 with LinearOutSlowInEasing + }, + repeatMode = Restart + ) + ) + + val progressC by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 1f, + animationSpec = infiniteRepeatable( + animation = keyframes { + delayMillis = 1000 + durationMillis = 2400 + 0.0f at 0 with LinearOutSlowInEasing + 0.5f at 1000 with FastOutLinearInEasing + 1f at 2400 with LinearOutSlowInEasing + }, + repeatMode = Restart + ) + ) + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF322F36)), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + modifier = Modifier.wrapContentHeight(), + text = "Copying files, wait...", + style = Typography.subtitle1.copy(color = Color.White), + ) + Surface( + modifier = Modifier + .wrapContentSize() + .padding(bottom = 150.dp) + ) { + MotionLayout( + modifier = Modifier + .fillMaxWidth() + .height(400.dp) + .background(Color(0xFF322F36)), + motionScene = MotionScene( + """{ + ConstraintSets: { + start: { + a: { + width: 30, + height: 30, + start: ['parent', 'start', 36], + bottom: ['parent', 'bottom', 24] + }, + folder_shared: { + width: 50, + height: 50, + start: ['parent', 'start', 32], + bottom: ['parent', 'bottom', 16] + }, + folder: { + width: 50, + height: 50, + end: ['parent', 'end',32], + bottom: ['parent', 'bottom', 16] + } + }, + end: { + a: { + width: 25, + height: 25, + rotationZ: 165, + end: ['parent', 'end', 36], + bottom: ['parent', 'bottom', 24] + }, + folder_shared: { + width: 50, + height: 50, + start: ['parent', 'start', 32], + bottom: ['parent', 'bottom', 16] + }, + folder: { + width: 50, + height: 50, + end: ['parent', 'end',32], + bottom: ['parent', 'bottom', 16] + } + } + }, + Transitions: { + default: { + from: 'start', + to: 'end', + pathMotionArc: 'a', + KeyFrames: { + KeyPositions: [ + { + target: ['a'], + frames: [5, 50, 95], + percentY: [0.8, 0.5, 0.8], + type: 'parentRelative' + } + ], + KeyCycles: [ + { + target: ['a'], + frames: [0, 50, 100], + period: [0 , 0 , 5], + rotationX: [0, 45, 45], + rotationY: [0, 45, 45], + } + ] + } + } + } + }""" + ), + debug = EnumSet.of(MotionLayoutDebugFlags.NONE), + progress = progressA + ) { + Image( + painter = painterResource(id = drawable.ic_send), + contentDescription = null, + modifier = Modifier.layoutId("a") + ) + Image( + painter = painterResource(id = drawable.ic_folder_shared), + contentDescription = null, + modifier = Modifier.layoutId("folder_shared") + ) + Image( + painter = painterResource(id = drawable.ic_folder), + contentDescription = null, + modifier = Modifier.layoutId("folder") + ) + } + + MotionLayout( + modifier = Modifier + .fillMaxWidth() + .height(400.dp), + motionScene = MotionScene( + """{ + ConstraintSets: { + start: { + b: { + width: 30, + height: 30, + start: ['parent', 'start', 36], + bottom: ['parent', 'bottom', 24] + } + }, + end: { + b: { + width: 25, + height: 25, + rotationZ: 165, + end: ['parent', 'end',36], + bottom: ['parent', 'bottom', 24] + } + } + }, + Transitions: { + default: { + from: 'start', + to: 'end', + pathMotionArc: 'a', + KeyFrames: { + KeyPositions: [ + { + target: ['b'], + frames: [5, 50, 95], + percentY: [0.8, 0.5, 0.8], + type: 'parentRelative' + } + ], + KeyCycles: [ + { + target: ['b'], + frames: [0, 50, 100], + period: [0 , 0 , 5], + rotationX: [0, 45, 45], + rotationY: [0, 45, 45], + } + ] + } + } + } + }""" + ), + debug = EnumSet.of(MotionLayoutDebugFlags.NONE), + progress = progressB + ) { + Image( + painter = painterResource(id = drawable.ic_send), + contentDescription = null, + modifier = Modifier.layoutId("b") + ) + } + + MotionLayout( + modifier = Modifier + .fillMaxWidth() + .height(400.dp), + motionScene = MotionScene( + """{ + ConstraintSets: { + start: { + c: { + width: 30, + height: 30, + start: ['parent', 'start', 36], + bottom: ['parent', 'bottom', 24] + } + }, + end: { + c: { + width: 25, + height: 25, + rotationZ: 165, + end: ['parent', 'end',36], + bottom: ['parent', 'bottom', 24] + } + } + }, + Transitions: { + default: { + from: 'start', + to: 'end', + pathMotionArc: 'a', + KeyFrames: { + KeyPositions: [ + { + target: ['c'], + frames: [5, 50, 95], + percentY: [0.8, 0.5, 0.8], + type: 'parentRelative' + } + ], + KeyCycles: [ + { + target: ['c'], + frames: [0, 50, 100], + period: [0 , 0 , 5], + rotationX: [0, 45, 45], + rotationY: [0, 45, 45], + } + ] + } + } + } + }""" + ), + debug = EnumSet.of(MotionLayoutDebugFlags.NONE), + progress = progressC + ) { + Image( + painter = painterResource(id = drawable.ic_send), + contentDescription = null, + modifier = Modifier.layoutId("c") + ) + } + } + PushpalRoy() + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/baseio/composeplayground/ui/animations/copyfile/CopyFile2.kt b/app/src/main/java/dev/baseio/composeplayground/ui/animations/copyfile/CopyFile2.kt new file mode 100644 index 0000000..3772939 --- /dev/null +++ b/app/src/main/java/dev/baseio/composeplayground/ui/animations/copyfile/CopyFile2.kt @@ -0,0 +1,162 @@ +package dev.baseio.composeplayground.ui.animations.copyfile + +import androidx.compose.animation.core.FastOutLinearInEasing +import androidx.compose.animation.core.RepeatMode.Restart +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.layoutId +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.constraintlayout.compose.ExperimentalMotionApi +import androidx.constraintlayout.compose.MotionLayout +import androidx.constraintlayout.compose.MotionLayoutDebugFlags +import androidx.constraintlayout.compose.MotionScene +import dev.baseio.composeplayground.R.drawable +import dev.baseio.composeplayground.contributors.PushpalRoy +import dev.baseio.composeplayground.ui.theme.Typography +import java.util.EnumSet + +@OptIn(ExperimentalMotionApi::class) +@Preview(group = "Copy File 2") +@Composable +fun CopyFile2() { + + val infiniteTransition = rememberInfiniteTransition() + val progressA by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 1f, + animationSpec = infiniteRepeatable( + animation = tween(delayMillis = 200, durationMillis = 2800, easing = FastOutLinearInEasing), + repeatMode = Restart + ) + ) + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF322F36)), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + modifier = Modifier.wrapContentHeight(), + text = "Copying files, wait...", + style = Typography.subtitle1.copy(color = Color.White), + ) + Surface( + modifier = Modifier + .wrapContentSize() + .padding(bottom = 150.dp) + ) { + MotionLayout( + modifier = Modifier + .fillMaxWidth() + .height(400.dp) + .background(Color(0xFF322F36)), + motionScene = MotionScene( + """{ + ConstraintSets: { + start: { + a: { + width: 40, + height: 40, + start: ['parent', 'start', 36], + bottom: ['parent', 'bottom', 24] + }, + folder_shared: { + width: 50, + height: 50, + start: ['parent', 'start', 32], + bottom: ['parent', 'bottom', 16] + }, + folder: { + width: 50, + height: 50, + end: ['parent', 'end',32], + bottom: ['parent', 'bottom', 16] + } + }, + end: { + a: { + width: 40, + height: 40, + rotationY: 185, + end: ['parent', 'end', 36], + bottom: ['parent', 'bottom', 24] + }, + folder_shared: { + width: 50, + height: 50, + start: ['parent', 'start', 32], + bottom: ['parent', 'bottom', 16] + }, + folder: { + width: 50, + height: 50, + end: ['parent', 'end',32], + bottom: ['parent', 'bottom', 16] + } + } + }, + Transitions: { + default: { + from: 'start', + to: 'end', + pathMotionArc: 'a', + KeyFrames: { + KeyPositions: [ + { + target: ['a'], + frames: [1, 10, 50, 99, 99], + percentY: [0.9, 0.6, 0.6, 0.6, 0.9], + type: 'parentRelative' + } + ] + } + } + } + }""" + ), + debug = EnumSet.of(MotionLayoutDebugFlags.SHOW_ALL), + progress = progressA + ) { + Image( + painter = painterResource(id = drawable.ic_file), + contentDescription = null, + modifier = Modifier.layoutId("a") + ) + Image( + painter = painterResource(id = drawable.ic_folder_shared), + contentDescription = null, + modifier = Modifier.layoutId("folder_shared") + ) + Image( + painter = painterResource(id = drawable.ic_folder), + contentDescription = null, + modifier = Modifier.layoutId("folder") + ) + } + } + PushpalRoy() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_send.png b/app/src/main/res/drawable-hdpi/ic_send.png new file mode 100644 index 0000000..2658e8c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_send.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_send.png b/app/src/main/res/drawable-mdpi/ic_send.png new file mode 100644 index 0000000..e161f2a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_send.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_send.png b/app/src/main/res/drawable-xhdpi/ic_send.png new file mode 100644 index 0000000..5113d38 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_send.png differ diff --git a/app/src/main/res/drawable/ic_file.xml b/app/src/main/res/drawable/ic_file.xml new file mode 100644 index 0000000..eae0bfe --- /dev/null +++ b/app/src/main/res/drawable/ic_file.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_folder.xml b/app/src/main/res/drawable/ic_folder.xml new file mode 100644 index 0000000..0a51188 --- /dev/null +++ b/app/src/main/res/drawable/ic_folder.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_folder_shared.xml b/app/src/main/res/drawable/ic_folder_shared.xml new file mode 100644 index 0000000..07e4f50 --- /dev/null +++ b/app/src/main/res/drawable/ic_folder_shared.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a144b92..0afd057 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,6 +2,8 @@ Compose Playground Anmol Verma anmol.verma@mutualmobile.com\nanmol.verma4@gmail.com + Pushpal Roy + pushpal.roy@mutualmobile.com\npushplaroy2007@gmail.com LOADING \ No newline at end of file