Android Kaki

Build beautiful, usable products using required Components for Android.

Exposing WhatsApp’s circle with Jetpack Compose


Victor Brandalize

ProAndroidDev

On this article, I’ll present you the way to create a round reveal animation that WhatsApp makes use of with Jetpack Compose.

My first try was to make use of AnimatedVisibility to attain one thing related.

AnimatedVisibility(
seen = seen,
) {
BottomSheet()
}

This code is equal to:

AnimatedVisibility(
seen = seen,
enter = expandVertically(),
exit = shrinkVertically()
) {
BottomSheet()
}

Nevertheless, I’m not in a position to obtain the round movement I’m on the lookout for.

My second try was to make use of a form to chop my composable issues. GenericShape permits me to write down any form I need however nothing permits me to attract a circle so I begin with a rectangle.

GenericShape { measurement, route ->
val heart = measurement.width / 2f
    this.addRect(
Rect(
left = heart - heart * it,
high = heart - heart * it,
proper = heart + heart * it,
backside = measurement.top
)
)
shut()
}

I’ve one thing to animate but it surely nonetheless misses the round movement I am on the lookout for.

Given {that a} rectangle isn’t what I need, I attempted utilizing addArc to attract an arc across the rectangle.

GenericShape { measurement, route ->
val centerV = measurement.top / 2f
val centerH = measurement.width / 2f
    addArc(
Rect(
left = centerH - centerH * it * 2,
high = measurement.top - measurement.top * it,
proper = centerH + centerH * it * 2,
backside = measurement.top + measurement.top * it
),
0f,
-180f
)
shut()
}

The result’s significantly better, nonetheless, I am unable to scale it utterly so there’s at all times a part of the element reduce out.

What if as an alternative of utilizing a standard arc, I exploit a extra “complicated” arc? That is once I tried to make use of cubicTo, it makes use of a cubic Bézier curve. It has 4 management factors that enable me to attract one thing like a semicircle.

If I implement a Bézier dice curve of the identical measurement as my composable curve the highest corners will nonetheless be reduce out so I want a solution to make the curve wrap the entire line my mixable curvy.

To try this, I made the curve twice as massive because the recombinable curve. Give x axis is finished by multiplying the width by 2, for y i’m utilizing an axis lerp perform come from top ARRIVE -height.

GenericShape { measurement, route ->
val centerH = measurement.width / 2f
    moveTo(
x = centerH - centerH * it * 2,
y = measurement.top,
)
val currentHeight = lerp(measurement.top, -size.top, it) cubicTo(
x1 = centerH - centerH * it,
y1 = currentHeight,
x2 = centerH + centerH * it,
y2 = currentHeight,
x3 = centerH + centerH * it * 2,
y3 = measurement.top,
)
shut()
}

The result’s fairly near what I need however the form does not develop proportionally.

I stored tweaking the code till I discovered one thing fairly near the animation WhatsApp was utilizing.

GenericShape { measurement, _ ->
val centerH = measurement.width / 2f
val multiplierW = 1.5f + measurement.top / measurement.width
    moveTo(
x = centerH - centerH * progress * multiplierW,
y = measurement.top,
)
val currentWidth = (centerH * progress * multiplierW * 2.5f) cubicTo(
x1 = centerH - centerH * progress * 1.5f,
y1 = measurement.top - currentWidth * 0.5f,
x2 = centerH + centerH * progress * 1.5f,
y2 = measurement.top - currentWidth * 0.5f,
x3 = centerH + centerH * progress * multiplierW,
y3 = measurement.top,
)
shut()
}

There are some magic numbers within the calculation and I am undecided why they work, nonetheless, the top consequence seems to be fairly just like what WhatsApp is utilizing.

In the event you assessment the WhatsApp animations, it’s possible you’ll discover that the objects inside the cardboard additionally animate a bit. Their scale could be at first 90%, then enhance to 110% and at last lower to 100%.

For implementation that I used animateFloatAsState.

var scale by bear in mind { mutableStateOf(0.9f) }
val animation = animateFloatAsState(
targetValue = scale,
animationSpec = FloatSpringSpec(
dampingRatio = 0.3f,
)
)
LaunchedEffect(Unit) {
delay(20 + place.toLong() * 20)
scale = 1f
}
Picture(
modifier = Modifier
...
.graphicsLayer {
scaleX = animation.worth
scaleY = animation.worth
}
)

It is a easy float animation that goes from 0.9 to 1 and makes use of the spring animation spec. I am including a 20 millisecond delay + one other delay based mostly on merchandise place so every part does not animate on the identical time. If you would like one thing to look later, simply give it a better place.

It does not look precisely like what WhatsApp makes use of however in case you can maintain tweaking delay and dampingRatio worth till you get one thing that you’re happy with.

If you wish to verify the supply code, you will discover it This.

In case you have any feedback or recommendations, be happy to contact me on Twitter.

John Wick: Chapter 4 (FREE) FULLMOVIE The Super Mario Bros Movie avatar 2 Where To Watch Creed 3 Free At Home Knock at the Cabin (2023) FullMovie Where To Watch Ant-Man 3 and the Wasp: Quantumania Cocaine Bear 2023 (FullMovie) Scream 6 Full Movie
Updated: June 6, 2023 — 11:14 pm

Leave a Reply

Your email address will not be published. Required fields are marked *

androidkaki.com © 2023 Android kaki