Windows 10 1607, UWP, Composition APIs–Walked Through Demo Code

I’ve written a few posts about the Windows 10 composition APIs for beautiful, fluid, animated UX gathered under this URL;

Composition Posts

and today I was putting together some demo code for other purposes and I thought I’d screen-capture what I had as a walk through of some of the capabilities of those composition APIs starting from a blank slate and walking through it;

That’s just one of my own, unofficial walk-throughs. For the official bits, visit the team site at;

http://aka.ms/winuilabs

Enjoy Smile

Windows 10 1607, Composition, XAML and a Blurred Background

Apologies for a bit of a ‘radio silence’ on this blog in recent weeks, I’ve been doing some travelling and other bits and pieces.

Whilst I was away, a mail flooded in from my reader saying;

“Hi,I read your blog and I have a question with blur effect and really need your help.

The main page has a background image and the bottom of the main page is a grid, I want it with blur effect. I have been looking at some answers on stackoverflow,but it seems useless.

Is there a way easily to make it?”

I should say that the title of the mail includes the acronym UWP so this is about UWP rather than, say, WPF.

I think that the UWP Composition APIs can achieve this sort of effect for a UI so I could post an example that did that using those ‘raw’ APIs but I wanted to take this question in a different direction and look into a new thing that has arrived since I last posted on this blog site.

That’s the UWP Community Toolkit. and there’s a video about it over on Channel9 on Robert Green’s excellent Toolbox show;

image

and if you dig into those resources you’ll find that one of the things that this Toolkit offers to developers is an easier way to do some animations that are powered by the composition APIs.

The Blur animation is powered by the CompositionBackdropBrush from Windows 10 build 1607 so you’d need to be on that target platform to have it do something for you but, otherwise, it should be fine to have a small piece of XAML like this one;

 

  <Grid
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition />
    </Grid.RowDefinitions>
    <Image
      Source="ms-appx:///Assets/eva.jpg"
      Stretch="UniformToFill"
      Grid.RowSpan="2">
    </Image>
    <Grid
      Grid.Row="1"
      xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
      xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"
      xmlns:core="using:Microsoft.Xaml.Interactions.Core">
      <interactivity:Interaction.Behaviors>
        <behaviors:Blur
          x:Name="blurBehavior"
          Value="10"
          Duration="0"
          Delay="0"
          AutomaticallyStart="True" />
      </interactivity:Interaction.Behaviors>
    </Grid>
  </Grid>

and bring in the NuGet packages Microsoft.Toolkit.Uwp, Microsoft.Toolkit.Uwp.UI, Microsoft.Toolkit.Uwp.UI.Animations along with Win2D.uwp and that should be all that’s needed to blur the bottom half of the image that’s being displayed here.

Hopefully, that might answer the question that got asked.

Only one note here – I’m still trying to figure out whether this will work with the V1.0.0 NuGet packages that are currently published. I seemed to struggle to get my blur to show using those packages whereas it worked fine when I built the source code for the toolkit from github. I need to investigate but apply a bit of a caveat if you see something similar.

Windows 10, UWP and Composition–More Light, Less Shade

Just a quick follow up on the post that I published where I took some baby steps in using lighting and shadows with the Visual Layer on Windows 10 1607.

Windows 10, UWP and Composition–Light and Shade

In that post, I’d failed to get a simple XAML scene lit with a PointLight and then James pinged me on Twitter saying;

image

and I’d actually seen the sample in question which shimmers some text;

Capture

and I hadn’t realised that it was a XAML based sample so I stared at it and it took me maybe 2-3 minutes to figure out what’s different about it from my attempt and I thought it was worth sharing what it taught me.

My attempt to do lighting with XAML involved a piece of ‘UI’ like this;

  <Grid
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    x:Name="grid">
    <Image
      x:Name="image"
      Source="assets\img102.jpg"
      Stretch="UniformToFill" />
  </Grid>

and then some code-behind which looks like this;

namespace App23
{
  using System.Numerics;
  using Windows.UI;
  using Windows.UI.Xaml;
  using Windows.UI.Xaml.Controls;
  using Windows.UI.Xaml.Hosting;

  public sealed partial class MainPage : Page
  {
    public MainPage()
    {
      this.InitializeComponent();
      this.Loaded += OnLoaded;
    }
    void OnLoaded(object sender, RoutedEventArgs e)
    {
      var gridVisual = ElementCompositionPreview.GetElementVisual(this.grid);

      var compositor = gridVisual.Compositor;

      var pointLight = compositor.CreatePointLight();
      pointLight.CoordinateSpace = gridVisual;
      pointLight.Color = Colors.Yellow;
      pointLight.Offset = new Vector3(
          (float)this.grid.ActualWidth / 2,
          (float)this.grid.ActualHeight / 2,
          50);

      pointLight.Targets.Add(gridVisual);
    }
  }
}

Now, this doesn’t work for me and the fact that it didn’t work caused me to take the classic programmer’s thinking path of “Somebody Else’s Problem”;

“ah, this hasn’t worked so I have to assume that there must be some limitation in the composition layer which means that you can’t apply lighting to XAML elements”

and it was pretty easy for me to put it to one side and go and do something else instead.

However, if I’d looked at the ‘Text Shimmer’ sample beforehand I’d have been confident that the composition layer worked fine and it was my own code that was broken.

What was broken about it? Object lifetimes. Here’s code that works for me. Hopefully it’s not a ‘red-herring’ Smile

namespace App23
{
  using System.Numerics;
  using Windows.UI;
  using Windows.UI.Composition;
  using Windows.UI.Xaml;
  using Windows.UI.Xaml.Controls;
  using Windows.UI.Xaml.Hosting;

  public sealed partial class MainPage : Page
  {
    public MainPage()
    {
      this.InitializeComponent();
      this.Loaded += OnLoaded;
    }
    void OnLoaded(object sender, RoutedEventArgs e)
    {
      var gridVisual = ElementCompositionPreview.GetElementVisual(this.grid);

      var compositor = gridVisual.Compositor;

      this.pointLight = compositor.CreatePointLight();
      this.pointLight.CoordinateSpace = gridVisual;
      this.pointLight.Color = Colors.Yellow;
      this.pointLight.Offset = new Vector3(
          (float)this.grid.ActualWidth / 2,
          (float)this.grid.ActualHeight / 2,
          50);

      this.pointLight.Targets.Add(gridVisual);
    }
    PointLight pointLight;
  }
}

and all I had to do was promote the PointLight variable to be a member of my Page and life is good and the light does what I expect it to.

Now, to be honest, I’ve hit this type of issue working with the composition APIs before and so I should have expected it and fixed my code but I think my intuitive expectation was that having created a light and handed it ‘to the system’ I’d expect the system to keep hold of it rather than asking me to keep hold of it.

Maybe that expectation comes from me applying XAML-like ‘retained graphics’ thinking that doesn’t necessarily apply here and this is a slight odd scenario because;

  • I ask the Compositor to create the PointLight
  • I ask the light to target a Visual
  • I don’t have to ‘insert’ the light into any kind of scene or anything like that

and so I hadn’t assumed that I was the owner of the PointLight and needed to keep it around although it’s worth saying that the PointLight is disposable so maybe that should have made it clear that the ownership lives with me as a consumer of the light.

That’s my learning for this post Smile

In looking around this area of ownership, I did spot that others are asking questions around object lifetimes and disposing of some of these pieces so it’s something that docs/guides could perhaps do more to help users of the APIs here understand how the lifetimes are meant to work;

image

but at least on this simplest of samples I got resolution as to why my code didn’t work when the sample code did!