Hey <@UNH9ZT3NZ> I tried to create a custom Vector...
# compose
m
Hey @Doris Liu I tried to create a custom VectorConverter for animating image scales. It didn't work out. I think I have to do more low-level or subclass the parent ContentScale interface. More in thread.
Copy code
val ContentScale.Companion.VectorConverter: TwoWayConverter<ContentScale, AnimationVector2D>
get() = TwoWayConverter({scale->
    when(scale){
        ContentScale.Crop -> AnimationVector2D(1f,1f)
        ContentScale.Fit -> AnimationVector2D(50f, 50f)
        ContentScale.FillHeight -> AnimationVector2D(100f, 100f)
        ContentScale.FillWidth -> AnimationVector2D(150f, 150f)
        ContentScale.Inside -> AnimationVector2D(200f, 200f)
        ContentScale.FillBounds -> AnimationVector2D(250f, 250f)
        ContentScale.None -> AnimationVector2D(300f, 300f)
        else -> AnimationVector2D(300f, 300f)
    }
},
{v ->
    when(v){
        AnimationVector2D(1f,1f) -> ContentScale.Crop
        AnimationVector2D(2f, 2f) -> ContentScale.Fit
        AnimationVector2D(3f, 3f) -> ContentScale.FillHeight
        AnimationVector2D(4f, 4f) -> ContentScale.FillWidth
        AnimationVector2D(5f, 5f) -> ContentScale.Inside
        AnimationVector2D(6f, 6f) -> ContentScale.FillBounds
        AnimationVector2D(7f,7f) -> ContentScale.None
        else -> ContentScale.None

    }
})
This does not seem to have any animating effect on the images' content scale. Are there any builtin options in Compose animation system to support ContentScale or do I have to define my own?
d
Could you share an example of the visual results you are going for with animating ContentScale?
m
I wanted to see a smooth transition between scenes when I changed ContentScale for example from ContentScale.Crop to ContentScale.FillWidth. With the custom VectorConverter I built, the content scale transition is not smooth, rather seems to be snapping. As far as I can remember, with view animations this was possible; with one of the animations, you could change scaleType and a smooth transition would occur.
I just found the View equivalent's name. It was ChangeImageTransform
d
You could animate the
ScaleFactor
that is calculated in
ContentScale
. Something like:
Copy code
@Composable
    fun animate(contentScale: ContentScale): ContentScale {
        val contentScaleState = rememberUpdatedState(newValue = contentScale)
        var scaleX: Animatable<Float, AnimationVector1D>? by remember {
            mutableStateOf(null)
        }
        var scaleY: Animatable<Float, AnimationVector1D>? by remember {
            mutableStateOf(null)
        }
        val scope = rememberCoroutineScope()
        return remember {
            object : ContentScale {
                override fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor {
                    val targetScaleFactor =
                        contentScaleState.value.computeScaleFactor(srcSize, dstSize)
                    scaleX = scaleX?.apply {
                        if (targetValue != targetScaleFactor.scaleX) {
                            scope.launch {
                                animateTo(targetScaleFactor.scaleX)
                            }
                        }
                    } ?: Animatable(targetScaleFactor.scaleX)

                    scaleY = scaleY?.apply {
                        if (targetValue != targetScaleFactor.scaleY) {
                            scope.launch {
                                animateTo(targetScaleFactor.scaleY)
                            }
                        }
                    } ?: Animatable(targetScaleFactor.scaleY)
                    return ScaleFactor(scaleX!!.value, scaleY!!.value)
                }
            }
        }
    }