CompositionProToolkit v0.5.0 Holiday Edition released!

After a long gap, I am back with another update to CompositionProToolkit. This time I have added a few helper classes for the Win2d project.

CanvasPathBuilder extension methods

CanvasPathBuilder allows you to create a freeform path using lines, arcs, Quadratic Beziers and Cubic Beziers. You can then convert this path to a CanvasGeometry. Each path is composed of one or more figures. Each figure definition is encapsulated by the BeginFigure() and EndFigure() methods of CanvasPathBuilder.

If you want to add a circle(or ellipse) or a polygon figure to your path, you need to break the figure into curves or line segments and add them to the path one by one.

I have added the following extension methods to the CanvasPathBuilder to add a circle, ellipse or a polygon figure directly to your path

public static void AddCircleFigure (CanvasPathBuilder pathBuilder, Vector2 center, float radius);
public static void AddCircleFigure (CanvasPathBuilder pathBuilder, float x, float y, float radius);
public static void AddEllipseFigure(CanvasPathBuilder pathBuilder, Vector2 center, float radiusX, float radiusY);
public static void AddEllipseFigure(CanvasPathBuilder pathBuilder, float x, float y, float radiusX, float radiusY);
public static void AddPolygonFigure(CanvasPathBuilder pathBuilder, int numSides, Vector2 center, float radius);
public static void AddPolygonFigure(CanvasPathBuilder pathBuilder, int numSides, float x, float y, float radius);

In the AddPolygonFigure, the radius parameter indicates the distance between the center of the polygon and its vertices.

Note: These methods add the required curves or line segments to your path internally. Since these methods add a figure to your path, you can invoke them only after closing the current figure in the path. They must not be called in between BeginFigure() and EndFigure() calls, otherwise an ArgumentException will be raised. These extension methods call the BeginFigure() and EndFigure() CanvasPathBuilder methods internally.

CanvasGeometryParser

Last month, while working on my new UWP app, I was using Win2d extensively and found out that in Win2d there was no support for the Path Mini Langugage which is quite popular in WPF/Silverlight. It is a powerful and complex mini-language which you can use to specify path geometries more compactly using Extensible Application Markup Language (XAML). It is derived mainly from the SVG (Scalable Vector Graphics) Path language specification. Here is an example

    M8.64,223.948c0,0,143.468,3.431,185.777-181.808c2.673-11.702-1.23-20.154,1.316-33.146h16.287c0,0-3.14,17.248,1.095,30.848c21.392,68.692-4.179,242.343-204.227,196.59L8.64,223.948z

So I added the CanvasGeometryParser class which parses the above string and converts it into appropriate CanvasPathBuilder commands. It contains the following static methods

public static CanvasGeometry Parse(ICanvasResourceCreator resourceCreator, System.String pathData, StringBuilder logger = null);

The logger parameter in this method is an option argument of type StringBuilder which can be used to obtain the CanvasPathBuilder commands in text format. It is mainly intended for information/debugging purpose only.

Here is an example usage of the CanvasGeometryParser

private void OnCanvasDraw(CanvasControl sender, CanvasDrawEventArgs args)
{
    string data = "M8.64,223.948c0,0,143.468,3.431,185.777-181.808c2.673-11.702-1.23-20.154," + 
        "1.316-33.146h16.287c0,0-3.14,17.248,1.095,30.848c21.392,68.692-4.179,242.343-204.227,196.59L8.64,223.948z";
    var geometry = CanvasGeometryParser.Parse(sender, data);

    args.DrawingSession.FillGeometry(geometry, Colors.Yellow);
    args.DrawingSession.DrawGeometry(geometry, Colors.Black, 2f);
}

Check out the Sample Gallery project in GitHub where you can interact with the CanvasGeometryParser by providing the SVG/XAML path data and converting it to CanvasGeometry. You can alter the StrokeThickness, StrokeColor and FillColor of the rendered geometry.

canvasgeometryparser

You can view the CanvasPathBuilder commands called to create the parsed geometry.

CanvasGeometryParser_cmds.jpg

Based on the SVG (Scalable Vector Graphics) Path language specification, the following rules must be followed to create the path data

  • All instructions are expressed as one character (e.g., a moveto is expressed as an M).
  • Superfluous white space and separators such as commas can be eliminated (e.g., M 100 100 L 200 200 contains unnecessary spaces and could be expressed more compactly as M100 100L200 200).
  • The command letter can be eliminated on subsequent commands if the same command is used multiple times in a row (e.g., you can drop the second “L” in M 100 200 L 200 100 L -100 -200 and use M 100 200 L 200 100 -100 -200 instead).
  • Relative versions of all commands are available (uppercase means absolute coordinates, lowercase means relative coordinates).

In the table below, the following notation is used:

() indicates grouping of parameters.

+ indicates 1 or more of the given parameter(s) is required.

Command Command Letter Parameters Remarks
MoveTo M (x y)+ Starts a new sub-path at the given (x,y) coordinate. If a moveto is followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit lineto commands.
ClosePath Z none Closes the current subpath by drawing a straight line from the current point to current subpath’s initial point.
LineTo L (x y)+ Draws a line from the current point to the given (x,y) coordinate which becomes the new current point.
HorizontalLineTo H (x)+ Draws a horizontal line from the current point (cpx, cpy) to (x, cpy).
VerticalLineTo V (y)+ Draws a vertical line from the current point (cpx, cpy) to (cpx, y).
CubicBezier C (x1 y1 x2 y2 x y)+ Draws a cubic Bézier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of the curve and (x2,y2) as the control point at the end of the curve.
SmoothCubicBezier S (x2 y2 x y)+ Draws a cubic Bézier curve from the current point to (x,y). The first control point is assumed to be the reflection of the second control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not an C, c, S or s, assume the first control point is coincident with the current point.)
QuadraticBezier Q (x1 y1 x y)+ Draws a quadratic Bézier curve from the current point to (x,y) using (x1,y1) as the control point.
SmoothQuadraticBezier T (x y)+ Draws a quadratic Bézier curve from the current point to (x,y). The control point is assumed to be the reflection of the control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not a Q, q, T or t, assume the control point is coincident with the current point.)
Arc A (radiusX radiusY angle isLargeFlag SweepDirection x y)+ Draws an elliptical arc from the current point to (x, y).
EllipseFigure O (radiusX radiusY x y)+ Adds an Ellipse Figure to the path. The current point remains unchanged.
PolygonFigure P (numSides radius x y)+ Adds an n-sided Polygon Figure to the path. The current point remains unchanged.

The latest code is available in GitHub and the Nuget package is available here.

Happy Holidays! 🙂

CompositionProToolkit v0.4.6 released

Another update to CompositionProToolkit this week with couple of feature additions to ImageFrame and some bug fixes.

ImageFrame

Optimized Shadow

ImageFrame now provides a new dependency property called OptimizeShadow which allows multiple ImageFrame instances to share the same DropShadow instance. You can set this property to True when you are displaying several ImageFrame instances within a single container and each ImageFrame instance has shadow enabled. This will reduce the memory footprint.

Dependency Property Type Description Default Value
OptimizeShadow Boolean Indicates whether the ImageFrame should use a shared shadow object to display the shadow. False

IDisposable

ImageFrame now implements the IDisposable interface and thus provides a Dispose method to free up resources. ImageFrame internally uses several Composition objects which must be disposed to optimize the memory usage within your app.

Guidelines for effectively disposing ImageFrame

Consider a scenario where you are displaying several ImageFrame instances in a GridView within a page. When the app navigates away from the page, then you must dispose the ImageFrame instances like this

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    foreach (var imgFrame in ItemGridView.GetDescendantsOfType())
    {
        imgFrame.Dispose();
    }    
    VisualTreeHelper.DisconnectChildrenRecursive(ItemGridView);
    ItemGridView.ItemsSource = null;
    ItemGridView.Items?.Clear();

    base.OnNavigatedFrom(e);
}

Frosted Glass Effect Brush

A new extension method CreateFrostedGlassBrush has been added to Compositor which, as the name suggests, allows you to create a custom shaped brush which gives a frosted glass effect. The main difference between this method and the CreateMaskedBackdropBrush is that when you apply the FrostedGlassBrush to a visual with a DropShadow, it will look better, whereas with the MaskedBackdropBrush, the shadow will darken the visual.

FrostedGlassEffect.png

You can obtain the mask from the FrostedGlass effect brush, to apply to the DropShadow, in the following way

var roundRectGeometry = CanvasGeometry.CreateRoundedRectangle(_generator.Device, 
    0, 0, _width, _height, 25, 25);
var maskSurface = _generator.CreateMaskSurface(visual.Size.ToSize(),
     roundRectGeometry);
var frostedBrush = _compositor.CreateFrostedGlassBrush(maskSurface,
     Colors.AntiqueWhite, 30f, _backdropBrush);

var shadow = _compositor.CreateDropShadow();
shadow.Opacity = 0.5f;
shadow.Color = Colors.Black;
shadow.Offset = new Vector3(10, 10, 0);
shadow.BlurRadius = 15;

// Apply the mask to the shadow
shadow.Mask = frostedBrush.GetSourceParameter("mask");

visual.Brush = frostedBrush;
visual.Shadow = shadow;

The FrostedGlass effect brush was inspired from this blog post.

The latest source code is available in GitHub and the NuGet package is available here.

CompositionProToolkit v0.4.5 released!

The past few releases were mostly dedicated to refactoring and ImageFrame. CompositionProToolkit v0.4.5 continues the tradition and brings in new additions to code and a few new features to the ImageFrame control.

CompositionProToolkit.Expressions

cpte_banner.png

Well, this task was pending for a long time! CompositionExpressionToolkit code now has been merged into CompositionProToolkit under the CompositionProToolkit.Expressions namespace. If you have not used the CompositionExpressionToolkit project before you can find out more more details about CompositionProToolkit.Expressions here.

ImageFrame

In this release, ImageFrame has got a few feature modifications and additions.

ImageFrame Source

The Source property of ImageFrame is of now of type object and it can accept the following types

  • Uri
  • String (from which a Uri can be successfully created)
  • StorageFile
  • IRandomAccessStream

Image Caching

Image caching is permanently enabled now. ImageFrame will internally cache the objects provided to Source property. The cache is located in the temporary folder of the application using the ImageFrame.

As a result, the following property has been deprecated and removed from ImageFrame

  • UseImageCache

You can clear the cache anytime you want by using the following code

await ImageCache.ClearCacheAsync();

ImageFrame Transitions

CPTT_1.gif

ImageFrame provides several transition animations while displaying the newly loaded image. You can configure which animation to run by setting the TransitionMode property of the imageFrame.

Dependency Property Type Description Default Value
TransitionMode TransitionModeType Indicates the type of transition animation to employ for displaying an image after it has been loaded. TransitionModeType.FadeIn

TransitionMode property can be set to any of the following values defined in the TransitionModeType enumeration

  • FadeIn – The newly loaded image fades into view.
  • SlideLeft – The newly loaded image slides into view from the right side of the ImageFrame and moves left.
  • SlideRight – The newly loaded image slides into view from the left side of the ImageFrame and moves right.
  • SlideUp – The newly loaded image slides into view from the bottom of the ImageFrame and moves up.
  • SlideDown – The newly loaded image slides into view from the top of the ImageFrame and moves down.
  • ZoomIn – The newly loaded image zooms into view from the center of the ImageFrame.

ImageFrame Placeholder

The ShowPlaceholder property is now set to True by default.

Latest source code is available in GitHub and Nuget package is available here.

CompositionProToolkit v0.4.4 released

Though CompositionProToolkit v0.4.4 was initially planned to be a small update aimed at fixing bugs and improving the user experience of the CompositionImageFrame, it turned out to be a larger update, ultimately requiring one of the oldest class in CompositionProToolkit to be refactored. Midway between the first phase of refactoring, I came up with another idea which led to the whole refactored code being discarded. I had to restart the refactoring from scratch and the final code appears to be much more streamlined than it was earlier. Another reason for refactoring was to shorten the names of the classes. Adding Composition to each of the classes resulted in very long names (CompositionSurfaceImageOptions for example).

Unfortunately, this refactoring led to some breaking changes again! But let me assure you, the pains that you will take to accommodate these breaking changes in your existing code will save a lot of headaches in the future.

Without much ado, let us delve into the details.

Breaking Changes

ICompositionMask

Of late, due to ever increasing requirements, I was adding more features to ICompositionMask which resulted in the class getting bloated. This class was playing a dual role – One, as the building block for creating a CompositionMaskBrush to render custom shaped visuals. Two, as the building block for creating a CompositionSurfaceBrush for rendering custom shaped geometries onto visuals.

Addition of new capabilities in ICompositionMask also introduced several flags in order to differentiate the two behaviors. It was high time to split them into two three interfaces –

  • IRenderSurface – This interface acts as the base interface for interfaces which render to the ICompositionSurface. It mainly contains references to an ICompositionGenerator object and an ICompositionSurface object which are the core objects required for rendering any geometry or image onto a ICompositionSurface.
  • IMaskSurface – This interface is used for rendering custom shaped geometries onto ICompositionSurface so that they can be useds as masks on Composition Visuals.
  • IGeometrySurface – This interface is used for rendering custom shaped geometries onto ICompositionSurface.

Both IMaskSurface and IGeometrySurface derive from IRenderSurface. Here is the interface hierarchy

RenderSurfaces

ICompositionSurfaceImage

If you look at the interface hierarchy image above, you will notice a fourth interface mentioned there – IImageSurface. It is actually the ICompositionSurfaceImage interface which has been refactored.

CompositionGenerator

CompositionGenerator‘s CreateMask APIs have been refactored into separate APIs for creating the three different types of render surfaces

IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry);
IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, 
    Color foregroundColor);
IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, 
    Color foregroundColor, Color backgroundColor);
IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, 
    ICanvasBrush foregroundBrush);
IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, 
    ICanvasBrush foregroundBrush, ICanvasBrush backgroundBrush);
IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, 
    ICanvasBrush foregroundBrush, Color backgroundColor);
IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, 
    Color foregroundColor, ICanvasBrush backgroundBrush);
Task CreateImageSurfaceAsync(Uri uri, Size size, 
    ImageSurfaceOptions options);

CompositionImageFrame

CompositionImageFrame has been renamed to ImageFrame.

CompositionSurfaceImageOptions

The class with the longest name in CompositionProToolkit has now been renamed to ImageSurfaceOptions.

What’s new in CompositionProToolkit v0.4.4?

ImageFrame has been refactored with a better logical workflow. It has resulted in a better user experience. If you do not provide a definite Width and Height values to the ImageFrame, it will now size itself based on the loaded image and the parent control hosting the ImageFrame.

A new property RenderFast has been added to ImageFrame which gives you the option to turn off the animations which are used while rendering the image. This property is set to False by default. You can turn it on in scenarios where the Source property of the ImageFrame is being rapidly updated. For example, consider a ListBox containing numerous ImageFrames which is being scrolled very fast.

Property Type Description Default value
RenderFast Boolean Indicates whether the animations need to be switched off if the ImageFrame is being used in scenarios where it is being rapidly updated with new Source. False

NOTE: Do not confuse the RenderFast property with the RenderOptimized property. The former is used to turn off the animations during rendering, while the latter is used to reduces the memory footprint of the ImageFrame.

The latest source is available in GitHub and the Nuget package is available here.

CompositionProToolkit v0.4.3 released!

Another busy week and I feel thrilled to announce the release of CompositionProToolkit v0.4.3. It mainly contains feature additions to CompositionImageFrame and some minor refactoring (no breaking changes!). Let’s delve into the details.

CompositionGeneratorFactory

CompositionGeneratorFactory APIs have been simplified further. Now there are two ways to obtain the CompositionGenerator – by providing a Compositor or by providing a CompositionGraphicDevice.

public static ICompositionGenerator GetCompositionGenerator(Compositor compositor,
    bool useSharedCanvasDevice = true, bool useSoftwareRenderer = false);
public static ICompositionGenerator GetCompositionGenerator(
    CompositionGraphicsDevice graphicsDevice);

The first API also has couple of optional parameters

  • useSharedCanvasDevice – indicates whether the CompositionGenerator should use a shared CanvasDevice or creates a new one.
  • useSoftwareRenderer – this parameter is provided as a argument when creating a new CanvasDevice (i.e. when usedSharedCanvasDevice is false).

ICompositionMask

Two new APIs have been added in ICompositionMask class which allow the redraw of the mask with a new Color or ICanvasBrush.

void Redraw(ICanvasBrush brush);
void Redraw(Color color);

CompositionImageFrame

CompositionImageFrame has received most attention in this release. Two of the most requested features – Placeholder and Image Caching, have now been incorporated into CompositionImageFrame. Also now whenever the AlignX or AlignY changes, the image animates to its new location.

When the image is being (cached and) loaded, the placeholder shows a progress bar which indicates the load progress.

Placeholder_progress

The following new properties have been added to CompositionImageFrame to configure the Placeholder and the Image Cache features.

Property Type Description Default value
ShowPlaceHolder Boolean Indicates whether the placeholder needs to be displayed during image load or when no image is loaded in the CompositionImageFrame. False
PlaceholderBackground Color Indicates the background color of the Placeholder. Colors.Black
PlaceholderColor Color Indicates the color with which the rendered placeholder geometry should be filled RGB(192, 192, 192)
UseImageCache Boolean Indicates whether the images should be cached before rendering them. True

CPT_8_1.gif

Using CompositionImageFrame with FilePicker

If you have a CompostionImageFrame control in you application and your want to use the FilePicker to select an image file to be displayed on the CompostionImageFrame, then you must do the following

var picker = new Windows.Storage.Pickers.FileOpenPicker
{
    ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail,
    SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary
};
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
var file = await picker.PickSingleFileAsync();
ImageFrame.Source = await ImageCache.GetCachedUriAsync(file);

Since the CompositionImageFrame‘s Source property expects a Uri, while the FilePicker provides a StorageFile. So in order to obtain a Uri from the StorageFile, you must first cache it using the ImageCache.GetCachedUriAsync() method.

The latest source code is available in GitHub and NuGet package is available here.

CompositionProToolkit v0.4.2 released


Well, the last week has been pretty busy – learning little more details about the Composition APIs, major refactoring of the CompositionProToolkit code, breaking changes and adding new features and controls. The hard work finally paid off. I am excited to announce the release of CompositionProToolkit v0.4.2. Let’s see, in detail, what this new version contains.

Breaking Changes

First and foremost, you would like to know what will not work if you move to version 0.4.2. After digging deeper into the various classes within the Windows.UI.Composition namespace, I realized that before introducing new features and controls, it was high time I refactored my code. Thus I began – optimizing various classes, removing lot of redundant Task.Run(…)* encapsulations. As a result, many APIs which were earlier asynchronous are now synchronous (you no longer need to await them!). The main advantages are improved execution speed and more robust code. 🙂

Here are some of the classes whose APIs have changed. If you are using them within their code you will have to update them to the new API calls.

CompositionGeneratorFactory

CompositionGeneratorFactory no longer requires a sharedLock parameter while obtaining the CompositionGenerator. The lock is now managed internally within each CompositionSurfaceImage. Since this was an optional argument in the GetCompositionGenerator API, if you were not providing this argument in your code the your code need not be changed.

v0.4.1

public static ICompositionGenerator GetCompositionGenerator(Compositor compositor, 
    CompositionGraphicsDevice graphicsDevice=null, object sharedLock=null);

v0.4.2

public static ICompositionGenerator GetCompositionGenerator(Compositor compositor, 
    CompositionGraphicsDevice graphicsDevice=null);

ICompositionMask

All the asynchronous APIs in ICompositionMask class have been refactored into synchronous APIs.

v0.4.1

Task RedrawAsync();
Task RedrawAsync(Geometry.CanvasGeometry geometry);
Task RedrawAsync(Size size, Geometry.CanvasGeometry geometry);
Task RedrawAsync(Size size, Geometry.CanvasGeometry geometry, ICanvasBrush brush);
Task RedrawAsync(Size size, Geometry.CanvasGeometry geometry, Color color);
Task ResizeAsync(Size size);

v0.4.2

void Redraw();
void Redraw(Geometry.CanvasGeometry geometry);
void Redraw(Size size, Geometry.CanvasGeometry geometry);
void Redraw(Size size, Geometry.CanvasGeometry geometry, ICanvasBrush brush);
void Redraw(Size size, Geometry.CanvasGeometry geometry, Color color);
void Resize(Size size);

ICompositionSurfaceImage

A few of the asynchronous APIs in ICompositionSurfaceImage class have been refactored into synchronous APIs.

v0.4.1

Task RedrawAsync(CompositionSurfaceImageOptions options);
Task ResizeAsync(Size size);
Task ResizeAsync(Size size, CompositionSurfaceImageOptions options);

v0.4.2

void Redraw(CompositionSurfaceImageOptions options);
void Resize(Size size);
void Resize(Size size, CompositionSurfaceImageOptions options);

ICompositionGenerator

All the asynchronous APIs in ICompositionGenerator related to creating of ICompositionMask and visual Reflection have been refactored into synchronous APIs.

v0.4.1

Task CreateMaskAsync(Size size, CanvasGeometry geometry);
Task CreateMaskAsync(Size size, CanvasGeometry geometry, ICanvasBrush brush);
Task CreateMaskAsync(Size size, CanvasGeometry geometry, Color color);
Task CreateReflectionAsync(ContainerVisual visual, float reflectionDistance, 
    float reflectionLength, ReflectionLocation location);

v0.4.2

ICompositionMask CreateMask(Size size, CanvasGeometry geometry);
ICompositionMask CreateMask(Size size, CanvasGeometry geometry, ICanvasBrush brush);
ICompositionMask CreateMask(Size size, CanvasGeometry geometry, Color color);
void CreateReflection(ContainerVisual visual, float reflectionDistance, 
    float reflectionLength, ReflectionLocation location));

