Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A kompozíciós vizualizációk alkotják azt a vizualizációfastruktúrát, amelyet a Microsoft.UI.Composition API minden más funkciója használ és épít. Az API lehetővé teszi a fejlesztők számára, hogy egy vagy több vizualizációs objektumot definiáljanak és hozzanak létre, amelyek mindegyike egyetlen csomópontot jelöl egy vizualizációfán.
Vizualizációk
Számos vizualizációtípus alkotja a vizualizáció fastruktúráját, valamint egy alap kefeosztályt, amely több alosztályt tartalmaz, amelyek befolyásolják a vizualizáció tartalmát:
- Vizualizáció – alapobjektum, a tulajdonságok többsége itt található, és a többi Vizualizáció objektum örökli.
-
ContainerVisual – a Visualból származik, és lehetővé teszi a gyermek objektumok létrehozását.
- SpriteVisual – a ContainerVisual-ból származik. Képes ecsetet társítani ahhoz, hogy a Visual képpontokat, például képeket, effektusokat vagy egyszínűt jelenítsen meg.
- LayerVisual – a ContainerVisual-ból származik. A vizualizáció gyermekei egyetlen rétegbe vannak lapolva.
- ShapeVisual – a ContainerVisualból származik. A CompositionShape gyökerét képező vizuális fa csomópont.
- RedirectVisual – a ContainerVisual-ból származik. A vizualizáció egy másik vizualizációból szerzi be a tartalmát.
- SceneVisual – a ContainerVisual-ból származik. Tárolóvizualizáció egy 3D jelenet csomópontjaihoz.
Tartalmat és effektusokat alkalmazhat a SpriteVisualsra a CompositionBrush és annak alosztályai, például a CompositionColorBrush, a CompositionSurfaceBrush és a CompositionEffectBrush használatával. Az kefékről további információt a CompositionBrush áttekintésében talál.
A CompositionVisual minta
Itt áttekintünk néhány WinUI 3 mintakódot, amely a korábban felsorolt három különböző vizualizációtípust mutatja be. Bár ez a minta nem foglalkozik olyan fogalmakkal, mint az animációk vagy az összetettebb effektusok, tartalmazza azokat az építőelemeket, amelyeket ezek a rendszerek használnak. (A teljes mintakód a cikk végén jelenik meg.)
A mintában számos egyszínű négyzet található, amelyekre kattintva a képernyő körül húzható. Ha egy négyzetre kattint, az előtérbe kerül, 45 fokkal elfordul, és átlátszatlanná válik, amikor mozgatva van.
Ez számos alapvető fogalmat mutat be az API használatához, többek között a következőket:
- Compositor létrehozása
- SpriteVisual létrehozása CompositionColorBrush használatával
- A vizualizáció kivágása
- A vizualizáció elforgatása
- Átlátszatlanság beállítása
- A vizualizáció helyének módosítása a gyűjteményben.
Compositor létrehozása
A Compositor létrehozása és tárolása egy változóban gyárként való használatra egyszerű feladat. WinUI-alkalmazásokban általában egy olyan XAML-elemből kéri le a compositort, amely már kapcsolódik a vizualizációfához:
Compositor compositor = ElementCompositionPreview.GetElementVisual(MyHost).Compositor;
Ha compositorra van szüksége, és nincs elérhető UIElement, használhatja CompositionTarget.GetCompositorForCurrentThread() helyette.
SpriteVisual és ColorBrush létrehozása
A Compositor használatával egyszerűen létrehozhat objektumokat, amikor szüksége van rájuk, például spriteVisual és CompositionColorBrush:
var visual = _compositor.CreateSpriteVisual();
visual.Brush = _compositor.CreateColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
Bár ez csak néhány sornyi kód, egy hatékony koncepciót mutat be: a SpriteVisual objektumok az effektusok rendszerének középpontjában állnak. A SpriteVisual nagy rugalmasságot biztosít a színek, képek és effektusok létrehozásához. A SpriteVisual egy egyetlen vizualizációtípus, amely egy 2D téglalapot egy ecsettel, ebben az esetben egyszínűvel tölthet ki.
Vizuális elem kivágása
A Compositor segítségével klipeket is létrehozhat vizualizációkhoz. Az alábbiakban egy példa látható az InsetClip használatával a vizualizáció mindkét oldalának vágására:
var clip = _compositor.CreateInsetClip();
clip.LeftInset = 1.0f;
clip.RightInset = 1.0f;
clip.TopInset = 1.0f;
clip.BottomInset = 1.0f;
_currentVisual.Clip = clip;
Az API más objektumaihoz hasonlóan az InsetClip is alkalmazhat animációkat a tulajdonságaira.
Klip elforgatása
A vizualizáció elforgatással átalakítható. Vegye figyelembe, hogy RotationAngle támogatja mind a radiánokat, mind a fokokat. Alapértelmezés szerint radiánokat ad meg, de a fokok egyszerűen megadhatók az alábbi kódrészletben látható módon:
child.RotationAngleInDegrees = 45.0f;
A forgatás csupán egy példa az API által biztosított átalakítási összetevőkre, hogy megkönnyítse ezeket a feladatokat. Ilyenek például az Eltolás, a Méretezés, a Tájolás, a Rotációs tengely és a 4x4 TransformMatrix.
Átlátszatlanság beállítása
A vizualizáció átlátszatlanságának beállítása egyszerű művelet lebegőpontos érték használatával. A mintában például az összes négyzet 0,8 opacitásnál kezdődik:
visual.Opacity = 0.8f;
A forgatáshoz hasonlóan az Opacitás tulajdonság is animálható.
A vizualizáció helyének módosítása a gyűjteményben
A Composition API lehetővé teszi, hogy egy vizuális elem pozíciója a VisualCollection elemei között több módon is megváltozzon. Az InsertAbove-val egy másik vizualizáció fölé helyezhető, az InsertBelow elem alá helyezve, az InsertAtTop használatával felülre mozgatva, vagy az InsertAtBottom aljára helyezve.
A mintában a vizualizáció , amelyre kattintott, felülre van rendezve:
parent.Children.InsertAtTop(_currentVisual);
Teljes példa
A teljes WinUI mintában a fenti fogalmakat együtt alkalmazzák az Visual objektumok egyszerű fájának felépítéséhez és bejárásához, hogy egyéni DirectX megjelenítés nélkül változtassák meg az átlátszatlanságot. A minta egy WinUI-t Grid használ a mutató bemenetéhez, és a kompozíciós fát a következővel ElementCompositionPreviewtárolja: .
<Page
x:Class="CompositionVisualSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid
x:Name="MyHost"
Background="Transparent"
PointerPressed="OnPointerPressed"
PointerMoved="OnPointerMoved"
PointerReleased="OnPointerReleased" />
</Page>
using System;
using System.Numerics;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Input;
using Windows.Foundation;
using Windows.UI;
namespace CompositionVisualSample
{
public sealed partial class MainPage : Page
{
private readonly Random _random = new();
private Compositor _compositor;
private ContainerVisual _root;
private ContainerVisual _currentVisual;
private Vector2 _offsetBias;
private bool _dragging;
public MainPage()
{
InitializeComponent();
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (_root != null)
{
return;
}
_compositor = ElementCompositionPreview.GetElementVisual(MyHost).Compositor;
_root = _compositor.CreateContainerVisual();
ElementCompositionPreview.SetElementChildVisual(MyHost, _root);
for (int index = 0; index < 20; index++)
{
_root.Children.InsertAtTop(CreateChildElement());
}
}
private ContainerVisual CreateChildElement()
{
var element = _compositor.CreateContainerVisual();
element.Size = new Vector2(100.0f, 100.0f);
var maxX = (float)Math.Max(MyHost.ActualWidth - element.Size.X, 0.0);
var maxY = (float)Math.Max(MyHost.ActualHeight - element.Size.Y, 0.0);
element.Offset = new Vector3(
(float)(_random.NextDouble() * maxX),
(float)(_random.NextDouble() * maxY),
0.0f);
var outer = _compositor.CreateSpriteVisual();
outer.Size = new Vector2(100.0f, 100.0f);
outer.Brush = _compositor.CreateColorBrush(Colors.White);
element.Children.InsertAtTop(outer);
var inner = _compositor.CreateSpriteVisual();
inner.Offset = new Vector3(3.0f, 3.0f, 0.0f);
inner.Size = new Vector2(94.0f, 94.0f);
byte red = (byte)(0xFF * (0.2f + (_random.NextDouble() / 0.8f)));
byte green = (byte)(0xFF * (0.2f + (_random.NextDouble() / 0.8f)));
byte blue = (byte)(0xFF * (0.2f + (_random.NextDouble() / 0.8f)));
inner.Brush = _compositor.CreateColorBrush(Color.FromArgb(0xFF, red, green, blue));
outer.Children.InsertAtTop(inner);
element.Opacity = 0.8f;
return element;
}
private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
Point position = e.GetCurrentPoint(MyHost).Position;
_currentVisual = null;
foreach (var child in _root.Children)
{
Vector3 offset = child.Offset;
Vector2 size = child.Size;
if ((position.X >= offset.X) &&
(position.X < offset.X + size.X) &&
(position.Y >= offset.Y) &&
(position.Y < offset.Y + size.Y))
{
_currentVisual = child as ContainerVisual;
_offsetBias = new Vector2(
(float)(offset.X - position.X),
(float)(offset.Y - position.Y));
}
}
if (_currentVisual != null)
{
ContainerVisual parent = (ContainerVisual)_currentVisual.Parent;
parent.Children.Remove(_currentVisual);
parent.Children.InsertAtTop(_currentVisual);
}
}
private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
{
if (_currentVisual == null)
{
return;
}
if (!_dragging)
{
_currentVisual.Opacity = 1.0f;
foreach (var child in _currentVisual.Children)
{
child.RotationAngleInDegrees = 45.0f;
child.CenterPoint = new Vector3(_currentVisual.Size.X / 2, _currentVisual.Size.Y / 2, 0.0f);
break;
}
var clip = _compositor.CreateInsetClip();
clip.LeftInset = 1.0f;
clip.RightInset = 1.0f;
clip.TopInset = 1.0f;
clip.BottomInset = 1.0f;
_currentVisual.Clip = clip;
_dragging = true;
}
Point position = e.GetCurrentPoint(MyHost).Position;
_currentVisual.Offset = new Vector3(
(float)(position.X + _offsetBias.X),
(float)(position.Y + _offsetBias.Y),
0.0f);
}
private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
if (_currentVisual == null)
{
return;
}
if (_dragging)
{
foreach (var child in _currentVisual.Children)
{
child.RotationAngle = 0.0f;
child.CenterPoint = new Vector3(0.0f, 0.0f, 0.0f);
break;
}
_currentVisual.Opacity = 0.8f;
_currentVisual.Clip = null;
_dragging = false;
}
_currentVisual = null;
}
}
}
Ha XAML-gazdagépelem rendelkezésre állása előtt inicializálnia kell egy kompozitort, használja CompositionTarget.GetCompositorForCurrentThread(), majd csatolja a vizuális elemeket a felhasználói felülethez, amint egy gazdagépelem elérhetővé válik.
Windows developer