Compose绘制大转盘 学习Canvas 与 动画

362 阅读1分钟
package com.gy.composestudy.view

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import com.gy.composestudy.R


@Composable
fun circle(titles:List<String>){
    val rotaAnim = remember {
          Animatable(0f)
    }
    val circle = 360f / titles.size
    val context = LocalContext.current
    Canvas(modifier = Modifier
        .size(300.dp)
        .graphicsLayer {
            rotationZ = rotaAnim.value
        }, onDraw = {
        for (i in titles.indices){
            rotate(i * circle){
                drawArc(color = if(i%2 == 0) Color.Red else Color.Blue, startAngle = -90f - circle/2, sweepAngle = circle,useCenter = true)

                val paint= Paint().asFrameworkPaint()
                paint.color = ContextCompat.getColor(context,R.color.black)
                paint.textSize= 80f
                val fm: android.graphics.Paint.FontMetrics = paint.fontMetrics
                val baseLineY= -fm.ascent
                val contentHeight=fm.descent - fm.ascent
                val textDp=contentHeight/(2.625f)

                drawIntoCanvas {
                    it.nativeCanvas.drawText(titles[i],size.width/2,baseLineY + 50, paint)
                }
            }
        }
    })
    LaunchedEffect(key1 = Unit, block = {
        rotaAnim.animateTo(360f * 10, animationSpec = infiniteRepeatable(animation = tween(8000, easing = LinearEasing)))
    })
}

img_v2_7c46b733-d90a-48a7-84c2-5bdcc1642edg.jpg