Delen via


samenstellingsborstels

Alles wat zichtbaar is op uw scherm in een WinUI-app is zichtbaar omdat het is geschilderd door een borstel. Met penselen kunt u gebruikersinterfaceobjecten (UI) schilderen met inhoud variërend van eenvoudige effen kleuren tot afbeeldingen, tekeningen en complexe effectketens. In dit onderwerp worden de concepten van schilderen met CompositionBrush geïntroduceerd.

Wanneer u met een WinUI XAML-app werkt, kunt u ervoor kiezen om een UIElement te schilderen met een XAML-borstel of een CompositionBrush. Normaal gesproken is het eenvoudiger om een XAML-kwast te kiezen als je scenario al door een bestaande ondersteund wordt. U kunt bijvoorbeeld een animatie toepassen op de kleur van een knop of de opvulling van tekst of een vorm met een afbeelding wijzigen. Als u iets nodig hebt dat niet wordt ondersteund door een XAML-borstel, zoals een geanimeerd masker, een geanimeerde stretch van negen rasters of een effectketen, kunt u een CompositionBrush gebruiken om een UIElement te schilderen via XamlCompositionBrushBase.

Wanneer u met de visuele laag werkt, moet een CompositionBrush worden gebruikt om het gebied van een SpriteVisual te schilderen.

Vereiste voorwaarden

In dit overzicht wordt ervan uitgegaan dat u bekend bent met de structuur van een basis Composition-applicatie, zoals beschreven in het Visuallaag-overzicht.

Schilder met een CompositionBrush

Een CompositionBrush "verft" een gebied met de uitvoer. Verschillende borstels hebben uiteenlopende uitvoersoorten. Sommige penselen schilderen een gebied met een effen kleur, andere met een kleurovergang, afbeelding, aangepaste tekening of effect. Er zijn ook gespecialiseerde borstels die het gedrag van andere borstels wijzigen. Zo kan bijvoorbeeld een dekkingsmasker worden gebruikt om te bepalen welk gebied wordt geschilderd door een CompositionBrush, of een negen-raster kan worden gebruikt om de stretch te regelen die op een CompositionBrush wordt toegepast bij het schilderen van een gebied. CompositionBrush kan van een van de volgende typen zijn:

klasse Details
CompositionColorBrush Verft een gebied met een effen kleur
CompositionSurfaceBrush Schildert een gebied met de inhoud van een ICompositionSurface
CompositionEffectBrush Schildert een gebied met de inhoud van een compositie-effect
CompositionMaskBrush Schildert een visuele weergave met een CompositionBrush met een opaciteitsmasker
CompositionNineGridBrush Schildert een gebied met een CompositionBrush met behulp van een NineGrid stretch
CompositionLinearGradientBrush Een gebied met een lineaire kleurovergang schilderen
CompositionRadialGradientBrush Een gebied met een radiale kleurovergang schilderen
CompositionBackdropBrush Schildert een gebied door achtergrondpixels te bemonsteren van ofwel de toepassing, of pixels direct achter het venster van de toepassing op het bureaublad. Wordt gebruikt als invoer voor een andere CompositionBrush zoals een CompositionEffectBrush

Verf met een effen kleur

Een CompositionColorBrush schildert een gebied met een effen kleur. Er zijn verschillende manieren om de kleur van een SolidColorBrush op te geven. U kunt bijvoorbeeld de alfa-, rode, blauwe en groene kanalen (ARGB) opgeven of een van de vooraf gedefinieerde kleuren van de klasse Kleuren gebruiken.

In de volgende afbeelding en code ziet u een kleine visuele structuur om een rechthoek te maken die is gestreken met een zwarte kleurborstel en geschilderd met een effen kleurborstel met de kleurwaarde van 0x9ACD32.

CompositionColorBrush

Compositor _compositor;
ContainerVisual _container;
SpriteVisual _colorVisual1, _colorVisual2;
CompositionColorBrush _blackBrush, _greenBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_container = _compositor.CreateContainerVisual();

_blackBrush = _compositor.CreateColorBrush(Colors.Black);
_colorVisual1 = _compositor.CreateSpriteVisual();
_colorVisual1.Brush = _blackBrush;
_colorVisual1.Size = new Vector2(156, 156);
_colorVisual1.Offset = new Vector3(0, 0, 0);
_container.Children.InsertAtBottom(_colorVisual1);

_greenBrush = _compositor.CreateColorBrush(Color.FromArgb(0xff, 0x9A, 0xCD, 0x32));
_colorVisual2 = _compositor.CreateSpriteVisual();
_colorVisual2.Brush = _greenBrush;
_colorVisual2.Size = new Vector2(150, 150);
_colorVisual2.Offset = new Vector3(3, 3, 0);
_container.Children.InsertAtBottom(_colorVisual2);

Verf met een lineaire kleurovergang

Een CompositionLinearGradientBrush schildert een gebied met een lineaire kleurovergang. Een lineaire kleurovergang combineert twee of meer kleuren over een lijn, de kleurovergangsas. U gebruikt GradientStop-objecten om de kleuren in de kleurovergang en de bijbehorende posities op te geven.

De volgende afbeelding en code toont een SpriteVisual geschilderd met een LinearGradientBrush met 2 stopt met het gebruik van een rode en gele kleur.

CompositionLinearGradientBrush

Compositor _compositor;
SpriteVisual _gradientVisual;
CompositionLinearGradientBrush _redyellowBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

_redyellowBrush = _compositor.CreateLinearGradientBrush();
_redyellowBrush.ColorStops.Add(_compositor.CreateColorGradientStop(0, Colors.Red));
_redyellowBrush.ColorStops.Add(_compositor.CreateColorGradientStop(1, Colors.Yellow));
_gradientVisual = _compositor.CreateSpriteVisual();
_gradientVisual.Brush = _redyellowBrush;
_gradientVisual.Size = new Vector2(156, 156);

Verf met een radiale kleurovergang

Een CompositionRadialGradientBrush verft een gebied met een radiale kleurovergang. Een radiale kleurovergang combineert twee of meer kleuren, waarbij de kleurovergang begint vanuit het midden van de ellips en eindigt bij de straal van de ellips. GradientStop-objecten worden gebruikt om de kleuren en hun locatie in de kleurovergang te definiëren.

In de volgende illustratie en code ziet u een SpriteVisual beschilderd met een RadialGradientBrush die 2 GradientStops heeft.

CompositionRadialGradientBrush

Compositor _compositor;
SpriteVisual _gradientVisual;
CompositionRadialGradientBrush RGBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

RGBrush = _compositor.CreateRadialGradientBrush();
RGBrush.ColorStops.Add(_compositor.CreateColorGradientStop(0, Colors.Aquamarine));
RGBrush.ColorStops.Add(_compositor.CreateColorGradientStop(1, Colors.DeepPink));
_gradientVisual = _compositor.CreateSpriteVisual();
_gradientVisual.Brush = RGBrush;
_gradientVisual.Size = new Vector2(200, 200);

Tekenen met een afbeelding

Een CompositionSurfaceBrush schildert een gebied met pixels die op een ICompositionSurface worden weergegeven. Een CompositionSurfaceBrush kan bijvoorbeeld worden gebruikt om een gebied te schilderen met een afbeelding die wordt weergegeven op een ICompositionSurface met behulp van de LoadedImageSurface-API .

In de volgende afbeelding en code ziet u een SpriteVisual die is geschilderd met een bitmap van een licorice die wordt weergegeven op een ICompositionSurface met behulp van LoadedImageSurface. De eigenschappen van CompositionSurfaceBrush kunnen worden gebruikt om de bitmap uit te rekken en uit te lijnen binnen de grenzen van de visual.

CompositionSurfaceBrush

Compositor _compositor;
SpriteVisual _imageVisual;
CompositionSurfaceBrush _imageBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

_imageBrush = _compositor.CreateSurfaceBrush();

// The loadedSurface has a size of 0x0 till the image has been downloaded, decoded and loaded to the surface. We can assign the surface to the CompositionSurfaceBrush and it will show up once the image is loaded to the surface.
LoadedImageSurface _loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/licorice.jpg"));
_imageBrush.Surface = _loadedSurface;

_imageVisual = _compositor.CreateSpriteVisual();
_imageVisual.Brush = _imageBrush;
_imageVisual.Size = new Vector2(156, 156);

Tekenen met een aangepaste tekening

Een CompositionSurfaceBrush kan ook worden gebruikt om een gebied te schilderen met pixels van een ICompositionSurface die wordt weergegeven met Win2D (of D2D).

De volgende code toont een SpriteVisual afgebeeld met een tekstrun gerenderd op een ICompositionSurface met Win2D. Als u Win2D met WinUI wilt gebruiken, installeert u het NuGet-pakket Microsoft.Graphics.Win2D in uw project.

Compositor _compositor;
CanvasDevice _device;
CompositionGraphicsDevice _compositionGraphicsDevice;
SpriteVisual _drawingVisual;
CompositionSurfaceBrush _drawingBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_device = CanvasDevice.GetSharedDevice();
_compositionGraphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(_compositor, _device);

_drawingBrush = _compositor.CreateSurfaceBrush();
CompositionDrawingSurface _drawingSurface = _compositionGraphicsDevice.CreateDrawingSurface(
    new Size(256, 256),
    DirectXPixelFormat.B8G8R8A8UIntNormalized,
    DirectXAlphaMode.Premultiplied);

using (var ds = CanvasComposition.CreateDrawingSession(_drawingSurface))
{
    ds.Clear(Colors.Transparent);
    var rect = new Rect(new Point(2, 2), (_drawingSurface.Size.ToVector2() - new Vector2(4, 4)).ToSize());
    ds.FillRoundedRectangle(rect, 15, 15, Colors.LightBlue);
    ds.DrawRoundedRectangle(rect, 15, 15, Colors.Gray, 2);
    ds.DrawText("This is a composition drawing surface", rect, Colors.Black, new CanvasTextFormat()
    {
        FontFamily = "Comic Sans MS",
        FontSize = 32,
        WordWrapping = CanvasWordWrapping.WholeWord,
        VerticalAlignment = CanvasVerticalAlignment.Center,
        HorizontalAlignment = CanvasHorizontalAlignment.Center
    });
}

_drawingBrush.Surface = _drawingSurface;

_drawingVisual = _compositor.CreateSpriteVisual();
_drawingVisual.Brush = _drawingBrush;
_drawingVisual.Size = new Vector2(156, 156);

Op dezelfde manier kan de CompositionSurfaceBrush ook worden gebruikt om een SpriteVisual te schilderen met een SwapChain met behulp van Win2D-interop. Dit voorbeeld toont hoe Win2D kan worden gebruikt om een SpriteVisual te tekenen met een swapchain.

Tekenen met een video

Een CompositionSurfaceBrush kan ook worden gebruikt om een gebied te schilderen met pixels van een ICompositionSurface die wordt weergegeven met behulp van een video die is geladen via de MediaPlayer-klasse .

De volgende code toont een SpriteVisual die is geschilderd met een video die is geladen op een ICompositionSurface.

Compositor _compositor;
SpriteVisual _videoVisual;
CompositionSurfaceBrush _videoBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

// MediaPlayer setup with a source URI.
_mediaPlayer = new MediaPlayer();

