Skip to content

Instantly share code, notes, and snippets.

@KlassenKonstantin
Created November 14, 2022 21:05
Show Gist options
  • Save KlassenKonstantin/a6390c2cde9558d39fbfb46e2a38c0fe to your computer and use it in GitHub Desktop.
Save KlassenKonstantin/a6390c2cde9558d39fbfb46e2a38c0fe to your computer and use it in GitHub Desktop.
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Slider
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import de.apuri.mirror.ui.theme.MirrorTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MirrorTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
var reflectionGap by remember { mutableStateOf(0.5f) }
var reflectionSize by remember { mutableStateOf(0.0f) }
val provideReflectionGap = { reflectionGap }
val provideReflectionSize = { reflectionSize }
val reflectionEnabled = remember {
derivedStateOf { reflectionSize > 0.2f }
}
val color = animateColorAsState(
if (reflectionEnabled.value) MaterialTheme.colorScheme.primary else LocalContentColor.current,
animationSpec = tween(1000)
)
Column {
Row(
modifier = Modifier
.weight(1f)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text = "Some ",
fontSize = 36.sp
)
WithReflection(
provideReflectionGap,
provideReflectionSize,
) {
Text(
text = "reflected ",
fontSize = 36.sp,
color = color.value
)
}
Text(
text = "text",
fontSize = 36.sp
)
}
LabeledSlider(text = "Gap", provideReflectionGap) { reflectionGap = it }
LabeledSlider(text = "Size", provideReflectionSize) { reflectionSize = it }
Spacer(modifier = Modifier.size(16.dp))
}
}
}
}
}
}
@Composable
fun LabeledSlider(
text: String,
provideValue: () -> Float,
onValueChange: (Float) -> Unit
) {
Row(
modifier = Modifier.padding(horizontal = 32.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier
.padding(end = 16.dp)
.weight(1f),
text = text,
textAlign = TextAlign.End
)
Slider(
modifier = Modifier.weight(4f),
value = provideValue(),
onValueChange = onValueChange
)
}
}
@Composable
fun WithReflection(
provideReflectionGap: () -> Float,
provideReflectionSize: () -> Float,
content: @Composable () -> Unit
) {
val size = remember { mutableStateOf(IntSize.Zero) }
Box(
Modifier
.wrapContentSize()
.onGloballyPositioned { size.value = it.size }
) {
content()
Box(
modifier = Modifier
.graphicsLayer {
alpha = 0.99f
rotationX = 180f
translationY =
size.value.height.toFloat() + (size.value.height.toFloat() * (provideReflectionGap() - 0.5f))
}
.drawWithContent {
drawContent()
drawRect(
brush = Brush.verticalGradient(
1 - provideReflectionSize() to Color.White,
1f to Color.Transparent,
),
blendMode = BlendMode.DstOut
)
}
) {
content()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment