How to scale a control while keeping it centered?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Diet Estus

I have a DialogueBox node with the following structure.

NinePatchRect
  > RichTextLabel
  > AnimationPlayer

When I’m opening and closing the DialogueBox, I animate the rect_size of my NinePatchRect from (0,0) to (500,64) or vice versa.

Unfortunately, as the box scales up and down, it stays anchored to the position of its topleft corner.

Ideally, I’d like the box to scale up and down while staying positioned at its center.

Event if I set the NinePatchRect's layout to center, it does not stay centered as it scales.

Further, even if I place the NinePatchRect in a CenterContainer, it does not stay centered as it scales (rather, its topleft corner is positoned at the center of the CenterContainer).

So, my question:

How do I animate the rect_size of the NinePatchRect while keeping it centered?

I know I could reposition the NinePatchRect every frame in _process() using its current width and height, but this seems very inelegant.

Further, I know I could just animate the rect_scale and change the pivot_offset to the center of the NinePatchRect. The reason I would rather animate the rect_size is so I can keep the borders a fixed size on my NinePatchRect as I animate it open and closed.

I am having the same problem. Have you found any solution that does not involve manually recalculating the position of the control?

dr-pop | 2020-12-09 10:00

You can use the Pivot Offset in Rect and set them to half of the rect size. At least on 3.2.3.

nickchu35 | 2021-02-11 20:15

the issue with that approach is that it doesn’t work for a lot of situations. even changing the pivot offset is a bit of a hack as if the dimensions of the rect change you need to update the pivot again. i feel like this is a simple and common enough use case that the engine should handle it on its own

takecare | 2021-10-12 14:02

:bust_in_silhouette: Reply From: hilfazer

You can animate rect_size together with NinePatchRect’s position to make it stay centered.

Final position was initial position minus half of NinePatchRect’s final size ( it would be (250,32) in your example ).

If initial position was, for example, (400, 300) final position would be (400 - 250, 300 - 32) = (150, 268).