Skip to content

Instantly share code, notes, and snippets.

@c5inco
Created February 11, 2022 06:23
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save c5inco/fafee7f0b911185e3c22729a483b6bb5 to your computer and use it in GitHub Desktop.
Save c5inco/fafee7f0b911185e3c22729a483b6bb5 to your computer and use it in GitHub Desktop.
Jetpack Compose implementation of inspirational design https://twitter.com/amos_gyamfi/status/1491506689408909316
package des.c5inco.material3
import androidx.compose.animation.core.*
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun MenuToClose() {
Box(
modifier = Modifier.fillMaxSize().background(Color.Black),
contentAlignment = Alignment.Center
) {
var showMenu by remember { mutableStateOf(true) }
val density = LocalDensity.current
val initialHeight = 58.dp
val endY = with(density) { initialHeight.roundToPx().toFloat() }
val strokeWidth = with(density) { (10.dp).roundToPx().toFloat() }
@Composable
fun springSpec(visibilityThreshold: Float? = null): SpringSpec<Float> =
spring(0.4f, 500f, visibilityThreshold)
val lineOneEndY by animateFloatAsState(
targetValue = if (showMenu) 0f else endY,
animationSpec = springSpec()
)
val lineTwoAlpha by animateFloatAsState(
targetValue = if (showMenu) 1f else 0f,
animationSpec = springSpec(0f)
)
val lineTwoScale by animateFloatAsState(
targetValue = if (showMenu) 1f else 0f,
animationSpec = springSpec()
)
val lineThreeEndY by animateFloatAsState(
targetValue = if (showMenu) endY else 0f,
animationSpec = springSpec()
)
Canvas(
Modifier
.size(height = initialHeight, width = 64.dp)
.pointerInput(Unit) {
detectTapGestures(onTap = { showMenu = !showMenu })
}
) {
val (width, height) = size
fun line(start: Offset, end: Offset, alpha: Float = 1f): Unit {
drawLine(
color = Color.White,
strokeWidth = strokeWidth,
cap = StrokeCap.Round,
start = start,
end = end,
alpha = alpha
)
}
line(
start = Offset(x = 0f, y = 0f),
end = Offset(x = width, y = lineOneEndY)
)
withTransform({
scale(lineTwoScale, Offset(x = 0f, y = height /2))
}) {
line(
start = Offset(x = 0f, y = height / 2),
end = Offset(x = width, y = height / 2),
alpha = lineTwoAlpha
)
}
line(
start = Offset(x = 0f, y = height),
end = Offset(x = width, y = lineThreeEndY)
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment