前两天看到这样一个效果,感觉挺有意思(原文地址:A Fancy Hover Effect For Your Avatar | CSS-Tricks - CSS-Tricks) 就想用安卓也实现一个挺简单的,就分享下实现)
放置图片并实现缩放效果
这一步很简单就是放置一个Image 附上使用的图片链接 assets.codepen.io/1480814/av+…
var scaled by remember {
mutableStateOf(false)
}
val imgScale by animateFloatAsState(targetValue = if (scaled) 1.25f else 1f)
Box(modifier = Modifier
.border(5.dp, Color.Red, CircleShape)
.clip(CircleShape)
.pointerInteropFilter {
when (it.action) {
MotionEvent.ACTION_DOWN -> {
scaled = true
}
MotionEvent.ACTION_MOVE -> {}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
scaled = false
}
else -> false
}
true
}) {
Image(
modifier = Modifier
.size(300.dp)
.scale(imgScale),
painter = painterResource(id = R.drawable.ic_avatar),
contentDescription = null
)
}
效果如下:
实现头像悬浮效果
借鉴原作者的思路,只要裁切时的形状是如下的绿幕形状即可
实现代码如下
class HoverShape() : Shape {
override fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density
): Outline {
return Outline.Rounded(
RoundRect(
left = 0f,
top = -size.height,
right = size.width,
bottom = size.height,
bottomLeftCornerRadius = CornerRadius(size.width),
bottomRightCornerRadius = CornerRadius(size.width)
)
)
}
}
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun FancyHoverAvatar(modifier: Modifier) {
var scaled by remember {
mutableStateOf(false)
}
val imgScale by animateFloatAsState(targetValue = if (scaled) 1.25f else 1f)
Box(modifier = modifier
.clip(HoverShape())
.drawWithContent {
val width = size.width * 0.025f
drawCircle(Color(0xFFECD078))
drawArc(
color = Color(0xFFC02942),
startAngle = 180f,
sweepAngle = 180f,
topLeft = Offset(width / 2, width / 2),
size = Size(size.width - width, size.height - width),
useCenter = false,
style = Stroke(width),
)
drawContent()
drawArc(
color = Color(0xFFC02942),
startAngle = 0f,
sweepAngle = 180f,
topLeft = Offset(width / 2, width / 2),
size = Size(size.width - width, size.height - width),
useCenter = false,
style = Stroke(width),
)
}
.pointerInteropFilter {
when (it.action) {
MotionEvent.ACTION_DOWN -> {
scaled = true
}
MotionEvent.ACTION_MOVE -> {}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
scaled = false
}
else -> false
}
true
}) {
Image(
modifier = Modifier
.size(300.dp)
.scale(imgScale),
painter = painterResource(id = R.drawable.ic_avatar),
contentDescription = null
)
}
}
(简要说说实现,因为没啥人看)
圆环绘制
原本的圆环部分不再用border实现,因为上下两部分的和图片的层级关系不一致,就直接调用drawArc的方式控制先后绘制顺序
裁切效果
继承Shape类后,按照原作者的绿幕形状进行实现即可,可查看上面的HoverShape部分,很容易
椭圆变形效果(未实现)
写到上面部分就懒下来了
最终效果
结语
用Compose可以极快的实现一些特定的效果,欢迎大家也来尝试!