[UWP]使用CompositionGeometricClip裁剪複雜圖形及進行動畫

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製作的動畫:

[UWP]使用CompositionGeometricClip裁剪複雜圖形及進行動畫

它只是很簡單地對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

Compositor.CreateInsetClip Method (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs

InsetClip Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs

Compositor.CreateGeometricClip Method (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

CompositionEllipseGeometry Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章