1. UWP中的其它裁剪方案 之前在 "這篇文章" 里,我介紹瞭如何使用 "UIElement.Clip" 裁剪UIElement的內容,使用代碼如下: 在 "另一篇文章里" 我介紹瞭如何使用 "CanvasActiveLayer" 裁剪Win2D內容,使用代碼如下: 這兩種方式都有他們的局限:Ca ...
1. UWP中的其它裁剪方案
之前在 這篇文章 里,我介紹瞭如何使用UIElement.Clip裁剪UIElement的內容,使用代碼如下:
<Canvas>
<Image Source="Images/Water_lilies.jpg" Width="200" Height="150">
<Image.Clip>
<RectangleGeometry Rect="100 75 50 50"/>
</Image.Clip>
</Image>
</Canvas>
在 另一篇文章里 我介紹瞭如何使用 CanvasActiveLayer 裁剪Win2D內容,使用代碼如下:
var fullSizeGeometry = CanvasGeometry.CreateRectangle(session, 0, 0, width, height);
var textGeometry = CanvasGeometry.CreateText(textLayout);
var finalGeometry = fullSizeGeometry.CombineWith(textGeometry, Matrix3x2.Identity, CanvasGeometryCombine.Exclude);
using (var layer = session.CreateLayer(1, finalGeometry))
{
//DrawSth
}
這兩種方式都有他們的局限:CanvasActiveLayer雖然很靈活,但只能裁剪Win2D的內容,而且代碼量不少;而UIElement.Clip雖然使用簡單,但只能裁剪矩形區域。而介於他們之間的是使用Visual.Clip
的裁剪方案。
2. Visual.Clip和InsetClip、CompositionGeometricClip
Visual.Clip允許用戶使用CompositionClip。剛開始繼承CompositionClip類的只有 InsetClip,它只能裁剪矩形區域,不能否定某些情況下它還是挺有用的,何況還能進行動畫,但比UIElement.Clip
還是好不了多少。使用方法如下:
var compositor = Window.Current.Compositor;
var visual = ElementCompositionPreview.GetElementVisual(uElement);
var clip = compositor.CreateInsetClip(leftInset, topInset, rightInset, bottomInset);
visual.Clip = clip;
到了1809,Compositor
提供了一個新的函數CreateGeometricClip,它可以以CompositionGeometry 為參數創建一個CompositionGeometricClip,這樣就可以根據CompositionGeometry
裁剪複雜的區域。Compositor
提供了CreateEllipseGeometry、CreateLineGeometry、CreatePathGeometry、CreatePathGeometry(CompositionPath)、CreateRectangleGeometry、CreateRoundedRectangleGeometry等一些列創建Geometry的函數,具體使用方法如下:
var compositor = Window.Current.Compositor;
var visual = ElementCompositionPreview.GetElementVisual(uElement);
var geometry = compositor.CreateEllipseGeometry();
geometry.Center = new System.Numerics.Vector2(192, 525);
geometry.Radius = Vector2.Zero;
var clip = compositor.CreateGeometricClip(geometry);
visual.Clip = clip;
上面的代碼使用CreateEllipseGeometry
創建了一個圓形的Geometry,設置好這個Geometry的中心點和半徑,然後用這個圓形裁剪Visual。
3. 創建動畫
CompositionApi的一個最大的好處是靈活的動畫,例如下麵這個用EllipseGeometry製作的動畫:
它只是很簡單地對Radius
進行KeyFrame動畫,代碼如下:
var compositor = Window.Current.Compositor;
var animation = compositor.CreateVector2KeyFrameAnimation();
animation.DelayTime = delayTime;
animation.Duration = TimeSpan.FromSeconds(0.7);
animation.InsertKeyFrame(1, new Vector2(600, 600));
ellipseGeometry.StartAnimation(nameof(CompositionEllipseGeometry.Radius), animation);
有趣的是Radius居然是個Vector2屬性,所以CompositionEllipseGeometry
其實可以創建為橢圓形。
4. 結語
有了CompositionGeometricClip可以在UWP裁剪複雜區域,但只能在1809以後使用。只是裁剪的話,目前看起來沒比WPF有多少優勢,但加上Composition動畫可玩性就強太多了。使用WPF的時候我幾乎不敢使用動畫,總是需要照顧低端配置,又擔心WPF的性能。10年過去了,UWP的性能以及現代化的電腦配置終於可以讓我放飛自我了。
5. 參考
Compositor Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
Visual.Clip Property (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
CompositionClip Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
InsetClip Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
CompositionGeometry Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
CompositionGeometricClip Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs