- 作者:老汪软件技巧
- 发表时间:2024-08-26 10:03
- 浏览量:
背景
在网上看到几个有意思的卡片动画效果,不过使用css实现的,我现在用compose复刻一下,这篇文章的效果都是卡片相关的,而且使用compose实现的方式和css有些差异,思路不完全一样。本篇文章不提供完整代码,主要提供思路和细节代码。
1.渐变边框卡片
效果实现主要就是一个Brush,然后颜色写成动画,如果将这两个渐变颜色的出现时机修改一下,还可以实现从特定方向出现的效果:
val color1 by animateColorAsState(
if (hover) Color(0, 219, 222) else Color.Transparent,
tween(600) //修改这个地方
)
val color2 by animateColorAsState(
if (hover) Color(252, 0, 255) else Color.Transparent,
tween(1200)
)
Box(
modifier = Modifier
.size(190.dp, 250.dp)
.background(Color.Black, shape)
.hoverable(interactionSource)
.border(
3.dp, Brush.linearGradient(
listOf(
color1, // 重点
color2, // 重点
),
start = Offset.Zero,
end = Offset(300f, 300f)
), shape
)
,
contentAlignment = Alignment.Center
)
2.发光呼吸边框
代码如下:
val shape = remember { RoundedCornerShape(8.dp) }
val interactionSource = remember { MutableInteractionSource() }
val infiniteTransition = rememberInfiniteTransition()
val alpha by infiniteTransition.animateFloat(
1f, 0.3f, infiniteRepeatable(
tween(2000, 0, easing = FastOutLinearInEasing),
repeatMode = RepeatMode.Reverse
)
)
val radius by infiniteTransition.animateFloat(
350f, 100f, infiniteRepeatable(
tween(2000, 0, easing = FastOutLinearInEasing),
repeatMode = RepeatMode.Reverse
)
)
Box(
modifier = Modifier
.size(190.dp, 250.dp)
.background(Color.Black, shape)
.hoverable(interactionSource)
.border(
3.dp, Brush.radialGradient(
listOf(
Color.White.copy(alpha),
Color.DarkGray,
),
center = Offset.Zero,
radius = radius
), shape
),
contentAlignment = Alignment.Center
) {
Icon(
Icons.Outlined.Face,
contentDescription = null,
tint = Color.Cyan,
modifier = Modifier
.fillMaxSize(0.5f)
)
}
3.流光边框
一个径向渐变,再加一个无限动画,让center一直沿着边框顺时针转。(注意,compose中的border是在组件之内,占据内部的大小)
//https://juejin.cn/post/7300784595619233819
//这个url是我发现这个效果的网址
@Composable
fun FlowingCard() {
val shape = remember { RoundedCornerShape(8.dp) }
var size by remember { mutableStateOf(IntSize.Zero) }
val interactionSource = remember { MutableInteractionSource() }
val hover by interactionSource.collectIsHoveredAsState()
val infiniteTransition = rememberInfiniteTransition()
val center by infiniteTransition.animateValue(
Offset.Zero,
Offset(size.width.toFloat(), size.height.toFloat()),
typeConverter = Offset.VectorConverter,
infiniteRepeatable(
keyframes {
durationMillis = 2000 //动画执行时长
Offset.Zero at 0
Offset(size.width.toFloat(), 0f) at 400
Offset(size.width.toFloat(), size.height.toFloat()) at 1000
Offset(0f, size.height.toFloat()) at 1400
Offset.Zero at 2000
},
repeatMode = RepeatMode.Restart
)
)
Box(
modifier = Modifier
.size(190.dp, 250.dp)
.onGloballyPositioned {
size = it.size
}
.background(Color.Black, shape)
.hoverable(interactionSource)
.border(
4.dp, Brush.radialGradient(
listOf(
Color(1, 209, 125),
Color.Transparent
),
center = center,
radius = 100f
), shape
),
contentAlignment = Alignment.Center
) {
Icon(
Icons.Outlined.Face,
contentDescription = null,
tint = Color.Cyan,
modifier = Modifier
.fillMaxSize(0.5f)
)
}
}
总结
本文写了三个有趣的边框动画,可以用在类似Card组件的边框上,如果你有喜欢或者觉得有趣的动画,可以发在评论区,我可以学习实现。