// Get a source from a URI. This could also come from a file or a stream.
var source = MediaSource.CreateFromUri(new Uri("https://go.microsoft.com/fwlink/?LinkID=809007&clcid=0x409"));
var item = new MediaPlaybackItem(source);
_mediaPlayer.Source = item;
_mediaPlayer.IsLoopingEnabled = true;

// Get the surface from MediaPlayer and put it on a brush.
_videoSurface = _mediaPlayer.GetSurface(_compositor);
_videoBrush = _compositor.CreateSurfaceBrush(_videoSurface.CompositionSurface);

_videoVisual = _compositor.CreateSpriteVisual();
_videoVisual.Brush = _videoBrush;
_videoVisual.Size = new Vector2(156, 156);

Verf met een filtereffect

Een CompositionEffectBrush schildert een gebied met de output van een CompositionEffect. Effecten in de visuallaag kunnen worden beschouwd als animatie-filtereffecten die worden toegepast op een verzameling broninhoud, zoals kleuren, kleurovergangen, afbeeldingen, video's, wisselketens, regio's van uw gebruikersinterface of structuren van visuals. De broninhoud wordt doorgaans opgegeven met behulp van een andere CompositionBrush.

In de volgende afbeelding en code ziet u een SpriteVisual die is geschilderd met een afbeelding van een kat waarop het filtereffect voor desaturatie is toegepast.

CompositionEffectBrush

Compositor _compositor;
SpriteVisual _effectVisual;
CompositionEffectBrush _effectBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

var graphicsEffect = new SaturationEffect
{
    Saturation = 0.0f,
    Source = new CompositionEffectSourceParameter("mySource")
};

var effectFactory = _compositor.CreateEffectFactory(graphicsEffect);
_effectBrush = effectFactory.CreateBrush();

CompositionSurfaceBrush surfaceBrush = _compositor.CreateSurfaceBrush();
LoadedImageSurface loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/cat.jpg"));
surfaceBrush.Surface = loadedSurface;

_effectBrush.SetSourceParameter("mySource", surfaceBrush);

_effectVisual = _compositor.CreateSpriteVisual();
_effectVisual.Brush = _effectBrush;
_effectVisual.Size = new Vector2(156, 156);

Zie Effecten in visuele laag voor meer informatie over het maken van een effect met behulp van CompositionBrushes

Verf met een CompositionBrush waaraan een opaciteitsmasker is toegevoegd

Een CompositionMaskBrush schildert een gebied met een CompositionBrush met een doorschijnendheidsmasker dat erop is toegepast. De bron van het opaciteitsmasker kan elke CompositionBrush van het type CompositionColorBrush, CompositionLinearGradientBrush, CompositionSurfaceBrush, CompositionEffectBrush of CompositionNineGridBrush zijn. Het dekkingsmasker moet een CompositionSurfaceBrush zijn.

In de volgende afbeelding en code ziet u een SpriteVisual geschilderd met een CompositionMaskBrush. De bron van het masker is een CompositionLinearGradientBrush die is gemaskeerd om eruit te zien als een cirkel met behulp van een afbeelding van cirkel als masker.

CompositionMaskBrush

Compositor _compositor;
SpriteVisual _maskVisual;
CompositionMaskBrush _maskBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

_maskBrush = _compositor.CreateMaskBrush();

CompositionLinearGradientBrush _sourceGradient = _compositor.CreateLinearGradientBrush();
_sourceGradient.ColorStops.Add(_compositor.CreateColorGradientStop(0,Colors.Red));
_sourceGradient.ColorStops.Add(_compositor.CreateColorGradientStop(1,Colors.Yellow));
_maskBrush.Source = _sourceGradient;

LoadedImageSurface loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/circle.png"), new Size(156.0, 156.0));
_maskBrush.Mask = _compositor.CreateSurfaceBrush(loadedSurface);

_maskVisual = _compositor.CreateSpriteVisual();
_maskVisual.Brush = _maskBrush;
_maskVisual.Size = new Vector2(156, 156);

