[UWP]使用CompositionLinearGradientBrush實現漸變畫筆並製作動畫

1. 什麼是 CompositionBrush

CompositionBrush(合成畫筆)是操作可視化層時用於繪製 SpriteVisual 區域的畫筆。

使UWP 應用時可以選擇使用 XAML 畫筆CompositionBrush(合成畫筆) 繪製 UIElement。很多時候XAML畫筆和合成畫筆都能實現同樣的效果,在官方文檔 使用 XAML 畫筆 vs。CompositionBrush 這一節中有詳細的對比介紹。

CompositionBrush性能更好且能做更復雜的動畫。XAML Brush的能力是有極限的,我從短暫的UWP生涯當中學到一件事,XAML Brush越是玩弄動畫,動畫就越可能因爲沒有料到的事態而失敗……除非超越XAML Brush。所以我不做XAML Brush動畫啦。

2. 使用CompositionLinearGradientBrush

CompositionLinearGradientBrush 是線性漸變畫筆,它是最基本的畫筆之一,可以實現類似 LinearGradientBrush的效果。基本使用步驟如下:

  1. 通過Compositor創建CompositionLinearGradientBrush;
  2. 通過Compositor創建並配置CompositionColorGradientStop,然後添加到CompositionLinearGradientBrush的ColorStops裏;
  3. 創建SpriteVisual並將它的Brush設置爲CompositionLinearGradientBrush;
  4. 使用ElementCompositionPreview.SetElementChildVisual 將SpriteVisual設置到某個UIElement的可視化層裏。

具體代碼如下:

<Rectangle x:Name="Gradient"/>
var compositor = Window.Current.Compositor;

//創建 CompositionLinearGradientBrush。
var gradientBrush = compositor.CreateLinearGradientBrush();
gradientBrush.StartPoint = Vector2.Zero;
gradientBrush.EndPoint = new Vector2(1.0f);

var blueGradientStop = compositor.CreateColorGradientStop();
blueGradientStop.Offset = 0f;
blueGradientStop.Color = Color.FromArgb(255, 43, 210, 255);
var redGradientStop = compositor.CreateColorGradientStop();
redGradientStop.Offset = 1f;
redGradientStop.Color = Color.FromArgb(255, 255, 43, 136);
gradientBrush.ColorStops.Add(blueGradientStop);
gradientBrush.ColorStops.Add(redGradientStop);

//創建SpriteVisual並設置Brush
var backgroundVisual = compositor.CreateSpriteVisual();
backgroundVisual.Brush = gradientBrush;

//將自定義 SpriteVisual 設置爲元素的可視化樹的最後一個子元素。
ElementCompositionPreview.SetElementChildVisual(Gradient, backgroundVisual);

Gradient.SizeChanged += (s, e) =>
{
    if (e.NewSize == e.PreviousSize)
        return;

    //設置gradientBrush的尺寸
    backgroundVisual.Size = e.NewSize.ToVector2();
    gradientBrush.CenterPoint = backgroundVisual.Size / 2;
};

運行效果如下:

寫了這麼多代碼,最終的效果其實和下面的XAML一樣。

<Rectangle x:Name="Gradient">
    <Rectangle.Fill>
        <LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
            <GradientStop Color="#FFFF2B88" Offset="1"/>
            <GradientStop Color="#FF2BD2FF" Offset="0"/>
        </LinearGradientBrush>
    </Rectangle.Fill>
</Rectangle>

到目前爲止看起來CompositionBrush沒什麼優勢。

3. 使用合成動畫

其實CompositionBrush其中一個好玩的地方是靈活的合成動畫。

要使用合成動畫,簡單來說就是三個步驟:

  1. 創建CompositionAnimation;
  2. 配置CompositionAnimation;
  3. 在要實現動畫效果的CompositionObject及其屬性上調用StartAnimation;

下面這段代碼是對CompositionColorGradientStop的Offset屬性進行動畫:

//創建動畫
var relaxGradientStopOffsetAnimation = _compositor.CreateScalarKeyFrameAnimation();
//配置動畫
relaxGradientStopOffsetAnimation.Duration = TimeSpan.FromSeconds(1);
relaxGradientStopOffsetAnimation.InsertKeyFrame(1.0f, ViewModel.IsInPomodoro ?1.0f : 0.75f);
//運行動畫
_relaxGradientStop.StartAnimation(nameof(_relaxGradientStop.Offset), relaxGradientStopOffsetAnimation);

完整代碼在 這裏,具體運行效果如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cVjMYyz0-1571792144062)(https://img2018.cnblogs.com/blog/38937/201910/38937-20191002215824260-1282046773.gif)]

4. 結語

其實上面的動畫也可以用XAML畫刷及Storyboard實現,但和這些技術已經老夫老妻了,再玩下去也沒什麼激情,所以想要玩點新花樣。最近一直在搞番茄鍾應用,有什麼新的想法都會塞進去,可以在下面地址安裝:

一個番茄鍾

5. 參考

合成畫筆 - Windows UWP applications _ Microsoft Docs
合成動畫 - Windows UWP applications _ Microsoft Docs
CompositionLinearGradientBrush Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
SpriteVisual Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
ElementCompositionPreview.SetElementChildVisual(UIElement, Visual) Method (Windows.UI.Xaml.Hosting) - Windows UWP applications _ Microsoft Docs

6. 源碼

OnePomodoro_Gradients.xaml.cs at master

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