JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.02k stars 1.1k forks source link

Canvas.drawArc is ignoring size parameter #458

Closed rustamsmax closed 2 years ago

rustamsmax commented 3 years ago

Canvas.drawArc is ignoring size parameter The issue is specific to desktop app. Android app is working as expected.

image

A workaround was to draw path with Path.addArcRad

image

olonho commented 3 years ago

Could you please provide code snippet that manifests bad behavior? Also note that signature of drawArc is

fun drawArc(
        left: Float,
        top: Float,
        right: Float,
        bottom: Float,
        startAngle: Float,
        sweepAngle: Float,
        useCenter: Boolean,
        paint: Paint
    )

and doesn't have size parameter.

rustamsmax commented 3 years ago

I used second option

image

olonho commented 3 years ago

Which version of Compose is that? Don't see method with such signature in 0.3.1 or 0.3.2.

olonho commented 3 years ago

Is it actually DrawScope.drawArc?

olonho commented 3 years ago

Works for me with code like that:

val infiniteTransition = rememberInfiniteTransition()
val radius by infiniteTransition.animateFloat(
        initialValue = 1f,
        targetValue = 600f,
        animationSpec = infiniteRepeatable(
            animation = tween(5000),
            repeatMode = RepeatMode.Restart
        )
    )
Canvas(modifier = Modifier.fillMaxSize()) {
            drawArc(
                color = Color.Black, topLeft = Offset.Zero, size = Size(radius, radius),
                startAngle = 0f, sweepAngle = -180f, useCenter = false,
                style = Stroke(width = 1f), alpha = 1.0f
            )
    }
rustamsmax commented 3 years ago

I'm using 0.4.0-build168 I'm not animating radius. I'm sharing full code snippet

https://gist.github.com/rustamsmax/a8083c6c3f330b18f8d4673052d33f1e

olonho commented 3 years ago

Indeed, we use Skija

public Canvas drawArc(float left, float top, float width, float height, float startAngle, float sweepAngle, boolean includeCenter, @NotNull Paint paint)

as


override fun drawArc(
        left: Float,
        top: Float,
        right: Float,
        bottom: Float,
        startAngle: Float,
        sweepAngle: Float,
        useCenter: Boolean,
        paint: Paint
    ) {
        skija.drawArc(
            left,
            top,
            right,
            bottom,
            startAngle,
            sweepAngle,
            useCenter,
            paint.skija
        )
    }
`
prepor commented 3 years ago

Thank you for the report! The fix is on the go! :)

olonho commented 3 years ago

Should be fixed in 0.4.0-build171, please check.

rustamsmax commented 3 years ago

Still not fixed

LouisCAD commented 3 years ago

@rustamsmax Sharing a reproducer that can be copy pasted (not a screenshot) should help maintainers check it's fixed 😉.

rustamsmax commented 3 years ago

I'm using 0.4.0-build168 I'm not animating radius. I'm sharing full code snippet

https://gist.github.com/rustamsmax/a8083c6c3f330b18f8d4673052d33f1e

@LouisCAD I've already shared gist

prepor commented 3 years ago

@rustamsmax I've just checked with 0.4.0-build173 and it looks like this:

Screenshot 2021-03-09 at 10 22 07

It looks correct, right?

rustamsmax commented 3 years ago

Hi @prepor Yes exactly. Did you uncomment the drawArc function call? In the code snippet the drawPath was a workaround

image

prepor commented 3 years ago

@rustamsmax yes, I did :)

olonho commented 3 years ago

@rustamsmax so does it fix it for you?

timo-drick commented 3 years ago

Not sure if it is related to this but i noticed that drawArc works not as expected when you define an offset. In this case it behaves differently. E.g. to get an Arc in center i have to use following code: Tested on 0.4.0-build171

fun main() = Window {
    Canvas(Modifier.fillMaxSize()) {
        val d = size.minDimension
        val r = d / 2f
        val offset = Offset((size.width / 2f - r), size.height / 2f - r)
        drawArc(
            color = Color.Green,
            size = Size(d - offset.x, d - offset.y), //  minus offset.x/y is the workaround and is not necessary in Android.
            topLeft = offset,
            startAngle = -90f,
            sweepAngle = 270f,
            useCenter = true
        )
    }
}
timo-drick commented 3 years ago

Ok it is fixed in build: 0.4.0-build173 :+1:

akurasov commented 2 years ago

Closing, as it is fixed.