Pages attached to single rotating panel

I’m trying to make a rotating menu, curiously similar to the one in your sidebar example, but with 3 different buttons instead of 2. I’m trying to implement the transitions between the 3 buttons using Pages and Navigators. However, I’m lost as to how I could set up the animations. It seems to me that LinearNavigator along with Exiting/EnteringNavigation only works if each page is a separate panel and each one has to be moved independently, but in my case each page is a button on the same panel, and moving one moves all. Is there a correct way to do this, or should I look for some kind of workaround instead?

For debugging purpose, I’ve placed the whole menu-disc in the middle of the screen, and each button has a NavigateTo that rotates that button to the lower-right corner (which is the one that will be visible once the menu-disc is in the correct place in the upper-left corner of the screen).

<Panel HitTestMode="LocalVisualAndChildren" ux:Name="menuDisc" Width="170" Height="170" >

    <float4 ux:Key="accentColor"   ux:Value="#ee8485"/>
    <Panel ux:Name="menuDiscPanel">

        <Circle ux:Binding="Appearance">
            <SolidColor Color="{Resource accentColor}"/>
        </Circle>

        <StackPanel ux:Class="HamburgerIcon" Width="25" Height="21">
            <Style>
                <Rectangle Margin="0,2" Height="3" CornerRadius="3">
                    <SolidColor Color="#fff" />
                </Rectangle>
            </Style>
            <Rectangle />
            <Rectangle />
            <Rectangle />
        </StackPanel>

        <Panel ux:Class="CloseIcon" Width="25" Height="25">
            <Style>
                <Rectangle Height="3" CornerRadius="3">
                    <SolidColor Color="#fff" />
                </Rectangle>
            </Style>
            <Rectangle>
                <Rotation Degrees="45" />
            </Rectangle>
            <Rectangle>
                <Rotation Degrees="-45" />
            </Rectangle>
        </Panel>

        <Panel ux:Class="BackIcon" Width="16" Height="25">
            <Style>
                <Rectangle Width="3" Height="20" CornerRadius="3">
                    <SolidColor Color="#fff" />
                </Rectangle>
            </Style>
            <Rectangle Alignment="Left">
                <Rotation Degrees="-45" />
            </Rectangle>
            <Rectangle Alignment="Right">
                <Rotation Degrees="45" />
            </Rectangle>
        </Panel>

        <Grid RowCount="2" ColumnCount="2" CellSpacing="-19">
            <Panel/>
            <BackIcon>
                <Clicked>
                    <NavigateTo Context="nav" Target="back"/>
                </Clicked>
            </BackIcon>
            <CloseIcon>
                <Clicked>
                    <NavigateTo Context="nav" Target="close"/>
                </Clicked>
            </CloseIcon>
            <HamburgerIcon>
                <Clicked>
                    <NavigateTo Context="nav" Target="hamburger"/>
                </Clicked>
            </HamburgerIcon>
        </Grid>

        <Rotation Degrees="0" ux:Name="rotation"/>
    </Panel>


    <DirectNavigation ux:Name="nav"/>

    <Page ux:Name="back">
        <WhileActive>
            <Rotate Duration="1" Easing="ElasticOut" Target="menuDisc" Degrees="90"/>
        </WhileActive>
    </Page>
    <Page ux:Name="hamburger">
        <WhileActive>
            <Rotate Duration="1" Easing="ElasticOut" Target="menuDisc" Degrees="0"/>
        </WhileActive>
    </Page>
    <Page ux:Name="close">
        <WhileActive>
            <Rotate Duration="1" Easing="ElasticOut" Target="menuDisc" Degrees="-90"/>
        </WhileActive>
    </Page>

</Panel>

The way the problem shows itself in this example is that the Easing is not the same, depending on which button you press.

This happens because two rotation animator are acting at the same time. Similar to adding two Rotation transforms and animating them separately.

Instead you can add a Rotation transform manually and animate it using a Change animator. The result is more predictable:

<Panel HitTestMode="LocalVisualAndChildren" ux:Name="menuDisc" Width="170" Height="170" >
        <Rotation ux:Name="menuDiscRotation"/>
     <!-- ....... -->
</Panel>
<Page ux:Name="back">
    <WhileActive>
        <Change menuDiscRotation.Degrees="90" Duration="1" Easing="BounceOut"/>
    </WhileActive>
</Page>

There also seems to be some strangeness with the Elastic Easing curve, so i tried with BounceOut.

One last thing. If you add HitTestMode="LocalBounds" to your buttons, they will be easier to hit :slight_smile:

Here is your full code edited with my suggestion:

    <Panel ux:Name="menuDiscPanel">

        <Circle ux:Binding="Appearance">
            <SolidColor Color="{Resource accentColor}"/>
        </Circle>

        <StackPanel ux:Class="HamburgerIcon" Width="25" Height="21">
            <Style>
                <Rectangle Margin="0,2" Height="3" CornerRadius="3">
                    <SolidColor Color="#fff" />
                </Rectangle>
            </Style>
            <Rectangle />
            <Rectangle />
            <Rectangle />
        </StackPanel>

        <Panel ux:Class="CloseIcon" Width="25" Height="25">
            <Style>
                <Rectangle Height="3" CornerRadius="3">
                    <SolidColor Color="#fff" />
                </Rectangle>
            </Style>
            <Rectangle>
                <Rotation Degrees="45" />
            </Rectangle>
            <Rectangle>
                <Rotation Degrees="-45" />
            </Rectangle>
        </Panel>

        <Panel ux:Class="BackIcon" Width="16" Height="25">
            <Style>
                <Rectangle Width="3" Height="20" CornerRadius="3">
                    <SolidColor Color="#fff" />
                </Rectangle>
            </Style>
            <Rectangle Alignment="Left">
                <Rotation Degrees="-45" />
            </Rectangle>
            <Rectangle Alignment="Right">
                <Rotation Degrees="45" />
            </Rectangle>
        </Panel>