So what’s new in v0.4.2?

Now that we are done with the breaking changes, let’s look what all new features and controls have been added to CompositionProToolkit v0.4.2.

CompositionSurfaceImageOptions

CompositionSurfaceImageOptions now has an additional property AutoResize which can be set to False when you are trying to render a large image onto the CompositionSurfaceImage as a thumbnail. This will optimize memory usage.

Property Type Description Default value
AutoResize Boolean Specifies whether the CompositionSurfaceImage should resize itself automatically to match the loaded image size. When set to True, the Stretch, HorizontalAlignment and VerticalAlignment options are ignored. False

CompositionImageFrame

CompositionImageFrame now provides a fade in animation while transitioning from one image to another. It also supports rounded corners and display of shadows which can be configured easily. It also allows an option to optimize the rendering of the image. This is useful for scenarios where you are trying to render a large image to a smaller size, for example thumbnails.

CPT6.gif

The following new properties have been added to CompositionImageFrame

Property Type Description Default value
CornerRadius CornerRadius Indicates the corner radius of the the ImageFrame. The image will be rendered with rounded corners. (0, 0, 0, 0)
DisplayShadow Boolean Indicates whether the shadow for this image should be displayed. False
RenderOptimized Boolean Indicates whether optimization must be used to render the image.Set this property to True if the CompositionImageFrame is very small compared to the actual image size. This will optimize memory usage. False
ShadowBlurRadius Double Specifies the Blur radius of the shadow. 0.0
ShadowColor Color Specifies the color of the shadow. Transparent
ShadowOffsetX Double Specifies the horizontal offset of the shadow. 0.0
ShadowOffsetY Double Specifies the vertical offset of the shadow. 0.0
ShadowOpacity Double Specifies the opacity of the shadow. 1
TransitionDuration Double Indicates the duration of the crossfade animation while transitioning from one image to another. 700ms

FluidBanner

FluidBanner is now a part of the CompositionProToolkit. It now internally uses CompositionSurfaceImage to host the images. It provides the following properties which can be used to customize the FluidBanner.

Dependency Property Type Description Default Value
AlignX AlignmentX Indicates how the image is positioned horizontally in the FluidBanner items. Center
AlignY AlignmentY Indicates how the image is positioned vertically in the FluidBanner items. Center
DecodeHeight int The height, in pixels, that the images are decoded to. (Optional) 0
DecodeWidth int The width, in pixels, that the images are decoded to. (Optional) 0
ItemBackground Color The background color of each item in the FluidBanner Black
ItemGap double The gap between adjacent items in the banner. 30
ItemsSource IEnumerable<Uri> The collection of Uris of images to be shown in the FluidBanner null
Padding Thickness The padding inside the FluidBanner Thickness(0)
Stretch Stretch Indicates how the image is resized to fill its allocated space within each FluidBanner item. Uniform

The latest source code is available in GitHub. The Nuget package is available here

CompositionProToolkit v0.4.1 released

Compared to the large number of features in CompositionProToolkit v0.4, version 0.4.1 incorporates the CompositionImageFrame control and code optimizations.

If you want to know more about the new features added to CompositionProToolkit v0.4 check my previous post.

CompositionImageFrame

CompositionImageFrame is a control which can be used for displaying images. It encapsulates a CompositionSurfaceImage object which is used for loading and rendering the images. It also supports Pointer interactions and raises events accordingly.

In order to configure the rendering of the image, CompositionImageFrame has the following properties

Dependency Property Type Description Default Value
AlignX AlignmentX Specifies how the image is positioned horizontally in the CompositionImageFrame. AlignmentX.Center
AlignY AlignmentY Specifies how the image is positioned vertically in the CompositionImageFrame. AlignmentY.Center
FrameBackground Color Specifies the background color of the CompositionImageFrame to fill the area where image is not rendered. Colors.Black
Interpolation CanvasImageInterpolation Specifies the interpolation used for rendering the image. HighQualityCubic
Source Uri Specifies the Uri of the image to be loaded into the CompositionImageFrame. null
Stretch Stretch Specifies how the image is resized to fill its allocated space in the CompositionImageFrame. Uniform

CompositionImageFrame raises the following events

  • ImageOpened – when the image has been successfully loaded from the Uri and rendered.
  • ImageFailed – when there is an error loading the image from the Uri.

CompositionProToolkit v0.4.1 is now available in NuGet. Source code is available in GitHub.

If you want to see the various controls and features of CompositionProToolkit in action, check out the SampleGallery project in GitHub.