Menu
Baran Kahyaoglu Dev Blog
Baran Kahyaoglu Dev Blog

Glaring Path Animation

Posted on 08/02/201210/06/2020 by brnkhy

So we created a glare effect on standard border in previous post but that insipid, boring border with rounded corners looked terrible. In this post, we’ll try to improve the shape, keeping the same old glaring effect we created.

We can’t change the shape of a border in WPF but we can use some other elements instead of border to achieve the same effect, like Path.

What we will do is to create different layers of Path’s and place the content above it ( instead of inside, like we do with Border ). Then maybe add some triggers ( or VisualStates ) for MouseOver, Selected etc states.

 

Let’s start with a simple path first;

    <Path Name=“Border”
       Data=“M0,5 5,0 350,0 360,10 360,200 340,220 10,220 0,210 Z”
       Opacity=“1”
       Stroke=“#317185”
       StrokeThickness=“2” />

As you can see from this simple declaration; Path is pretty much Border with a custom shape ( for this kind of usage ). Only non-trivial thing is the Data attribute and syntax for data input. I will not go into detail for that but you can read a lot more about XAML Geometry and syntax here. But to give you a tldr; version, it’s like an array of points; 0,5 –>5,0 –>350,0 etc.

And this is what it should look like;

 

WindowClipping (2)

 

Not bad, not bad at all…

And another trick before the real thing; using Path as Opacity Mask. Considering our rectangular image won’t fit in this irregular shaped frame.

    <Border Width=“355” Height=“215”>
        <Image HorizontalAlignment=“Center”
               VerticalAlignment=“Center”
               SnapsToDevicePixels=“True”
               Source=”{Binding Screenshot}“
               Stretch=“UniformToFill”/>
        <Border.OpacityMask>
            <VisualBrush>
                <VisualBrush.Visual>
                    <Path Data=“M2,5 5,2 350,2 358,10 358,200 340,218 10,218 2,210 Z” Fill=“White” />
                </VisualBrush.Visual>
            </VisualBrush>
        </Border.OpacityMask>
    </Border>

Putting image into a border is a good old trick to properly centralize stretch image ( UniformToFill ) which I use frequently. And then we use a Path as Visual Brush to create an Opacity Mask for that border.

Now let’s start our picture frame. I’ll use a grid as container for all path’s, images, triggers and other stuff. You can also use any other panel for this, like Canvas. Grid is just easy-mode.

    <Grid Width=“360” Height=“220”>
        <Border Width=“355” Height=“215”>
            <Image HorizontalAlignment=“Center”
                   VerticalAlignment=“Center”
                   SnapsToDevicePixels=“True”
                   Source=”{Binding Screenshot}“
                   Stretch=“UniformToFill” />
            <Border.OpacityMask>
                <VisualBrush>
                    <VisualBrush.Visual>
                        <Path Data=“M2,5 5,2 350,2 358,10 358,200 340,218 10,218 2,210 Z” Fill=“White” />
                    </VisualBrush.Visual>
                </VisualBrush>
            </Border.OpacityMask>
        </Border>

        <Path Name=“MainBorder”
               Data=”{StaticResource path}“
               Opacity=“1”
               Stroke=“#317185”
               StrokeThickness=“2” />

        <Path Name=“Background”
               Data=”{StaticResource path}“
               Opacity=“0.1”
               StrokeThickness=“1”>
            <Path.Fill>
                <RadialGradientBrush Center=“0.5,0.5”>
                    <GradientStop Offset=“0” Color=“Transparent” />
                    <GradientStop Offset=“1” Color=“#148cd1” />
                </RadialGradientBrush>
            </Path.Fill>
        </Path>

        <Path Name=“BackgroundUpper”
               Data=“M0,150 0,5 5,0 220,0 180,30 50,30 30,50 30,120 Z”
               Opacity=“0.9”
               Stroke=“#148cd1”
               StrokeThickness=“1”>
            <Path.Fill>
                <LinearGradientBrush StartPoint=“0.5,0” EndPoint=“0.5,1”>
                    <GradientStop Offset=“0” Color=“#357194” />
                    <GradientStop Offset=“1” Color=“#045482” />
                </LinearGradientBrush>
            </Path.Fill>
        </Path>
        <Path Name=“BackgroundLower”
               Data=“M360,60 340,90 340,170 310,200 160,200 130,220 340,220 360,200”
               Opacity=“0.8”
               Stroke=“#148cd1”
               StrokeThickness=“1”>
            <Path.Fill>
                <LinearGradientBrush StartPoint=“0.5,0” EndPoint=“0.5,1”>
                    <GradientStop Offset=“0” Color=“#357194” />
                    <GradientStop Offset=“1” Color=“#045482” />
                </LinearGradientBrush>
            </Path.Fill>
        </Path>

        <Path Name=“Border”
               Data=”{StaticResource path}“
               StrokeThickness=“5”>
            <Path.Stroke>
                <LinearGradientBrush Opacity=“0.8” StartPoint=“0,0” EndPoint=“1,1”>
                    <GradientStop x:Name=“gs1” Offset=“-0.5” Color=“Transparent” />
                    <GradientStop x:Name=“gs2” Offset=“-0.4” Color=“Transparent” />
                    <GradientStop x:Name=“gs3” Offset=“0” Color=“#31C7F5” />
                    <GradientStop x:Name=“gs4” Offset=“0.4” Color=“Transparent” />
                    <GradientStop x:Name=“gs5” Offset=“1.5” Color=“Transparent” />
                </LinearGradientBrush>
            </Path.Stroke>
        </Path>

        <Grid.Triggers>
            <EventTrigger RoutedEvent=“Grid.Loaded”>
                <BeginStoryboard Name=“Glance”>
                    <Storyboard RepeatBehavior=“Forever”>
                        <DoubleAnimation Duration=“0:0:5”
                                           From=“-0.1”
                                           Storyboard.TargetName=“gs2”
                                           Storyboard.TargetProperty=“Offset”
                                           To=“5.0” />
                        <DoubleAnimation Duration=“0:0:5”
                                           From=“0”
                                           Storyboard.TargetName=“gs3”
                                           Storyboard.TargetProperty=“Offset”
                                           To=“5.1” />
                        <DoubleAnimation Duration=“0:0:5”
                                           From=“0.1”
                                           Storyboard.TargetName=“gs4”
                                           Storyboard.TargetProperty=“Offset”
                                           To=“5.2” />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Grid.Triggers>
    </Grid>

OK this is a lot of stuff, so before explaining what’s going on here, I’ll show you the result;

 

WindowClipping (3)

 

It might look a bit complex for a simple starter sample but it’s rather easy really.

 

Now let’s go back and have a look at stuff inside our container grid. First of all, we have our image at the bottom of everything ( wrapped by a border but it’s not really important at this point ). The wrapper border also uses a path as Opacity Mask to crop the sharp corners of our rectangular image to fit.

 

After that, there is “MainBorder”, the non-animated static thin line you see around our image. Nothing fancy here. It uses a StaticResource path, to show it’s not only possible but also much better option than writing Path data again and again.

 

Then there is the “Background” layer. I guess it’s a wrong name for it though as it’s above the image, not behind. It’ creates a blue haze around the image, using a RadialGradientBrush. You may remove it as well, but I think it helps to mesh the colorful image with our blue sci-fi frame.

 

Above that, there is “BackgroundUpper” and “BackgroundLower” . I don’t even know why I keep them calling “Background” even though they are on top of everything but whatever. Those are that plate-like parts at the top-left and bottom-right of the image. Kinda helps the mood I guess. They both use LinearGradientBrush as SolidColorBrush felt & looked boring.

 

Then there is “Border”, pretty much the path version of the border we created in previous post. This time it doesn’t have the static line though ( we use MainBorder for that ). This one is mainly transparent and there is just a thick glare which looks like it’s moving on MainBorder as they stacked perfectly. Kind of hard to describe but you’ll know what I mean as soon as you see it.

 

I believe the Grid Triggers are exactly same as the Border Triggers we created in previous post. They just change the Offset of LinearGradientBrush that we use in “Border”. The animation is on a 5 second loop, first 1 second is the glare effect moving through the border and next 4 seconds is just a padding between animations.

 

Aaand that’s it. I guess just “MainBorder” and “Border” would be enough but I wanted to show some extra stuff you can do. Playing around with XAML is always fun but overdoing it hurts it more than helps.

Ah and one more thing, this won’t work in Silverlight as it is. Silverlight doesn’t have VisualBrush ( which we used for Image OpacityMask ) and some other stuff. I bet there are equivalent stuff or a work around but that’s beyond me.

 

I hope you liked it, see you next time!

Share on Social Media
twitter facebook linkedin reddit email

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Facebook (Opens in new window)

Related

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Search

Subscribe to Blog via Email

Follow me on Twitter!

My Tweets

Categories

  • Desktop Development (26)
  • Game Development (39)
  • Mapbox Unity SDK (4)
  • Uncategorized (8)
  • Unity3D (21)
  • Web Development (6)
  • WinRT Development (1)

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org
©2025 Baran Kahyaoglu Dev Blog | Powered by WordPress & Superb Themes