Verf met een CompositionBrush met behulp van NineGrid stretch

Een CompositionNineGridBrush schildert een gebied met een CompositionBrush die wordt uitgerekt met behulp van de metafoor van het negen raster. Met de metafoor van negen rasters kunt u randen en hoeken van een CompositionBrush anders uitrekken dan het midden ervan. De bron van de negen-grid stretch kan elke CompositionBrush van het type CompositionColorBrush, CompositionSurfaceBrush, of CompositionEffectBrush zijn.

De volgende code toont een SpriteVisual geschilderd met een CompositionNineGridBrush. De bron van het masker is een CompositionSurfaceBrush die wordt uitgerekt met behulp van een Nine-Grid.

Compositor _compositor;
SpriteVisual _nineGridVisual;
CompositionNineGridBrush _nineGridBrush;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

_nineGridBrush = _compositor.CreateNineGridBrush();

// nineGridImage.png is 50x50 pixels; nine-grid insets, as measured relative to the actual size of the image, are: left = 1, top = 5, right = 10, bottom = 20 (in pixels)
LoadedImageSurface _imageSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/nineGridImage.png"));
CompositionSurfaceBrush sourceBrush = _compositor.CreateSurfaceBrush(_imageSurface);
_nineGridBrush.Source = sourceBrush;

// Set nine-grid insets.
_nineGridBrush.SetInsets(1, 5, 10, 20);

// Set the appropriate stretch on the SurfaceBrush for the center of the nine-grid.
sourceBrush.Stretch = CompositionStretch.Fill;

_nineGridVisual = _compositor.CreateSpriteVisual();
_nineGridVisual.Brush = _nineGridBrush;
_nineGridVisual.Size = new Vector2(100, 75);

Verf met achtergrond pixels

Een CompositionBackdropBrush schildert een gebied met de inhoud achter het gebied. Een CompositionBackdropBrush wordt nooit zelfstandig gebruikt, maar wordt in plaats daarvan gebruikt als invoer voor een andere CompositionBrush zoals een EffectBrush. Als u bijvoorbeeld een CompositionBackdropBrush gebruikt als invoer voor een Blur-effect, kunt u een vorstglaseffect bereiken.

In de volgende code ziet u een kleine visuele boom om een afbeelding te maken met behulp van CompositionSurfaceBrush en een melkglas-overlay over de afbeelding heen. De matglasoverlay wordt gemaakt door een SpriteVisual gevuld met een EffectBrush boven de afbeelding te plaatsen. De EffectBrush gebruikt een CompositionBackdropBrush als invoer voor het vervagende effect.

Compositor _compositor;
ContainerVisual _containerVisual;
SpriteVisual _imageVisual;
SpriteVisual _backdropVisual;

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

// Create a container visual to host the visual tree.
_containerVisual = _compositor.CreateContainerVisual();

// Create _imageVisual and add it to the bottom of the container visual.
CompositionSurfaceBrush _licoriceBrush = _compositor.CreateSurfaceBrush();
LoadedImageSurface loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/licorice.jpg"));
_licoriceBrush.Surface = loadedSurface;

_imageVisual = _compositor.CreateSpriteVisual();
_imageVisual.Brush = _licoriceBrush;
_imageVisual.Size = new Vector2(156, 156);
_imageVisual.Offset = new Vector3(0, 0, 0);
_containerVisual.Children.InsertAtBottom(_imageVisual);

// Create a SpriteVisual and add it to the top of the container visual.
// Paint the visual with an EffectBrush that applies blur to the content underneath it.
GaussianBlurEffect blurEffect = new GaussianBlurEffect()
{
    Name = "Blur",
    BlurAmount = 1.0f,
    BorderMode = EffectBorderMode.Hard,
    Source = new CompositionEffectSourceParameter("source")
};

