compose loading 第三篇

78 阅读1分钟

compose loading 第三篇

利用keyframes制作变相球体运动效果

device-2023-10-21-175137 00_00_00-00_00_30.gif

Box(modifier = Modifier.fillMaxSize()) {
    Dialog(
        onDismissRequest = { /*TODO*/ },
        properties = DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = true)
    ) {
        Box(
            Modifier
                .wrapContentSize()
                .defaultMinSize(minWidth = 120.dp, minHeight = 120.dp)
                .align(
                    Alignment.Center
                )
                .background(Color(0x80000000), RoundedCornerShape(12.dp))
        ) {
            var start1 by remember {
                mutableStateOf(false)
            }
            var ratio = animateFloatAsState(
                targetValue = if (start1) 3f else 0.0f, animationSpec = infiniteRepeatable(
                    animation = keyframes {
                        durationMillis = 1200
                        0.0f at 0 with FastOutLinearInEasing
                        1f at 100 with LinearEasing
                        2f at 1000 with LinearOutSlowInEasing

                    }, repeatMode = RepeatMode.Reverse
                )
            )
            Canvas(
                modifier = Modifier
                    .size(48.dp)
                    .align(Alignment.Center)
                    .rotate(45f),
                onDraw = {
                    var r = 16.dp.value
                    translate(top = if (ratio.value > 2f) -(size.height / 2) * (ratio.value / 3f) else 0f) {
                        rotate(
                            degrees = if (ratio.value > 1f && ratio.value <= 2f) 360 * (ratio.value - 1f) else 0f,
                            pivot = Offset(size.width / 2, size.height / 2)
                        ) {
                            translate(top = if (ratio.value <= 1f) size.height * ratio.value / 2 else size.height / 2) {
                                drawCircle(
                                    Color.White,
                                    radius = r,
                                    center = Offset(size.width / 2, size.height / 2)
                                )
                            }
                        }
                    }


                })
            if (!start1) {
                LaunchedEffect(key1 = "roll", block = {
                    start1 = true
                })
            }

        }
    }
}

三个球体跳动等待效果

device-2023-10-20-172522 00_00_00-00_00_30.gif

Box(modifier = Modifier.fillMaxSize()) {
    Dialog(
        onDismissRequest = { /*TODO*/ },
        properties = DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = true)
    ) {
        Box(
            Modifier
                .wrapContentSize()
                .defaultMinSize(minWidth = 120.dp, minHeight = 120.dp)
                .align(
                    Alignment.Center
                )
                .background(Color(0x80000000), RoundedCornerShape(12.dp))
        ) {
            var start by remember {
                mutableStateOf(false)
            }
            var start1 by remember {
                mutableStateOf(false)
            }
            val index by animateIntAsState(
                targetValue = if (start) 4 else 1,
                animationSpec = infiniteRepeatable(
                    animation = tween(
                        900,
                        easing = LinearEasing
                    ), repeatMode = RepeatMode.Reverse
                )
            )
            Log.d("TAG", "index$index")
            val value by animateFloatAsState(
                targetValue = if (start1) 1f else 0.0f, animationSpec = spring(
                    dampingRatio = Spring.DampingRatioHighBouncy,
                    stiffness = Spring.StiffnessMedium
                ), finishedListener = {
                    if (it == 1f) {
                        start1 = false
                    } else if (it == 0f) {
                        start1 = true
                    }
                }
            )
            Canvas(modifier = Modifier
                .size(48.dp)
                .align(Alignment.Center), onDraw = {
                var r = 16.dp.value
                var tranY = size.height * value / 4
                translate(top = if (index == 1) tranY else 0f) {
                    drawCircle(
                        Color.White,
                        radius = r,
                        center = Offset(0f, size.height / 2)
                    )
                }
                translate(top = if (index == 2) tranY else 0f) {
                    drawCircle(
                        Color.White,
                        radius = r,
                        center = Offset(size.width / 2, size.height / 2)
                    )
                }
                translate(top = if (index == 3) tranY else 0f) {
                    drawCircle(
                        Color.White,
                        radius = r,
                        center = Offset(size.width, size.height / 2)
                    )
                }
            })
            val scope = rememberCoroutineScope()
            if (!start) {
                LaunchedEffect(key1 = "roll", block = {
                    scope.launch {
                        start = true
                    }

                })
            } else {
                LaunchedEffect(key1 = "roll", block = {
                    scope.launch {
                        start1 = true
                    }

                })
            }
        }
    }
}

大方片x、y、z旋转效果

device-2023-10-20-173237 00_00_00-00_00_30.gif

Box(modifier = Modifier.fillMaxSize()) {
    Dialog(
        onDismissRequest = { /*TODO*/ },
        properties = DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = true)
    ) {
        Box(
            Modifier
                .wrapContentSize()
                .defaultMinSize(minWidth = 120.dp, minHeight = 120.dp)
                .align(
                    Alignment.Center
                )
                .background(Color(0x80000000), RoundedCornerShape(12.dp))
        ) {
            var start by remember {
                mutableStateOf(false)
            }
            var start1 by remember {
                mutableStateOf(false)
            }
            val index by animateIntAsState(
                targetValue = if (start) 4 else 1,
                animationSpec = infiniteRepeatable(
                    animation = tween(
                        2000,
                        easing = LinearEasing
                    ), repeatMode = RepeatMode.Reverse
                )
            )
            Log.d("TAG", "index$index")
            val value by animateFloatAsState(
                targetValue = if (start1) 1f else 0.0f, animationSpec = spring(
                    dampingRatio = Spring.DampingRatioHighBouncy,
                    stiffness = Spring.StiffnessLow
                ), finishedListener = {
                    if (it == 1f) {
                        start1 = false
                    } else if (it == 0f) {
                        start1 = true
                    }
                }
            )
            Canvas(modifier = Modifier
                .size(48.dp)
                .align(Alignment.Center)
                .graphicsLayer {
                    when (index) {
                        1 -> {
                            this.rotationZ = 360 * value
                        }

                        2 -> {
                            this.rotationX = 360 * value
                        }

                        3 -> {
                            this.rotationY = 360 * value
                        }
                    }

                }, onDraw = {
                drawRect(Color.Green)
            })
            val scope = rememberCoroutineScope()
            if (!start) {
                LaunchedEffect(key1 = "roll", block = {
                    scope.launch {
                        start = true
                    }

                })
            } else {
                LaunchedEffect(key1 = "roll", block = {
                    scope.launch {
                        start1 = true
                    }

                })
            }
        }
    }
}