Colton Idle
08/04/2021, 4:21 AMBox() {
Image(
modifier = Modifier.height(140.dp).offset(x = (-200).dp),
painter = painterResource(id = com.myapp.myresources.R.drawable.catdog),
contentDescription = null)
}
ms
08/04/2021, 4:23 AMcontentAlignment
to Start for Box, that may helpColton Idle
08/04/2021, 4:25 AMAlbert Chang
08/04/2021, 4:36 AMplaceable.place(-placeable.width, 0)
.Colton Idle
08/04/2021, 4:50 AMColton Idle
08/04/2021, 4:51 AMAlbert Chang
08/04/2021, 4:52 AMval offset = remember { Animatable(0) }
// In layout block
placeable.place(offset.value - placeable.width, 0)
Colton Idle
08/04/2021, 4:53 AMColton Idle
08/04/2021, 5:10 AMprivate fun Modifier.animatedXAxisPeak(offset: Float) = layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
layout(placeable.width, placeable.height) {
placeable.place(x = ((offset - (placeable.width)).toInt()), y = 0)
}
}
I haven't figured out how to do the animated offset yet.
I thought this would work, but I'll keep trying.
Box() {
val offset = remember { Animatable(0F) }
if (currentPage == 1) {
offset.targetValue = 50F
} else if (currentPage == 2) {
offset.targetValue = 100F
}
Image(
modifier =
Modifier.height(140.dp)
.animatedXAxisPeak(offset = offset.value),
Albert Chang
08/04/2021, 5:14 AManimateTo()
on the Animatable
.
Also if your animation is state-based you may want to use animateFloatAsState
.Nader Jawad
08/04/2021, 5:20 AMAlignment
parameter to the Image
composable with a value of -1, 0 for the horizontal and vertical alignment respectively. This will align the image to the left side within the bounds of the Image composable. An alignment of 0,0 means to center the contents of the drawn image within the composable bounds. Alignment is intended to be used for positioning or parallax effects within the Image composable.Colton Idle
08/04/2021, 5:22 AMBox {
val offset = remember { Animatable(0F) }
val scope = rememberCoroutineScope()
if (currentPage == 1) {
scope.launch { offset.animateTo(50F) }
} else if (currentPage == 2) {
scope.launch { offset.animateTo(100F) }
}
Image(
modifier = Modifier.height(140.dp).animatedXAxisPeak(offset.value),
The only issue is the "animateTo" calls are just guesses of mine. I'm going to see if the alignment param makes things easier.Colton Idle
08/04/2021, 5:24 AMImage(
alignment = Alignment(-1, 0),
?ms
08/04/2021, 5:28 AMBiasAlignment
Nader Jawad
08/04/2021, 5:30 AMAlignment(-1, 0)
as you had in your snippetColton Idle
08/04/2021, 5:31 AMNader Jawad
08/04/2021, 5:31 AMNader Jawad
08/04/2021, 5:32 AMBiasAlignment
as @ms suggestedNader Jawad
08/04/2021, 5:33 AMAlignment
is the interface and BiasAlignment
is an implementation of that interfaceColton Idle
08/04/2021, 5:38 AMImage(
alignment = BiasAlignment(-1F, 0F),
modifier = Modifier.height(140.dp),
but the image still showed up dead center 🤔Nader Jawad
08/04/2021, 5:47 AMContentScale.Fit
which will automatically scale the image to fit within the bounds of the composable which won't end up needing to handle any alignment. As you mentioned earlier that the height is to be fixed and the image is expected to be wider than the height, you could use ContentScale.FillHeight
instead. This will ensure the image fills the height of the Image composable but will crop the width of the image being drawn. This is positioned by the alignment parameter you have provided as well.Albert Chang
08/04/2021, 5:49 AMBiasAlignment
?Nader Jawad
08/04/2021, 5:52 AMNader Jawad
08/04/2021, 5:52 AMColton Idle
08/04/2021, 5:53 AMImage(
alignment = BiasAlignment(-1F, 0F),
contentScale = ContentScale.FillHeight,
modifier = Modifier.height(140.dp)
I will keep trying different content scales...Albert Chang
08/04/2021, 5:55 AMNader Jawad
08/04/2021, 5:56 AMms
08/04/2021, 5:56 AMNader Jawad
08/04/2021, 5:57 AMColton Idle
08/04/2021, 5:57 AMNader Jawad
08/04/2021, 5:59 AMColton Idle
08/04/2021, 5:59 AMColton Idle
08/04/2021, 6:01 AMBox() {
Image(
alignment = BiasAlignment(-1F, 0F),
contentScale = ContentScale.FillHeight,
modifier = Modifier.height(140.dp),
painter = painterResource(id = com.myapp.myresources.R.drawable.catdog),
contentDescription = null)
}
This is what I have currently, and it seems like it's just smack in the middle of the screen. I will try with -2 etc, as Nader suggested.Albert Chang
08/04/2021, 6:04 AMplaceable.place(-placeable.width, 0)
).Colton Idle
08/04/2021, 6:05 AMColton Idle
08/04/2021, 6:07 AMBox {
val offset = remember { Animatable(10F) }
val scope = rememberCoroutineScope()
when (currentPage) {
0 -> scope.launch { offset.animateTo(10F) }
1 -> scope.launch { offset.animateTo(7F) }
2 -> scope.launch { offset.animateTo(5F) }
3 -> scope.launch { offset.animateTo(2F) }
4 -> scope.launch { offset.animateTo(-5F) }
5 -> scope.launch { offset.animateTo(-8F) }
}
Image(
alignment = BiasAlignment(offset.value, 0F),
contentScale = ContentScale.FillHeight,
modifier = Modifier.height(140.dp)
Nader Jawad
08/04/2021, 6:10 AMColton Idle
08/04/2021, 6:12 AMNader Jawad
08/04/2021, 6:15 AMAlbert Chang
08/04/2021, 6:23 AMval offsetPercent by animateFloatAsState(
targetValue = when (currentPage) {
0 -> 0f
1 -> 0.2f
2 -> 0.4f
3 -> 0.6f
4 -> 0.8f
else -> 1f
}
)
Image(
painter = painterResource(id = com.myapp.myresources.R.drawable.catdog),
contentDescription = null,
modifier = Modifier
.height(140.dp)
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
layout(constraints.maxWidth, placeable.height) {
placeable.place(
x = lerp(-placeable.width, constraints.maxWidth, offsetPercent),
y = 0
)
}
}
)
Colton Idle
08/04/2021, 6:25 AMAlbert Chang
08/04/2021, 6:27 AMandroidx.compose.ui.util.lerp
in androidx.compose.ui:ui-util
. Or you can just copy the function:
fun lerp(start: Float, stop: Float, fraction: Float): Float {
return (1 - fraction) * start + fraction * stop
}
Colton Idle
08/04/2021, 6:32 AMColton Idle
08/04/2021, 6:48 AMAlbert Chang
08/04/2021, 6:50 AMmeasurable.measure(constraints.copy(maxWidth = Constraints.Infinity))
.Nader Jawad
08/04/2021, 7:08 AMval offscreenAlignment = object : Alignment {
override fun align(
size: IntSize,
space: IntSize,
layoutDirection: LayoutDirection
): IntOffset {
return IntOffset(-size.width, 0)
}
}
Nader Jawad
08/04/2021, 7:09 AMColton Idle
08/04/2021, 3:38 PM