1

I am trying to draw Squircle Image using the Android Jetpack Compose.

I found simple code set on Github: https://github.com/Size0f/android.compose.squircle/blob/master/squircle/src/main/java/com/sizeof/libraries/compose/squircle/SquircleShape.kt

Here is SquuircleShape compose:

class SquircleShape : Shape {

    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ) = Outline.Generic(
        path = createSquirclePath(size, SMOOTHING)
    )

    private fun createSquirclePath(size: Size, smoothing: Double): androidx.compose.ui.graphics.Path {
        return Path().apply {
            val oversize = size.width * OVERSAMPLING_MULTIPLIER
            val squircleRadius = (oversize / 2F).toInt()

            // power radius before for optimization
            val poweredRadius = squircleRadius
                .toDouble()
                .pow(smoothing)

            // generate Y coordinates for path
            val yCoordinates = (-squircleRadius..squircleRadius).map { x ->
                x.toFloat() to evalSquircleFun(x, poweredRadius, smoothing)
            }

            // generate Y coordinates for mirror half of squircle shape
            val yMirroredCoordinates = yCoordinates.map { (x, y) -> Pair(x, -y) }

            var currentX = 0F
            var currentY = 0F

            // set path by using quadraticBezier
            (yCoordinates + yMirroredCoordinates).forEach { (x, y) ->
                quadTo(currentX, currentY, x, y)
                currentX = x
                currentY = y
            }

            close()

            // scale down to original size - for better corners without anti-alias
            transform(
                scaleMatrix(
                    sx = 1 / OVERSAMPLING_MULTIPLIER,
                    sy = 1 / OVERSAMPLING_MULTIPLIER
                )
            )

            // translate path to center
            transform(
                translationMatrix(
                    tx = size.width / 2,
                    ty = size.height / 2
                )
            )
        }.asComposePath()
    }

    // squircle formula: | (r^smoothing) - |x|^5 | ^ (1 / smoothing)
    private fun evalSquircleFun(x: Int, poweredRadius: Double, smoothing: Double) =
        (poweredRadius - abs(x.toDouble().pow(smoothing))).pow(1 / smoothing).toFloat()

    companion object {
        private const val SMOOTHING = 3.0
        private const val OVERSAMPLING_MULTIPLIER = 4F
    }
}

Here is SquircleImage compose:

@Composable
fun SquircleImage(
    modifier: Modifier = Modifier,
    imageRequest: ImageRequest,
    size: Dp,
    backgroundColor: Color = Gray10,
    borderColor: Color = Gray20,
    borderSize: Dp = 0.5.dp,
    radius: Dp = 24.dp
) {
    Box(
        modifier = modifier
            .size(size)
            .clip(SquircleShape())
            .background(borderColor),
        contentAlignment = Alignment.Center
    ) {
        Image(
            painter = rememberAsyncImagePainter(
                model = imageRequest,
                contentScale = ContentScale.Crop
            ),
            contentDescription = null,
            contentScale = ContentScale.Crop,
            modifier = Modifier
                .clip(SquircleShape())
                .background(backgroundColor)
                .size(size - borderSize - borderSize),
        )
    }
}

In general, it works fine like: enter image description here

But if I navigate other pages again and again repeatedly, the Squircle images are gone!: enter image description here

There is no exception or meaningful logs.

It doesn't happen always. Occurrence frequency maybe 1/10? And It occurs on Android 10.

Somebody help me, please?

yoonhok
  • 2,575
  • 2
  • 30
  • 58

0 Answers0