diff --git a/components/OpacityMaskView/OpenSolution.bat b/components/OpacityMaskView/OpenSolution.bat
new file mode 100644
index 000000000..814a56d4b
--- /dev/null
+++ b/components/OpacityMaskView/OpenSolution.bat
@@ -0,0 +1,3 @@
+@ECHO OFF
+
+powershell ..\..\tooling\ProjectHeads\GenerateSingleSampleHeads.ps1 -componentPath %CD% %*
\ No newline at end of file
diff --git a/components/OpacityMaskView/samples/Assets/Owl3.jpg b/components/OpacityMaskView/samples/Assets/Owl3.jpg
new file mode 100644
index 000000000..1c8f39f70
Binary files /dev/null and b/components/OpacityMaskView/samples/Assets/Owl3.jpg differ
diff --git a/components/OpacityMaskView/samples/Assets/icon.png b/components/OpacityMaskView/samples/Assets/icon.png
new file mode 100644
index 000000000..8435bcaa9
Binary files /dev/null and b/components/OpacityMaskView/samples/Assets/icon.png differ
diff --git a/components/OpacityMaskView/samples/Dependencies.props b/components/OpacityMaskView/samples/Dependencies.props
new file mode 100644
index 000000000..e622e1df4
--- /dev/null
+++ b/components/OpacityMaskView/samples/Dependencies.props
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/OpacityMaskView/samples/MultiTarget.props b/components/OpacityMaskView/samples/MultiTarget.props
new file mode 100644
index 000000000..18f6c7c98
--- /dev/null
+++ b/components/OpacityMaskView/samples/MultiTarget.props
@@ -0,0 +1,9 @@
+
+
+
+ uwp;wasdk;
+
+
diff --git a/components/OpacityMaskView/samples/OpacityMaskView.Samples.csproj b/components/OpacityMaskView/samples/OpacityMaskView.Samples.csproj
new file mode 100644
index 000000000..de93cdc71
--- /dev/null
+++ b/components/OpacityMaskView/samples/OpacityMaskView.Samples.csproj
@@ -0,0 +1,16 @@
+
+
+ OpacityMaskView
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
diff --git a/components/OpacityMaskView/samples/OpacityMaskView.md b/components/OpacityMaskView/samples/OpacityMaskView.md
new file mode 100644
index 000000000..77de6143e
--- /dev/null
+++ b/components/OpacityMaskView/samples/OpacityMaskView.md
@@ -0,0 +1,18 @@
+---
+title: OpacityMaskView
+author: h82258652
+description: A control that applies an opacity mask to its content.
+keywords: OpacityMaskView, Control, Layout
+dev_langs:
+ - csharp
+category: Controls
+subcategory: Layout
+discussion-id: 490
+issue-id: 0
+icon: assets/icon.png
+---
+# OpacityMaskView
+
+The `OpacityMaskView` control applies an opacity mask to its content. The mask is defined by the `OpacityMask` property, which can contain a `Brush` object. The `OpacityMask` property is typically set to a `LinearGradientBrush` or `ImageBrush` object.
+
+> [!Sample OpacityMaskViewSample]
diff --git a/components/OpacityMaskView/samples/OpacityMaskViewSample.xaml b/components/OpacityMaskView/samples/OpacityMaskViewSample.xaml
new file mode 100644
index 000000000..546a72d77
--- /dev/null
+++ b/components/OpacityMaskView/samples/OpacityMaskViewSample.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/OpacityMaskView/samples/OpacityMaskViewSample.xaml.cs b/components/OpacityMaskView/samples/OpacityMaskViewSample.xaml.cs
new file mode 100644
index 000000000..9c90cf9ce
--- /dev/null
+++ b/components/OpacityMaskView/samples/OpacityMaskViewSample.xaml.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using CommunityToolkit.WinUI.Controls;
+
+namespace OpacityMaskViewExperiment.Samples;
+
+///
+/// An example sample page of a custom control inheriting from Panel.
+///
+[ToolkitSample(id: nameof(OpacityMaskViewSample), "OpacityMaskView sample", description: $"A sample for showing how to create and use a {nameof(OpacityMaskView)} control.")]
+public sealed partial class OpacityMaskViewSample : Page
+{
+ public OpacityMaskViewSample()
+ {
+ this.InitializeComponent();
+ }
+}
diff --git a/components/OpacityMaskView/src/CommunityToolkit.WinUI.Controls.OpacityMaskView.csproj b/components/OpacityMaskView/src/CommunityToolkit.WinUI.Controls.OpacityMaskView.csproj
new file mode 100644
index 000000000..450b7af64
--- /dev/null
+++ b/components/OpacityMaskView/src/CommunityToolkit.WinUI.Controls.OpacityMaskView.csproj
@@ -0,0 +1,12 @@
+
+
+ OpacityMaskView
+ This package contains OpacityMaskView.
+
+
+ CommunityToolkit.WinUI.Controls.OpacityMaskViewRns
+
+
+
+
+
diff --git a/components/OpacityMaskView/src/Dependencies.props b/components/OpacityMaskView/src/Dependencies.props
new file mode 100644
index 000000000..e622e1df4
--- /dev/null
+++ b/components/OpacityMaskView/src/Dependencies.props
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/OpacityMaskView/src/MultiTarget.props b/components/OpacityMaskView/src/MultiTarget.props
new file mode 100644
index 000000000..18f6c7c98
--- /dev/null
+++ b/components/OpacityMaskView/src/MultiTarget.props
@@ -0,0 +1,9 @@
+
+
+
+ uwp;wasdk;
+
+
diff --git a/components/OpacityMaskView/src/OpacityMaskView.cs b/components/OpacityMaskView/src/OpacityMaskView.cs
new file mode 100644
index 000000000..43bc5ed26
--- /dev/null
+++ b/components/OpacityMaskView/src/OpacityMaskView.cs
@@ -0,0 +1,111 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Numerics;
+#if WINDOWS_WINAPPSDK
+using Microsoft.UI.Composition;
+using Microsoft.UI.Xaml.Hosting;
+using Microsoft.UI.Xaml.Shapes;
+#else
+using Windows.UI.Composition;
+using Windows.UI.Xaml.Hosting;
+using Windows.UI.Xaml.Shapes;
+#endif
+
+namespace CommunityToolkit.WinUI.Controls;
+
+///
+/// A control that applies an opacity mask to its content.
+///
+[TemplatePart(Name = RootGridTemplateName, Type = typeof(Grid))]
+[TemplatePart(Name = MaskContainerTemplateName, Type = typeof(Border))]
+[TemplatePart(Name = ContentPresenterTemplateName, Type = typeof(ContentPresenter))]
+public partial class OpacityMaskView : ContentControl
+{
+ ///
+ /// Identifies the property.
+ ///
+ public static readonly DependencyProperty OpacityMaskProperty =
+ DependencyProperty.Register(nameof(OpacityMask), typeof(UIElement), typeof(OpacityMaskView), new PropertyMetadata(null, OnOpacityMaskChanged));
+
+ private const string ContentPresenterTemplateName = "PART_ContentPresenter";
+ private const string MaskContainerTemplateName = "PART_MaskContainer";
+ private const string RootGridTemplateName = "PART_RootGrid";
+
+#if WINDOWS_WINAPPSDK
+ private readonly Compositor _compositor = CompositionTarget.GetCompositorForCurrentThread();
+#else
+ private readonly Compositor _compositor = Window.Current.Compositor;
+#endif
+ private CompositionBrush? _mask;
+ private CompositionMaskBrush? _maskBrush;
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpacityMaskView()
+ {
+ DefaultStyleKey = typeof(OpacityMaskView);
+ }
+
+ ///
+ /// Gets or sets a as the opacity mask that is applied to alpha-channel masking for the rendered content of the content.
+ ///
+ public UIElement? OpacityMask
+ {
+ get => (UIElement?)GetValue(OpacityMaskProperty);
+ set => SetValue(OpacityMaskProperty, value);
+ }
+
+ ///
+ protected override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ Grid rootGrid = (Grid)GetTemplateChild(RootGridTemplateName);
+ ContentPresenter contentPresenter = (ContentPresenter)GetTemplateChild(ContentPresenterTemplateName);
+ Border maskContainer = (Border)GetTemplateChild(MaskContainerTemplateName);
+
+ _maskBrush = _compositor.CreateMaskBrush();
+ _maskBrush.Source = GetVisualBrush(contentPresenter);
+ _mask = GetVisualBrush(maskContainer);
+ _maskBrush.Mask = OpacityMask is null ? null : _mask;
+
+ SpriteVisual redirectVisual = _compositor.CreateSpriteVisual();
+ redirectVisual.RelativeSizeAdjustment = Vector2.One;
+ redirectVisual.Brush = _maskBrush;
+ ElementCompositionPreview.SetElementChildVisual(rootGrid, redirectVisual);
+ }
+
+ private static CompositionBrush GetVisualBrush(UIElement element)
+ {
+ Visual visual = ElementCompositionPreview.GetElementVisual(element);
+
+ Compositor compositor = visual.Compositor;
+
+ CompositionVisualSurface visualSurface = compositor.CreateVisualSurface();
+ visualSurface.SourceVisual = visual;
+ ExpressionAnimation sourceSizeAnimation = compositor.CreateExpressionAnimation($"{nameof(visual)}.Size");
+ sourceSizeAnimation.SetReferenceParameter(nameof(visual), visual);
+ visualSurface.StartAnimation(nameof(visualSurface.SourceSize), sourceSizeAnimation);
+
+ CompositionSurfaceBrush brush = compositor.CreateSurfaceBrush(visualSurface);
+
+ visual.Opacity = 0;
+
+ return brush;
+ }
+
+ private static void OnOpacityMaskChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ OpacityMaskView self = (OpacityMaskView)d;
+ if (self._maskBrush is not { } maskBrush)
+ {
+ return;
+ }
+
+ UIElement? opacityMask = (UIElement?)e.NewValue;
+ maskBrush.Mask = opacityMask is null ? null : self._mask;
+ }
+}
diff --git a/components/OpacityMaskView/src/OpacityMaskView.xaml b/components/OpacityMaskView/src/OpacityMaskView.xaml
new file mode 100644
index 000000000..0c1ca0903
--- /dev/null
+++ b/components/OpacityMaskView/src/OpacityMaskView.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/components/OpacityMaskView/src/Themes/Generic.xaml b/components/OpacityMaskView/src/Themes/Generic.xaml
new file mode 100644
index 000000000..22f7bcef4
--- /dev/null
+++ b/components/OpacityMaskView/src/Themes/Generic.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/components/OpacityMaskView/tests/OpacityMaskView.Tests.projitems b/components/OpacityMaskView/tests/OpacityMaskView.Tests.projitems
new file mode 100644
index 000000000..ec9a003ff
--- /dev/null
+++ b/components/OpacityMaskView/tests/OpacityMaskView.Tests.projitems
@@ -0,0 +1,11 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ 04511143-C2A3-4893-810D-3C1EA2877430
+
+
+ OpacityMaskViewExperiment.Tests
+
+
\ No newline at end of file
diff --git a/components/OpacityMaskView/tests/OpacityMaskView.Tests.shproj b/components/OpacityMaskView/tests/OpacityMaskView.Tests.shproj
new file mode 100644
index 000000000..3f996ee59
--- /dev/null
+++ b/components/OpacityMaskView/tests/OpacityMaskView.Tests.shproj
@@ -0,0 +1,13 @@
+
+
+
+ 04511143-C2A3-4893-810D-3C1EA2877430
+ 14.0
+
+
+
+
+
+
+
+