Home > Software design >  How i can animation or state change inside the Canvas in jetpack compose?
How i can animation or state change inside the Canvas in jetpack compose?

Time:11-10

suppose i have simple composable fun which has Canvas.

Canvas(modifier = Modifier
        .padding(start = 60.dp, end = 60.dp)
        .fillMaxSize(),
        onDraw = {
            val w = size.width
            val h = size.height

            val s1LineOffset = w / 4 - 10
            val s2LineOffset = w * 3 / 8 - 10

            drawImage(
                image = ImageBitmap.imageResource(
                    res = resources,
                    id = R.drawable.bttn
                ),
                topLeft = Offset(
                    x = b1StartOffset,
                    y = 0f
                )
            )
          }
        )

I want to define the state of animation using the canvas sizes for initial and target value but i cant do so because i can't use this inside draw scope thats why i have to use it above the Canvas block, hence cant access Canvas size what should i do

val anim by ballAnim.animateFloat(
    initialValue = ,
    targetValue =,
    animationSpec =
)

CodePudding user response:

It is more of a simple job. Just create and remember a MutableState<T> value, then update it inside Canvas. For example,

var canvasSize by remember { mutableStateOf(IntSize()) }

Canvas(modifier = Modifier
        .padding(start = 60.dp, end = 60.dp)
        .fillMaxSize(),
        onDraw = {
    
            canvasSize = size //Assign it here
            val w = size.width
            val h = size.height

            val s1LineOffset = w / 4 - 10
            val s2LineOffset = w * 3 / 8 - 10

            drawImage(
                image = ImageBitmap.imageResource(
                    res = resources,
                    id = R.drawable.bttn
                ),
                topLeft = Offset(
                    x = b1StartOffset,
                    y = 0f
                )
            )
          }
        )
val anim by ballAnim.animateFloat(
        initialValue = canvasSize.width,
        targetValue = canvasSize.height, //whatever
        animationSpec = spring()
    )

CodePudding user response:

One of the options is animating some normalized value and denormalizing it using size inside onDraw, e.g.:

val animNormalized by ballAnim.animateFloat(
    initialValue = 0.5,
    targetValue = 0.8,
    animationSpec =
)

Canvas(modifier = Modifier
        .padding(start = 60.dp, end = 60.dp)
        .fillMaxSize(),
        onDraw = {
            val w = size.width
            val h = size.height
           
            val anim = animNormalized * w
            ...
          }
        )
  • Related