Solution TL;DR
Using Modifier.wrapContentSize(Alignment, true) on a child basically tells its parent “I will ignore your constraints and position myself with this alignment)“.
Failure to use Modifier.wrapContentSize on the child will just center (whenever it violates the parent constrains - this is 'compose' default behavior)
The unbounded parameter determines if this applies for the max constraints or not. In this case, it should be true since the duck gets centered when it violates the max contrains.
Full explanation
(From Adam Powell at Google):
This has to do with how Compose UI's layout system works. When a compose UI element is measured, the parent gives the child a set of constraints - min and max width and height. If the child returns a size that is not compatible with the constraints, the parent sees a size for the child clamped to be compatible with the constraints anyway.
When the parent places the misbehaving child, the child's actual position is centered with respect to the clamped size rect seen by the parent
This helps write and arrange UI elements that have hard requirements while attributing where the breakdown happened; it also helps for simple cases of placing absolute-sized elements within larger minimum-sized areas
Modifier.size - as opposed to Modifier.preferredSize - tells an element to disregard the constraints it is measured with and be the given size anyway.
So if you use Modifier.size(100.dp) inside a container that is only 50dp large, it will do what you ask for, but the parent will position that element as if it were only 50dp
That's what you're seeing here - the duck is bigger than the container, so it's getting centered by this default behavior. First along the horizontal axis, since it becomes larger than the available width first, and then along the vertical axis once it becomes too big for the available height too.
Modifiers have the ability to alter this behavior by implementing a resolution strategy for when the content becomes too big (or too small) for the constraints. Modifier.wrapContentSize is an example of this; it relaxes a minimum size constraint and lets you supply options for how the element should be positioned within the minimum size
Note that wrapContentSize has an unbounded parameter that permits the element to be larger than the available size, which seems particularly relevant for your case. Apply this to the modifier of the child inside the Box
Quoted from Slack thread https://kotlinlang.slack.com/archives/CJLTWPH7S/p1609086849306600