Skip to content

Instantly share code, notes, and snippets.

@c5inco
Last active May 17, 2023 21:19
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save c5inco/48921fdcb9874ae1121324569fe343c5 to your computer and use it in GitHub Desktop.
Save c5inco/48921fdcb9874ae1121324569fe343c5 to your computer and use it in GitHub Desktop.
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