Interactive Glass Bottom Bar
Add interactive feedbacks for the glass bottom bar
Last updated
Add interactive feedbacks for the glass bottom bar
Last updated
val animationScope = rememberCoroutineScope()
val progressAnimation = remember { Animatable(0f) }
Box(
Modifier
.graphicsLayer {
val progress = progressAnimation.value
val maxScale = (size.width + 16f.dp.toPx()) / size.width
val scale = lerp(1f, maxScale, progress)
scaleX = scale
scaleY = scale
}
.drawBackdrop(
backdrop = backdrop,
shape = { CircleShape },
effects = {
vibrancy()
blur(4f.dp.toPx())
lens(16f.dp.toPx(), 32f.dp.toPx())
},
onDrawSurface = { drawRect(Color.White.copy(alpha = 0.5f)) }
)
.clickable {}
.pointerInput(animationScope) {
val animationSpec = spring(0.5f, 300f, 0.001f)
awaitEachGesture {
// press
awaitFirstDown()
animationScope.launch {
progressAnimation.animateTo(1f, animationSpec)
}
// release
waitForUpOrCancellation()
animationScope.launch {
progressAnimation.animateTo(0f, animationSpec)
}
}
}
.fillMaxHeight()
.weight(1f)
)val animationScope = rememberCoroutineScope()
val progressAnimation = remember { Animatable(0f) }
Box(
Modifier
.drawBackdrop(
backdrop = backdrop,
shape = { CircleShape },
effects = {
vibrancy()
blur(4f.dp.toPx())
lens(16f.dp.toPx(), 32f.dp.toPx())
},
layerBlock = {
val progress = progressAnimation.value
val maxScale = (size.width + 16f.dp.toPx()) / size.width
val scale = lerp(1f, maxScale, progress)
scaleX = scale
scaleY = scale
},
onDrawSurface = { drawRect(Color.White.copy(alpha = 0.5f)) }
)
.clickable(interactionSource = null, indication = null) {}
.pointerInput(animationScope) {
val animationSpec = spring(0.5f, 300f, 0.001f)
awaitEachGesture {
// press
awaitFirstDown()
animationScope.launch {
progressAnimation.animateTo(1f, animationSpec)
}
// release
waitForUpOrCancellation()
animationScope.launch {
progressAnimation.animateTo(0f, animationSpec)
}
}
}
.fillMaxHeight()
.weight(1f)
)Box(Modifier.fillMaxSize()) {
val backgroundColor = Color.White
val backdrop = rememberLayerBackdrop {
drawRect(backgroundColor)
drawContent()
}
MainNavHost(
modifier = Modifier.layerBackdrop(backdrop)
)
Row(
Modifier
.safeContentPadding()
.height(64f.dp)
.fillMaxWidth()
.align(Alignment.BottomCenter),
horizontalArrangement = Arrangement.spacedBy(8f.dp),
verticalAlignment = Alignment.CenterVertically
) {
val animationScope = rememberCoroutineScope()
val progressAnimation = remember { Animatable(0f) }
Box(
Modifier
.drawBackdrop(
backdrop = backdrop,
shape = { CircleShape },
effects = {
vibrancy()
blur(4f.dp.toPx())
lens(16f.dp.toPx(), 32f.dp.toPx())
},
layerBlock = {
val progress = progressAnimation.value
val maxScale = (size.width + 16f.dp.toPx()) / size.width
val scale = lerp(1f, maxScale, progress)
scaleX = scale
scaleY = scale
},
onDrawSurface = { drawRect(Color.White.copy(alpha = 0.5f)) }
)
.clickable(interactionSource = null, indication = null) {}
.pointerInput(animationScope) {
val animationSpec = spring(0.5f, 300f, 0.001f)
awaitEachGesture {
// press
awaitFirstDown()
animationScope.launch {
progressAnimation.animateTo(1f, animationSpec)
}
// release
waitForUpOrCancellation()
animationScope.launch {
progressAnimation.animateTo(0f, animationSpec)
}
}
}
.fillMaxHeight()
.weight(1f)
)
Box(
Modifier
.drawBackdrop(
backdrop = backdrop,
shape = { ContinuousCapsule },
effects = {
vibrancy()
blur(4f.dp.toPx())
lens(16f.dp.toPx(), 32f.dp.toPx())
},
onDrawSurface = {
val tint = Color(0xFF0088FF)
drawRect(tint, blendMode = BlendMode.Hue)
drawRect(tint.copy(alpha = 0.75f))
}
)
.aspectRatio(1f)
)
}
}