How to smoothly move elements in a line without overlap

9658913--1374950--upload_2024-2-22_16-49-42.png

In our application, we are able to navigate various screens (in a set order) and depending which screen you are on, the top navigation bar (as posted in the image) gets updated with where you are, with the buttons indicating which screen it represents.

Normally (with ugui) I would probably calculate in code where I would need to position the buttons in relation to each other and which button should be in the middle (current screen), but I was wondering if there might be a more appropriate way with UI Toolkit.

Initially I thought I might make 3 visual elements for the left, middle and right and simply switch the buttons parent to the appropriate side, but that would instantly snap the button in place and I would like to have it (smoothly) move towards its destination.

Anyone know of an elegant solution to this? Otherwise I guess I would have to move it myself, calculating the relative positions.

Thanks in advance!

Hi,

Here is a little exemple I made using the uss transition:












/ui:VisualElement
/ui:VisualElement
/ui:UXML

With the following simple script to do the transition:

public class SpacerMove : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        var root = GetComponent<UIDocument>().rootVisualElement;
        root.RegisterCallback<TransitionEndEvent>(OnComplete);
    }

    private void OnComplete(TransitionEndEvent evt)
    {
        // Correctly reorder spacers around selected element.
        Debug.Log("TransitionEvent " + evt);
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            var root = GetComponent<UIDocument>().rootVisualElement;

            var spacerleft2 = root.Q("SpacerLeft2");
            spacerleft2.style.transitionProperty = new List<StylePropertyName> { new StylePropertyName("flex-grow") };
            spacerleft2.style.transitionDuration = new List<TimeValue> { new TimeValue(500, TimeUnit.Millisecond) };
            spacerleft2.style.flexGrow = 1.0f;

            var spacerRight = root.Q("SpacerRight");
            spacerRight.style.transitionProperty = new List<StylePropertyName> { new StylePropertyName("flex-grow") };
            spacerRight.style.transitionDuration = new List<TimeValue> { new TimeValue(500, TimeUnit.Millisecond) };
            spacerRight.style.flexGrow = 0.0f;
        }
    }
}

Let me know if it helps.

1 Like

Ah yes, thanks! This gives me something to play with.