Instantly share code, notes, and snippets.
Last active
June 30, 2024 17:31
-
Star
(22)
22
You must be signed in to star a gist -
Fork
(1)
1
You must be signed in to fork a gist
-
Save c5inco/48921fdcb9874ae1121324569fe343c5 to your computer and use it in GitHub Desktop.
Jetpack Compose port of https://twitter.com/Erwin_AI/status/1627563624691810307
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.compose.animation.core.EaseInOut | |
import androidx.compose.animation.core.animateDpAsState | |
import androidx.compose.animation.core.animateFloatAsState | |
import androidx.compose.animation.core.tween | |
import androidx.compose.desktop.ui.tooling.preview.Preview | |
import androidx.compose.foundation.background | |
import androidx.compose.foundation.border | |
import androidx.compose.foundation.clickable | |
import androidx.compose.foundation.hoverable | |
import androidx.compose.foundation.interaction.MutableInteractionSource | |
import androidx.compose.foundation.interaction.collectIsHoveredAsState | |
import androidx.compose.foundation.layout.* | |
import androidx.compose.foundation.shape.RoundedCornerShape | |
import androidx.compose.material.MaterialTheme | |
import androidx.compose.material.Surface | |
import androidx.compose.material.Text | |
import androidx.compose.material.darkColors | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.getValue | |
import androidx.compose.runtime.remember | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.draw.BlurredEdgeTreatment | |
import androidx.compose.ui.draw.blur | |
import androidx.compose.ui.draw.drawBehind | |
import androidx.compose.ui.geometry.CornerRadius | |
import androidx.compose.ui.graphics.Brush | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.graphics.graphicsLayer | |
import androidx.compose.ui.semantics.Role | |
import androidx.compose.ui.text.font.FontWeight | |
import androidx.compose.ui.unit.dp | |
import androidx.compose.ui.unit.sp | |
import androidx.compose.ui.window.Window | |
import androidx.compose.ui.window.application | |
@Preview | |
@Composable | |
fun App() { | |
MaterialTheme(colors = darkColors()) { | |
Surface( | |
color = Color(0xff111827) | |
) { | |
Box ( | |
Modifier.fillMaxSize(), | |
contentAlignment = Alignment.Center | |
) { | |
GradientShadowButton { | |
Text( | |
text = "Hover me for magic", | |
color = Color.White, | |
fontSize = 16.sp, | |
fontWeight = FontWeight.W500 | |
) | |
} | |
} | |
} | |
} | |
} | |
@Composable | |
fun GradientShadowButton( | |
onClick: () -> Unit = {}, | |
modifier: Modifier = Modifier, | |
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, | |
content: @Composable RowScope.() -> Unit, | |
) { | |
val isButtonHovered by interactionSource.collectIsHoveredAsState() | |
val scaleAnimated by animateFloatAsState( | |
targetValue = if (isButtonHovered) 1f else 0.7f, | |
animationSpec = tween(durationMillis = 1000, easing = EaseInOut) | |
) | |
val alphaAnimated by animateFloatAsState( | |
targetValue = if (isButtonHovered) 0.75f else 0f, | |
animationSpec = tween(durationMillis = 1000, easing = EaseInOut) | |
) | |
val blurAnimated by animateDpAsState( | |
targetValue = if (isButtonHovered) 48.dp else 8.dp, | |
animationSpec = tween(durationMillis = 1000, easing = EaseInOut) | |
) | |
Box ( | |
modifier | |
.hoverable(interactionSource) | |
.width(IntrinsicSize.Max) | |
.height(IntrinsicSize.Max) | |
) { | |
val gradientBrush = Brush.linearGradient( | |
colors = listOf(Color(0xff6171fe), Color(0xff9f6afe), Color(0xffb79dfe)) | |
) | |
Box( | |
Modifier | |
.graphicsLayer { | |
scaleX = scaleAnimated | |
scaleY = scaleAnimated | |
} | |
.blur(radius = blurAnimated, edgeTreatment = BlurredEdgeTreatment.Unbounded) | |
.drawBehind { | |
drawRoundRect( | |
brush = gradientBrush, | |
cornerRadius = CornerRadius(8.dp.toPx()), | |
alpha = alphaAnimated | |
) | |
} | |
.fillMaxSize() | |
) | |
Row( | |
Modifier | |
.padding(16.dp) | |
.clickable( | |
interactionSource = interactionSource, | |
indication = null, | |
role = Role.Button, | |
onClick = onClick | |
) | |
.background(color = Color(0xff18181b), shape = RoundedCornerShape(8.dp)) | |
.border( | |
width = 2.dp, | |
brush = gradientBrush, | |
shape = RoundedCornerShape(8.dp) | |
) | |
.padding(horizontal = 16.dp, vertical = 12.dp), | |
horizontalArrangement = Arrangement.Center | |
) { | |
content() | |
} | |
} | |
} | |
// Compose Desktop entry point for testing | |
fun main() = application { | |
Window( | |
onCloseRequest = ::exitApplication, | |
title = "Gradient Shadow Button" | |
) { | |
App() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment