From 0c4d2d95299ab375bedd4b45f279dfeb7605c83a Mon Sep 17 00:00:00 2001
From: 0x5BFA <62196528+0x5bfa@users.noreply.github.com>
Date: Tue, 14 Jul 2026 19:05:40 +0900
Subject: [PATCH] Init
---
.../SampleSupport/Data/ControlInfoData.json | 33 ++++
.../CompositionBasicsChildVisual.txt | 33 ++++
.../CompositionBasicsClip.txt | 26 +++
.../CompositionBasicsGetElementVisual.txt | 32 ++++
.../CompositionBasicsPage.xaml | 175 +++++++++++++++++
.../CompositionBasicsPage.xaml.cs | 180 ++++++++++++++++++
.../CompositionBasicsTransformMatrix.txt | 25 +++
7 files changed, 504 insertions(+)
create mode 100644 WinUIGallery/Samples/CompositionBasics/CompositionBasicsChildVisual.txt
create mode 100644 WinUIGallery/Samples/CompositionBasics/CompositionBasicsClip.txt
create mode 100644 WinUIGallery/Samples/CompositionBasics/CompositionBasicsGetElementVisual.txt
create mode 100644 WinUIGallery/Samples/CompositionBasics/CompositionBasicsPage.xaml
create mode 100644 WinUIGallery/Samples/CompositionBasics/CompositionBasicsPage.xaml.cs
create mode 100644 WinUIGallery/Samples/CompositionBasics/CompositionBasicsTransformMatrix.txt
diff --git a/WinUIGallery/SampleSupport/Data/ControlInfoData.json b/WinUIGallery/SampleSupport/Data/ControlInfoData.json
index 681e0569f..feb070d32 100644
--- a/WinUIGallery/SampleSupport/Data/ControlInfoData.json
+++ b/WinUIGallery/SampleSupport/Data/ControlInfoData.json
@@ -3799,6 +3799,39 @@
}
]
},
+ {
+ "UniqueId": "Composition",
+ "Title": "Composition",
+ "IconGlyph": "\uE81E",
+ "Items": [
+ {
+ "UniqueId": "CompositionBasics",
+ "Title": "Basics",
+ "ApiNamespace": "Microsoft.UI.Composition",
+ "Subtitle": "Connect XAML elements to the Visual layer and apply fundamental transforms and clips.",
+ "ImagePath": "ms-appx:///Assets/ControlImages/AnimationInterop.png",
+ "Description": "Learn the foundations of XAML and Composition interop by retrieving and attaching visuals, working with coordinate systems, applying transform matrices, and clipping content.",
+ "IsNew": true,
+ "Docs": [
+ {
+ "Title": "Composition overview",
+ "Uri": "https://learn.microsoft.com/windows/apps/windows-app-sdk/composition"
+ },
+ {
+ "Title": "ElementCompositionPreview - API",
+ "Uri": "https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.hosting.elementcompositionpreview"
+ },
+ {
+ "Title": "Visual - API",
+ "Uri": "https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.composition.visual"
+ }
+ ],
+ "RelatedControls": [
+ "XamlCompInterop"
+ ]
+ }
+ ]
+ },
{
"UniqueId": "Motion",
"Title": "Motion",
diff --git a/WinUIGallery/Samples/CompositionBasics/CompositionBasicsChildVisual.txt b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsChildVisual.txt
new file mode 100644
index 000000000..9c4f3ee47
--- /dev/null
+++ b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsChildVisual.txt
@@ -0,0 +1,33 @@
+--- header
+Attach a Composition child Visual and position it with AnchorPoint
+--- xaml
+
+--- c#
+private SpriteVisual? _childVisual;
+
+private void ChildVisualExample_Loaded(object sender, RoutedEventArgs e)
+{
+ Visual hostVisual = ElementCompositionPreview.GetElementVisual(ChildVisualHost);
+ _childVisual = hostVisual.Compositor.CreateSpriteVisual();
+ _childVisual.Size = new Vector2(80);
+ _childVisual.Brush = hostVisual.Compositor.CreateColorBrush(Colors.DodgerBlue);
+
+ ElementCompositionPreview.SetElementChildVisual(ChildVisualHost, _childVisual);
+ UpdateChildVisual();
+}
+
+private void UpdateChildVisual()
+{
+ // AnchorPoint is normalized: (0,0) is the top-left and (1,1) is the bottom-right.
+ _childVisual.AnchorPoint = new Vector2(anchorX, anchorY);
+ _childVisual.Offset = new Vector3(ChildVisualHost.ActualSize / 2, 0);
+}
+
+private void Page_Unloaded(object sender, RoutedEventArgs e)
+{
+ ElementCompositionPreview.SetElementChildVisual(ChildVisualHost, null);
+ _childVisual?.Dispose();
+}
diff --git a/WinUIGallery/Samples/CompositionBasics/CompositionBasicsClip.txt b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsClip.txt
new file mode 100644
index 000000000..f7defa3e0
--- /dev/null
+++ b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsClip.txt
@@ -0,0 +1,26 @@
+--- header
+Clip a XAML element through its Composition Visual
+--- xaml
+
+
+
+--- c#
+private InsetClip? _insetClip;
+
+private void ClipExample_Loaded(object sender, RoutedEventArgs e)
+{
+ Visual visual = ElementCompositionPreview.GetElementVisual(ClipTarget);
+ _insetClip = visual.Compositor.CreateInsetClip();
+ visual.Clip = _insetClip;
+}
+
+private void UpdateClip(float horizontalInset, float verticalInset)
+{
+ _insetClip.LeftInset = horizontalInset;
+ _insetClip.RightInset = horizontalInset;
+ _insetClip.TopInset = verticalInset;
+ _insetClip.BottomInset = verticalInset;
+}
diff --git a/WinUIGallery/Samples/CompositionBasics/CompositionBasicsGetElementVisual.txt b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsGetElementVisual.txt
new file mode 100644
index 000000000..ea8910e25
--- /dev/null
+++ b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsGetElementVisual.txt
@@ -0,0 +1,32 @@
+--- header
+Get and transform the Visual backing a XAML element
+--- xaml
+
+
+
+--- c#
+private Visual? _elementVisual;
+
+private void ElementVisualExample_Loaded(object sender, RoutedEventArgs e)
+{
+ _elementVisual = ElementCompositionPreview.GetElementVisual(ElementVisualTarget);
+ UpdateVisual();
+}
+
+private void UpdateVisual()
+{
+ if (_elementVisual is null)
+ {
+ return;
+ }
+
+ // CenterPoint uses pixels in the Visual's coordinate space.
+ _elementVisual.CenterPoint = new Vector3(ElementVisualTarget.ActualSize / 2, 0);
+ // Translation is also exposed directly on UIElement as a Composition facade.
+ ElementVisualTarget.Translation = new Vector3(translationX, translationY, 0);
+ _elementVisual.RotationAngleInDegrees = rotation;
+}
diff --git a/WinUIGallery/Samples/CompositionBasics/CompositionBasicsPage.xaml b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsPage.xaml
new file mode 100644
index 000000000..2d2e54f43
--- /dev/null
+++ b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsPage.xaml
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WinUIGallery/Samples/CompositionBasics/CompositionBasicsPage.xaml.cs b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsPage.xaml.cs
new file mode 100644
index 000000000..1e0499494
--- /dev/null
+++ b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsPage.xaml.cs
@@ -0,0 +1,180 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using Microsoft.UI.Composition;
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Xaml.Hosting;
+using System;
+using System.Numerics;
+
+namespace WinUIGallery.ControlPages;
+
+public sealed partial class CompositionBasicsPage : Page
+{
+ private Visual? _elementVisual;
+ private SpriteVisual? _childVisual;
+ private Visual? _transformMatrixVisual;
+ private InsetClip? _insetClip;
+
+ public CompositionBasicsPage()
+ {
+ InitializeComponent();
+ Unloaded += CompositionBasicsPage_Unloaded;
+ }
+
+ private void ElementVisualExample_Loaded(object sender, RoutedEventArgs e)
+ {
+ _elementVisual = ElementCompositionPreview.GetElementVisual(ElementVisualTarget);
+ UpdateElementVisualCenterPoint();
+ UpdateElementVisualTransform();
+ }
+
+ private void ElementVisualTarget_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ UpdateElementVisualCenterPoint();
+ }
+
+ private void ElementVisualTransform_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
+ {
+ UpdateElementVisualTransform();
+ }
+
+ private void UpdateElementVisualCenterPoint()
+ {
+ if (_elementVisual is null)
+ {
+ return;
+ }
+
+ _elementVisual.CenterPoint = new Vector3(ElementVisualTarget.ActualSize / 2, 0);
+ }
+
+ private void UpdateElementVisualTransform()
+ {
+ if (_elementVisual is null)
+ {
+ return;
+ }
+
+ ElementVisualTarget.Translation = new Vector3(
+ (float)TranslationXSlider.Value,
+ (float)TranslationYSlider.Value,
+ 0);
+ _elementVisual.RotationAngleInDegrees = (float)RotationSlider.Value;
+ }
+
+ private void ChildVisualExample_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (_childVisual is null)
+ {
+ Compositor compositor = ElementCompositionPreview.GetElementVisual(ChildVisualHost).Compositor;
+ _childVisual = compositor.CreateSpriteVisual();
+ _childVisual.Size = new Vector2(80);
+ _childVisual.Brush = compositor.CreateColorBrush(Windows.UI.Color.FromArgb(255, 0, 120, 212));
+ ElementCompositionPreview.SetElementChildVisual(ChildVisualHost, _childVisual);
+ }
+
+ UpdateChildVisual();
+ }
+
+ private void ChildVisualHost_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ UpdateChildVisual();
+ }
+
+ private void AnchorPointSlider_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
+ {
+ UpdateChildVisual();
+ }
+
+ private void UpdateChildVisual()
+ {
+ if (_childVisual is null)
+ {
+ return;
+ }
+
+ _childVisual.AnchorPoint = new Vector2(
+ (float)AnchorXSlider.Value,
+ (float)AnchorYSlider.Value);
+ _childVisual.Offset = new Vector3(ChildVisualHost.ActualSize / 2, 0);
+ }
+
+ private void TransformMatrixExample_Loaded(object sender, RoutedEventArgs e)
+ {
+ _transformMatrixVisual = ElementCompositionPreview.GetElementVisual(TransformMatrixTarget);
+ UpdateTransformMatrixCenterPoint();
+ UpdateTransformMatrix();
+ }
+
+ private void TransformMatrixTarget_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ UpdateTransformMatrixCenterPoint();
+ }
+
+ private void TransformMatrixSlider_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
+ {
+ UpdateTransformMatrix();
+ }
+
+ private void UpdateTransformMatrixCenterPoint()
+ {
+ if (_transformMatrixVisual is null)
+ {
+ return;
+ }
+
+ _transformMatrixVisual.CenterPoint = new Vector3(TransformMatrixTarget.ActualSize / 2, 0);
+ }
+
+ private void UpdateTransformMatrix()
+ {
+ if (_transformMatrixVisual is null)
+ {
+ return;
+ }
+
+ float skewRadians = (float)(SkewXSlider.Value * Math.PI / 180);
+ Matrix4x4 skewMatrix = Matrix4x4.Identity;
+ skewMatrix.M21 = MathF.Tan(skewRadians);
+ _transformMatrixVisual.TransformMatrix =
+ Matrix4x4.CreateScale((float)ScaleXSlider.Value, 1, 1) *
+ skewMatrix;
+ }
+
+ private void ClipExample_Loaded(object sender, RoutedEventArgs e)
+ {
+ Visual visual = ElementCompositionPreview.GetElementVisual(ClipTarget);
+ _insetClip ??= visual.Compositor.CreateInsetClip();
+ visual.Clip = _insetClip;
+ UpdateClip();
+ }
+
+ private void ClipSlider_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
+ {
+ UpdateClip();
+ }
+
+ private void UpdateClip()
+ {
+ if (_insetClip is null)
+ {
+ return;
+ }
+
+ float horizontalInset = (float)HorizontalClipSlider.Value;
+ float verticalInset = (float)VerticalClipSlider.Value;
+ _insetClip.LeftInset = horizontalInset;
+ _insetClip.RightInset = horizontalInset;
+ _insetClip.TopInset = verticalInset;
+ _insetClip.BottomInset = verticalInset;
+ }
+
+ private void CompositionBasicsPage_Unloaded(object sender, RoutedEventArgs e)
+ {
+ ElementCompositionPreview.SetElementChildVisual(ChildVisualHost, null);
+ _childVisual?.Dispose();
+ _childVisual = null;
+ }
+}
diff --git a/WinUIGallery/Samples/CompositionBasics/CompositionBasicsTransformMatrix.txt b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsTransformMatrix.txt
new file mode 100644
index 000000000..2db426032
--- /dev/null
+++ b/WinUIGallery/Samples/CompositionBasics/CompositionBasicsTransformMatrix.txt
@@ -0,0 +1,25 @@
+--- header
+Apply multiple transforms with TransformMatrix
+--- xaml
+
+
+
+--- c#
+private Visual? _visual;
+
+private void UpdateTransform(float horizontalScale, float skewInDegrees)
+{
+ _visual ??= ElementCompositionPreview.GetElementVisual(TransformMatrixTarget);
+ _visual.CenterPoint = new Vector3(TransformMatrixTarget.ActualSize / 2, 0);
+
+ float skewInRadians = skewInDegrees * MathF.PI / 180;
+ Matrix4x4 skewMatrix = Matrix4x4.Identity;
+ skewMatrix.M21 = MathF.Tan(skewInRadians);
+ _visual.TransformMatrix =
+ Matrix4x4.CreateScale(horizontalScale, 1, 1) *
+ skewMatrix;
+}