@@ -24,6 +24,9 @@ import androidx.compose.ui.unit.Dp
2424import androidx.compose.ui.unit.dp
2525import top.yukonga.miuix.kmp.basic.ProgressIndicatorDefaults.ProgressIndicatorColors
2626import top.yukonga.miuix.kmp.theme.MiuixTheme
27+ import kotlin.math.PI
28+ import kotlin.math.cos
29+ import kotlin.math.sin
2730
2831/* *
2932 * A [LinearProgressIndicator] with Miuix style.
@@ -260,6 +263,61 @@ fun CircularProgressIndicator(
260263 }
261264}
262265
266+ /* *
267+ * A [InfiniteProgressIndicator] with Miuix style showing an orbiting dot.
268+ *
269+ * @param modifier The modifier to be applied to the indicator.
270+ * @param color The color of the indicator.
271+ * @param size The size (diameter) of the circular indicator.
272+ * @param strokeWidth The width of the circular stroke.
273+ * @param orbitingDotSize The size of the orbiting dot.
274+ */
275+ @Composable
276+ fun InfiniteProgressIndicator (
277+ modifier : Modifier = Modifier ,
278+ color : Color = Color .Gray ,
279+ size : Dp = ProgressIndicatorDefaults .DefaultInfiniteProgressIndicatorSize ,
280+ strokeWidth : Dp = ProgressIndicatorDefaults .DefaultInfiniteProgressIndicatorStrokeWidth ,
281+ orbitingDotSize : Dp = ProgressIndicatorDefaults .DefaultInfiniteProgressIndicatorOrbitingDotSize
282+ ) {
283+ val rotationAnim = remember { Animatable (0f ) }
284+
285+ LaunchedEffect (Unit ) {
286+ rotationAnim.animateTo(
287+ targetValue = 360f ,
288+ animationSpec = infiniteRepeatable(
289+ animation = tween(800 , easing = LinearEasing ),
290+ repeatMode = RepeatMode .Restart
291+ )
292+ )
293+ }
294+
295+ Canvas (modifier = modifier.size(size)) {
296+ val center = Offset (this .size.width / 2 , this .size.height / 2 )
297+ val radius = (size.toPx() - strokeWidth.toPx()) / 2
298+
299+ drawCircle(
300+ color = color,
301+ radius = radius,
302+ center = center,
303+ style = Stroke (strokeWidth.toPx(), cap = StrokeCap .Round )
304+ )
305+
306+ val orbitRadius = radius - 2 * orbitingDotSize.toPx()
307+ val angle = rotationAnim.value * PI .toFloat() / 180f
308+ val dotCenter = center + Offset (
309+ x = orbitRadius * cos(angle),
310+ y = orbitRadius * sin(angle)
311+ )
312+
313+ drawCircle(
314+ color = color,
315+ radius = orbitingDotSize.toPx(),
316+ center = dotCenter
317+ )
318+ }
319+ }
320+
263321object ProgressIndicatorDefaults {
264322 /* * The default height of [LinearProgressIndicator]. */
265323 val DefaultLinearProgressIndicatorHeight = 6 .dp
@@ -270,6 +328,15 @@ object ProgressIndicatorDefaults {
270328 /* * The default size of [CircularProgressIndicator]. */
271329 val DefaultCircularProgressIndicatorSize = 36 .dp
272330
331+ /* * The default stroke width of [InfiniteProgressIndicator]. */
332+ val DefaultInfiniteProgressIndicatorStrokeWidth = 2 .dp
333+
334+ /* * The default radius width of the orbiting dot in [InfiniteProgressIndicator]. */
335+ val DefaultInfiniteProgressIndicatorOrbitingDotSize = 2 .dp
336+
337+ /* * The default size of [InfiniteProgressIndicator]. */
338+ val DefaultInfiniteProgressIndicatorSize = 20 .dp
339+
273340 /* *
274341 * The default [ProgressIndicatorColors] used in [LinearProgressIndicator].
275342 */
0 commit comments