Android 13 introduced a wavy progress bar for its media controls in quick settings.
How can I recreate it in Jetpack Compose and Compose Multiplatform?
Here is a related question for Flutter and Dart: Squiggly Seekbar with Animation in Flutter
TLDR: There is a library for that: Wavy slider.
Disclosure: I'm the author of the library.
There are two methods to draw this wavy pattern.
(x, sine(x))
point)Android 13 and 14 has used Bezier curves (here is source code of Android 14 squiggly progress).
There are two variations of the Bezier curve (that I know of):
So, a simple way to draw the wave is to use cubic Bezier curves.
Start the x at 0
. Then call cubicRelativeTo
with three arguments: control point 1, control point 2, and the next point. Place the first control in the (middle, waveHeight) and the other in (middle, -waveHeight) and the next point in waveLength
. Set the x to waveLength and repeat this for the entire length of the whole wave (x < totalWaveLength).
The downside is that, the actual wave height is less than the value provided. To get an accurate height, this post will probably help.
See this comprehensive guide about Bezier curves: https://pomax.github.io/bezierinfo/
It does not matter which one of the two functions to use (it only affects the initial phase aka position of the wave). We are going to use the sine function.
So, progressing the x
from 0
to sliderTotalWidth
pixels (in a simple for loop), and given the following:
And then can call the canvas lineTo(x, y)
for each pair of x and y.
Then you just need to infinitely animate the wave shift between 0
and L
with your desired speed (duration) and provide that animated value as waveShiftPx
.
To see the complete implementation, see the core file of the library that does the drawing of the wave.