CompositionEffectFactory blurEffectFactory = _compositor.CreateEffectFactory(blurEffect);
CompositionEffectBrush _backdropBrush = blurEffectFactory.CreateBrush();

// Create a BackdropBrush and bind it to the EffectSourceParameter source.
_backdropBrush.SetSourceParameter("source", _compositor.CreateBackdropBrush());

_backdropVisual = _compositor.CreateSpriteVisual();
_backdropVisual.Brush = _backdropBrush;
_backdropVisual.Size = new Vector2(78, 78);
_backdropVisual.Offset = new Vector3(39, 39, 0);
_containerVisual.Children.InsertAtTop(_backdropVisual);

Compositieborstels combineren

Een aantal CompositionBrushes gebruikt andere CompositionBrushes als invoer. Als u bijvoorbeeld de methode SetSourceParameter gebruikt, kunt u een andere CompositionBrush instellen als invoer voor een CompositionEffectBrush. De onderstaande tabel bevat een overzicht van de ondersteunde combinaties van CompositionBrushes. Houd er rekening mee dat het gebruik van een niet-ondersteunde combinatie een uitzondering genereert.

Borstel EffectBrush.SetSourceParameter() MaskBrush.Mask MaskBrush.Source NineGridBrush.Source
CompositionColorBrush JA JA JA JA
CompositionLinear
Gradientpenseel
JA JA JA NEE
CompositionSurfaceBrush JA JA JA JA
CompositionEffectBrush NEE NEE JA NEE
CompositionMaskBrush NEE NEE NEE NEE
CompositionNineGridBrush JA JA JA NEE
CompositionBackdropBrush JA NEE NEE NEE

Een XAML Brush versus CompositionBrush gebruiken

De volgende tabel bevat een lijst met scenario's en of XAML of Composition brush wordt voorgeschreven voor het schilderen van een UIElement of een SpriteVisual in uw applicatie.

Opmerking

Als een CompositionBrush wordt voorgesteld voor een XAML UIElement, wordt ervan uitgegaan dat de CompositionBrush is verpakt met behulp van een XamlCompositionBrushBase.

Scenario XAML UIElement Composition SpriteVisual
Een gebied met effen kleur schilderen SolidColorBrush CompositionColorBrush
Een gebied met animatiekleur schilderen SolidColorBrush CompositionColorBrush
Een gebied met een statische kleurovergang schilderen LinearGradientBrush CompositionLinearGradientBrush
Een gebied verven met geanimeerde gradiëntstops CompositionLinearGradientBrush CompositionLinearGradientBrush
Een gebied met een afbeelding schilderen ImageBrush CompositionSurfaceBrush
Een gebied met een webpagina schilderen WebView2 N/A
Een gebied met een afbeelding schilderen met behulp van NineGrid stretch Beeldcontrole CompositionNineGridBrush
Een gebied schilderen met geanimeerde NineGrid stretch CompositionNineGridBrush CompositionNineGridBrush
Een gebied weergeven met een swapchain SwapChainPanel CompositionSurfaceBrush met swapchain-interoperabiliteit
Een gebied tekenen met een video MediaPlayerElement CompositionSurfaceBrush met media-interoperabiliteit
Een gebied tekenen met aangepaste 2D-tekening CanvasControl van Win2D CompositionSurfaceBrush met Win2D-interoperabiliteit
Een gebied met niet-geanimeerd masker schilderen Gebruik XAML-vormen om een masker te definiëren CompositionMaskBrush
Een gebied schilderen met een geanimeerd masker CompositionMaskBrush CompositionMaskBrush
Een gebied schilderen met een filtereffect met animatie CompositionEffectBrush CompositionEffectBrush
Een gebied schilderen met een effect dat is toegepast op achtergrond pixels CompositionBackdropBrush CompositionBackdropBrush

Systeemeigen DirectX- en Direct2D-interop samenstellen met BeginDraw en EndDraw

XAML brush interop met XamlCompositionBrushBase