3D Button

3D Button

Subscribe for Live Previews, in your browser

$3 / month

Code

@Composable
private fun ThreeDButton(
    buttonColor: Color = Color(0xffd736ff),
    radius: Dp = 16.dp,
    content: @Composable RowScope.() -> Unit,
) {
    val interactionSource = remember { MutableInteractionSource() }
    val isHovered by interactionSource.collectIsHoveredAsState()

    var isClicked by remember { mutableStateOf(false) }

    val offset by animateIntAsState(
        targetValue = when {
            isClicked -> 10
            isHovered -> 25
            else -> 20
        }
    )
    Box(
        Modifier
            .graphicsLayer { rotationX = 15f }
            .pointerHoverIcon(PointerIcon.Hand)
            .hoverable(interactionSource)
            .pointerInput(Unit) {
                detectTapGestures(
                    onPress = {
                        isClicked = true
                        awaitRelease()
                        isClicked = false
                    }
                )
            }
            .width(IntrinsicSize.Max)
            .height(IntrinsicSize.Min)
    ) {

        Box(
            Modifier.fillMaxSize()
                .offset { IntOffset(0, offset) }
                .background(
                    Color.Black.copy(alpha = .3f),
                    shape = RoundedCornerShape(radius)
                )
        )

        Box(
            Modifier.fillMaxSize()
                .background(
                    color = buttonColor,
                    shape = RoundedCornerShape(radius)
                )
                .background(
                    brush = Brush.verticalGradient(
                        colors = listOf(
                            Color.Transparent,
                            Color.Black.copy(alpha = .3f),
                        ),
                    ),
                    shape = RoundedCornerShape(radius)
                )
        )

        Box(
            Modifier.fillMaxSize()
                .offset { IntOffset(0, -offset) }
                .background(
                    color = buttonColor,
                    shape = RoundedCornerShape(radius)
                )
                .background(
                    brush = Brush.verticalGradient(
                        colors = listOf(Color.White.copy(alpha = .3f), Color.Transparent)
                    ),
                    shape = RoundedCornerShape(radius)
                )
                .border(
                    width = (1f).dp,
                    brush = Brush.verticalGradient(
                        colors = listOf(
                            Color.White.copy(alpha = .5f),
                            Color.Transparent,
                            Color.Black.copy(alpha = .1f)
                        )
                    ),
                    shape = RoundedCornerShape(radius)
                )
                .padding(horizontal = 32.dp, vertical = 16.dp)
        ) {
            Row(content = content)
        }
    }
}
Mastodon