|
val buttonStateProgress = FloatPropKey() |
|
|
|
@Composable |
|
fun NeomorphButton( |
|
modifier: Modifier = Modifier |
|
) { |
|
// [1] |
|
val buttonState = remember { mutableStateOf(ButtonState.IDLE) } |
|
|
|
// [2] |
|
val fromState = if(buttonState.value == ButtonState.IDLE) { |
|
ButtonState.PRESSED |
|
} else { |
|
ButtonState.IDLE |
|
} |
|
|
|
val state = transition( |
|
definition = transitionDefinition { |
|
state(ButtonState.IDLE) { this[buttonStateProgress] = 0f } |
|
state(ButtonState.PRESSED) { this[buttonStateProgress] = 1f } |
|
|
|
// [3] |
|
transition(ButtonState.IDLE to ButtonState.PRESSED, |
|
ButtonState.PRESSED to ButtonState.IDLE) { |
|
buttonStateProgress using tween() |
|
} |
|
}, |
|
|
|
// [4] |
|
initState = fromState, |
|
toState = buttonState.value |
|
) |
|
|
|
|
|
CircleNeomorph( |
|
state = state, |
|
modifier = modifier |
|
|
|
// [5] |
|
.pressIndicatorGestureFilter( |
|
onStart = { buttonState.value = ButtonState.PRESSED }, |
|
onStop = { buttonState.value = ButtonState.IDLE } |
|
) |
|
) |
|
} |
|
|
|
@Composable |
|
fun CircleNeomorph( |
|
state: TransitionState, |
|
modifier: Modifier = Modifier, |
|
) { |
|
// [6] |
|
val bias = (3 - 2f * state[buttonStateProgress]) |
|
|
|
Box(modifier = modifier.size(size = 200.dp)) { |
|
|
|
// [7] |
|
Box(modifier = Modifier.size(120.dp) |
|
.clip(shape = CircleShape) |
|
.background( |
|
brush = RadialGradient( |
|
colors = listOf(NeomorphLightColor, Color.Transparent), |
|
.. |
|
) |
|
) |
|
.align(alignment = BiasAlignment(bias * -0.1f, bias * -0.1f)) |
|
) |
|
|
|
// [8] |
|
Box(modifier = Modifier.size(120.dp) |
|
.clip(shape = CircleShape) |
|
.background( |
|
brush = RadialGradient( |
|
colors = listOf(NeomorphDarkColor, NeomorphDarkColor, Color.Transparent), |
|
.. |
|
) |
|
) |
|
.align(alignment = BiasAlignment(bias * 0.1f, bias * 0.1f)) |
|
) |
|
|
|
// [9] |
|
Box(modifier = Modifier.size(size = 100.dp) |
|
.clip(shape = CircleShape) |
|
.align(alignment = Alignment.Center) |
|
.background(color = NeomorphColor)) |
|
} |
|
} |