lepoco / wpfui

WPF UI provides the Fluent experience in your known and loved WPF framework. Intuitive design, themes, navigation and new immersive controls. All natively and effortlessly.
https://wpfui.lepo.co
MIT License
7.67k stars 748 forks source link

NavigationItem pin animation #26

Open MajorXAML opened 2 years ago

MajorXAML commented 2 years ago

Just tweaked NavigationItem https://github.com/lepoco/wpfui/pull/25

Now it is an exact copy Microsoft Store nav except for the pin animation. In XAML we can make two types of animation for forward and backward respectively, but we need something in the code to know which one to play.

Example Animation

MajorXAML commented 2 years ago

I give up, I guess I'm too dumb for this task. If anyone wants to continue, here is what I was able to find out.

  1. This pin seems to be outside of the NavigationItem (see screenshot) or uses negative margin. mstore

  2. It can probably be ported from the ModernWPF NavigationView I assume it's a PointerRectangle, but I'm not 100% sure. This code is incredibly complicated and confusing, I don't have enough knowledge yet. lol.

Here's an example from ModernWPF: navigation_modernwpf

The only difference is that in Windows 11 this pin only travels between two NavigationItems, whereas in ModernWPF this pin travels through all the pins that separate it from the end target

@Pomianowski Thanks for the code! but I don't quite understand how you can use it from the xaml (i.e. via triggers). Something like <EventTrigger RoutedEvent="NavigatedBackward"> doesn't work. 🤔

MajorXAML commented 2 years ago

Made a primitive version with margin animation, although it's not perfect simple `<Window x:Class="PinAnimation.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:PinAnimation" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="MainWindow" Width="800" Height="450" Background="Gray" mc:Ignorable="d">

<Window.Resources>
    <Storyboard x:Key="StoryboardUp">
        <ThicknessAnimationUsingKeyFrames
            BeginTime="00:00:00"
            Storyboard.TargetName="ActiveBorder"
            Storyboard.TargetProperty="Margin">
            <SplineThicknessKeyFrame KeyTime="00:00:00" Value="0,17,0,17" />
            <SplineThicknessKeyFrame KeyTime="00:00:0.1" Value="0,0,0,17" />
            <SplineThicknessKeyFrame KeyTime="00:00:0.2" Value="0,0,0,58" />
        </ThicknessAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="StoryboardDown">
        <ThicknessAnimationUsingKeyFrames
            BeginTime="00:00:00"
            Storyboard.TargetName="ActiveBorder2"
            Storyboard.TargetProperty="Margin">
            <SplineThicknessKeyFrame KeyTime="00:00:00" Value="0,17,0,17" />
            <SplineThicknessKeyFrame KeyTime="00:00:0.1" Value="0,17,0,0" />
            <SplineThicknessKeyFrame KeyTime="00:00:0.2" Value="0,58,0,0" />
        </ThicknessAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>

<Window.Triggers>
    <EventTrigger RoutedEvent="Button.Click" SourceName="UpBtn">
        <BeginStoryboard Storyboard="{StaticResource StoryboardUp}" />
    </EventTrigger>
    <EventTrigger RoutedEvent="Button.Click" SourceName="DownBtn">
        <BeginStoryboard Storyboard="{StaticResource StoryboardDown}" />
    </EventTrigger>
</Window.Triggers>

<Grid>
    <StackPanel VerticalAlignment="Center">
        <WrapPanel HorizontalAlignment="Center">

            <Border
                Width="64"
                Height="58"
                VerticalAlignment="Top"
                Panel.ZIndex="1"
                Background="Azure"
                CornerRadius="4">
                <Border
                    x:Name="ActiveBorder"
                    Width="4"
                    Margin="0,1,0,25"
                    HorizontalAlignment="Left"
                    Panel.ZIndex="0"
                    Background="BlueViolet"
                    CornerRadius="2" />
            </Border>

            <Border
                Width="64"
                Height="58"
                VerticalAlignment="Top"
                Panel.ZIndex="1"
                Background="Azure"
                CornerRadius="4">
                <Border
                    x:Name="ActiveBorder2"
                    Width="4"
                    Margin="0,17,0,17"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Stretch"
                    Panel.ZIndex="0"
                    Background="BlueViolet"
                    CornerRadius="2" />
            </Border>

        </WrapPanel>

        <WrapPanel
            Margin="10"
            HorizontalAlignment="Center"
            VerticalAlignment="Center">
            <Button x:Name="UpBtn" Content="Up" />
            <Button x:Name="DownBtn" Content="Down" />
        </WrapPanel>

    </StackPanel>
</Grid>

`