Instantly share code, notes, and snippets.
Forked from c5inco/GradientShadowButton.kt
Created
February 22, 2023 08:38
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save dawidhyzy/204336bfb47bec783d6e9fd8e8af8f47 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