<Grid RowCount="2" ColumnCount="2" CellSpacing="-19">
    <Panel/>
    <BackIcon>
        <Clicked>
            <NavigateTo Context="nav" Target="back"/>
        </Clicked>
    </BackIcon>
    <CloseIcon>
        <Clicked>
            <NavigateTo Context="nav" Target="close"/>
        </Clicked>
    </CloseIcon>
    <HamburgerIcon>
        <Clicked>
            <NavigateTo Context="nav" Target="hamburger"/>
        </Clicked>
    </HamburgerIcon>
</Grid>

<Rotation Degrees="0" ux:Name="rotation"/>
    </Panel>


    <DirectNavigation ux:Name="nav"/>

    <Page ux:Name="back">
        <WhileActive>
            <Change menuDiscRotation.Degrees="90" Duration="1" Easing="BounceOut"/>
        </WhileActive>
    </Page>
    <Page ux:Name="hamburger">
        <WhileActive>
            <Change menuDiscRotation.Degrees="0" Duration="1" Easing="BounceOut"/>
        </WhileActive>
    </Page>
    <Page ux:Name="close">
        <WhileActive>
            <Change menuDiscRotation.Degrees="-90" Duration="1" Easing="BounceOut"/>
        </WhileActive>
    </Page>

</Panel>

Thanks for the suggestion, however that doesn’t work correctly. The animation snaps and goes from the back button rather than the close button when the close button is active and I click the hamburger icon…

I’m unsure whether this is a bug in fuse or in this ux…

You’re right, that didn’t really do the trick. Will have to look more into this one.

In the meantime you could take a look at the Attractor class:

<LinearNavigation ux:Name="nav"/>
<Attractor ux:Name="attractor" Target="menuDiscRotation.Degrees"/>
<Page ux:Name="back">
    <ActivatingAnimation>
        <Set attractor.Value="90"/>
    </ActivatingAnimation>
</Page>
<Page ux:Name="hamburger">
    <ActivatingAnimation>
        <Set attractor.Value="0"/>
    </ActivatingAnimation>
</Page>
<Page ux:Name="close">
    <ActivatingAnimation>
        <Set attractor.Value="-90"/>
    </ActivatingAnimation>
</Page>

It doesn’t currently allow for the same amount of customizability in terms of easing curves, but it lets you animate smoothly between arbitrary values.

Here is the full modified source:

<App Theme="Basic" ClearColor="#eeeeeeff">
    <Panel HitTestMode="LocalVisualAndChildren" ux:Name="menuDisc" Width="170" Height="170" >
        <Rotation ux:Name="menuDiscRotation"/>
        <float4 ux:Key="accentColor"   ux:Value="#ee8485"/>

        <Panel ux:Name="menuDiscPanel">

            <Circle ux:Binding="Appearance">
                <SolidColor Color="{Resource accentColor}"/>
            </Circle>

            <StackPanel ux:Class="HamburgerIcon" Width="25" Height="21">
                <Style>
                    <Rectangle Margin="0,2" Height="3" CornerRadius="3">
                        <SolidColor Color="#fff" />
                    </Rectangle>
                </Style>
                <Rectangle />
                <Rectangle />
                <Rectangle />
            </StackPanel>

            <Panel ux:Class="CloseIcon" Width="25" Height="25">
                <Style>
                    <Rectangle Height="3" CornerRadius="3">
                        <SolidColor Color="#fff" />
                    </Rectangle>
                </Style>
                <Rectangle>
                    <Rotation Degrees="45" />
                </Rectangle>
                <Rectangle>
                    <Rotation Degrees="-45" />
                </Rectangle>
            </Panel>

            <Panel ux:Class="BackIcon" Width="16" Height="25">
                <Style>
                    <Rectangle Width="3" Height="20" CornerRadius="3">
                        <SolidColor Color="#fff" />
                    </Rectangle>
                </Style>
                <Rectangle Alignment="Left">
                    <Rotation Degrees="-45" />
                </Rectangle>
                <Rectangle Alignment="Right">
                    <Rotation Degrees="45" />
                </Rectangle>
            </Panel>

            <Grid RowCount="2" ColumnCount="2" CellSpacing="-19">
                <Panel/>
                <BackIcon HitTestMode="LocalBounds">
                    <Clicked>
                        <NavigateTo Context="nav" Target="back"/>
                    </Clicked>
                </BackIcon>
                <CloseIcon HitTestMode="LocalBounds">
                    <Clicked>
                        <NavigateTo Context="nav" Target="close"/>
                    </Clicked>
                </CloseIcon>
                <HamburgerIcon HitTestMode="LocalBounds">
                    <Clicked>
                        <NavigateTo Context="nav" Target="hamburger"/>
                    </Clicked>
                </HamburgerIcon>
            </Grid>
        </Panel>

        <LinearNavigation ux:Name="nav"/>
        <Attractor ux:Name="attractor" Target="menuDiscRotation.Degrees"/>
        <Page ux:Name="back">
            <ActivatingAnimation>
                <Set attractor.Value="90"/>
            </ActivatingAnimation>
        </Page>
        <Page ux:Name="hamburger">
            <ActivatingAnimation>
                <Set attractor.Value="0"/>
            </ActivatingAnimation>
        </Page>
        <Page ux:Name="close">
            <ActivatingAnimation>
                <Set attractor.Value="-90"/>
            </ActivatingAnimation>
        </Page>

    </Panel>
</App>