Изменение содержимого холста Animate

У меня есть изображение, занимающее весь экран. Это как фон.

Я выполняю рендеринг с помощью метода drawImage(...)что делает его просто прекрасным и оправдывает мои ожидания. Я хочу изменить источник Image щелкнув по нему.

Как мне оживить это изменение?

Я не думаю Canvasпредлагает API анимации для чего угодно, не говоря уже о изображениях. Подойдет любая анимация. Cross-Fade, Slide (кстати, предпочтительно). Возможно ли это вообще в Canvas? Если нет, то как правильно это реализовать?

По коду отрисовки изображения:

      Canvas(modifier = Modifier.fillMaxSize()) {
    drawImage(
        background,
        srcSize = IntSize(background.width, background.height),
        dstSize = IntSize(size.width.roundToInt(), size.height.roundToInt())
    )
}

2 ответа

Надеюсь, мой пример поможет вам понять, как это работает, вы можете использовать AnimatedContentчтобы сделать сложную анимацию, как вы хотите. я не использовал canvas.

      Row {
    var count by remember { mutableStateOf(0) }
    Button(onClick = { count++ }) {
        Text("Add")
    }
    AnimatedContent(
        targetState = count,
        transitionSpec = {
            // Compare the incoming number with the previous number.
            if (targetState > initialState) {
                // If the target number is larger, it slides up and fades in
                // while the initial (smaller) number slides up and fades out.
                slideInVertically({ height -> height }) + fadeIn() with
                        slideOutVertically({ height -> -height }) + fadeOut()
            } else {
                // If the target number is smaller, it slides down and fades in
                // while the initial number slides down and fades out.
                slideInVertically({ height -> -height }) + fadeIn() with
                        slideOutVertically({ height -> height }) + fadeOut()
            }.using(
                // Disable clipping since the faded slide-in/out should
                // be displayed out of bounds.
                SizeTransform(clip = false)
            )
        }
    ) { targetCount ->
        Image(
            imageVector = if (targetCount % 2 == 0) Icons.Filled.ArrowBack else Icons.Filled.AccountBox,
            contentDescription = "test"
        )
    }
}

Результат

Вы можете использоватьAnimatableчтобы анимировать положение всего, что вы рисуете внутри Canvas, и нарисуйте оба старых/новых изображения следующим образом:

      var currentBackground by remember { mutableStateOf<ImageBitmap?>(null) }
var newBackground by remember { mutableStateOf<ImageBitmap?>(null) }
val offset = remember { Animatable(0f) }

LaunchedEffect(background) {
    if (currentBackground == null) {
        currentBackground = background
        return@LaunchedEffect
    }
    newBackground = background
    offset.animateTo(1f)
    currentBackground = background
    newBackground = null
    offset.snapTo(0f)
}
Canvas(modifier = Modifier.fillMaxSize()) {
    fun drawImage(image: ImageBitmap, offset: Float)  {
        drawImage(
            image,
            srcSize = IntSize(image.width, image.height),
            dstSize = IntSize(size.width.roundToInt(), size.height.roundToInt()),
            dstOffset = IntOffset(0, (size.height * offset).roundToInt()),
        )
    }
    clipRect {
        currentBackground?.let {
            drawImage(it, offset.value)
        }
        newBackground?.let {
            drawImage(it, offset.value - 1)
        }
    }
}

Результат:

Другие вопросы по тегам