本文將演示如何在 Avalonia 的後臺程式碼裡面建立 Animation 執行播放
本文演示的內容是將介面裡面的一個 TextBlock 控制元件,透過修改控制元件的 RenderTransform 的 TranslateTransform 執行平移
為了方便演示,先在 MainView.axaml 裡面新增一個 TextBlock 控制元件,如下面程式碼。大家可以在本文末尾找到本文所有的程式碼的下載方法
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform X="700"/>
</TextBlock.RenderTransform>
</TextBlock>
接下來演示如何在後臺程式碼裡面建立動畫和播放動畫
演示的程式碼放在 Loaded 事件裡面,強行使用 Task.Delay 模擬業務的延遲。當然了,如果只是動畫本身期望延遲,可以使用 Animation 的 Delay 屬性執行延遲
public partial class MainView : UserControl
{
public MainView()
{
InitializeComponent();
Loaded += MainView_Loaded;
}
private async void MainView_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
// 這裡的延遲換成 Animation 的 Delay 也對的,且換成 Animation 的更好。這裡的延遲非必須
await Task.Delay(100);
... // 忽略其他程式碼
}
先建立 Animation 物件,設定動畫的過程時間,如下面程式碼所示
var animation = new Animation()
{
Duration = TimeSpan.FromSeconds(10),
... // 忽略其他程式碼
};
接著新增核心的邏輯,透過關鍵幀動畫,設定 TranslateTransform 的 XProperty 在第 0 秒的時候從 0 開始,在第 10 秒的時候為 500d 的值。如此即可作出平緩的動畫,實現 TranslateTransform 的 X 從 0 移動到 500 的值,且過程動畫用 10 秒
var animation = new Animation()
{
Duration = TimeSpan.FromSeconds(10),
IterationCount = new IterationCount(5),
PlaybackDirection = PlaybackDirection.Alternate,
Children =
{
new KeyFrame()
{
Setters =
{
new Setter(TranslateTransform.XProperty, 0d),
},
KeyTime = TimeSpan.FromSeconds(0)
},
new KeyFrame()
{
Setters =
{
new Setter(TranslateTransform.XProperty, 500d),
},
KeyTime = TimeSpan.FromSeconds(10)
}
}
};
這裡需要小心一個細節,那就是 XProperty 是定義了 double 型別的屬性,要求傳入的引數也是 double 型別的。如果這裡沒有寫 0d 而是寫 0 將會在後續播放動畫步驟啥都沒有發生。我認為這裡是 Avalonia 的一個設計缺陷,應該在框架層做好轉換型別邏輯
完成動畫定義之後,現在動畫還沒附加在某個控制元件進行播放,咱就從使用者控制元件裡面獲取剛才介面定義的控制元件,例子程式碼如下
var content = Content;
var textBlock = (TextBlock)content!;
拿到控制元件之後,使用 Animation 的 RunAsync 方法進行播放,這個方法可以不等待返回值。只有在期望等待到動畫播放結束的時候,才需要等待返回值的 Task 完成
在 Avalonia 裡面存在一個設計缺陷是沒有提供和 WPF 一樣的故事板,如果有多個控制元件同時播放動畫只好多次呼叫 RunAsync 方法,且多次呼叫之間不要加上 await 等待
_ = animation.RunAsync(textBlock);
全部的後臺建立和播放動畫程式碼如下
var content = Content;
var textBlock = (TextBlock)content!;
var animation = new Animation()
{
Duration = TimeSpan.FromSeconds(10),
IterationCount = new IterationCount(5),
PlaybackDirection = PlaybackDirection.Alternate,
Children =
{
new KeyFrame()
{
Setters =
{
new Setter(TranslateTransform.XProperty, 0d),
},
KeyTime = TimeSpan.FromSeconds(0)
},
new KeyFrame()
{
Setters =
{
new Setter(TranslateTransform.XProperty, 500d),
},
KeyTime = TimeSpan.FromSeconds(10)
}
}
};
_ = animation.RunAsync(textBlock);
本文程式碼放在 github 和 gitee 上,可以使用如下命令列拉取程式碼。我整個程式碼倉庫比較龐大,使用以下命令列可以進行部分拉取,拉取速度比較快
先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 77ef3ad873b021c71c80ca08cfbff5cadda5e3fc
以上使用的是國內的 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令列繼續輸入以下程式碼,將 gitee 源換成 github 源進行拉取程式碼。如果依然拉取不到程式碼,可以發郵件向我要程式碼
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 77ef3ad873b021c71c80ca08cfbff5cadda5e3fc
獲取程式碼之後,進入 AvaloniaIDemo/QarnahedajaceYawemcehem 資料夾,即可獲取到原始碼
更多 AvaloniaI 部落格,請參閱 部落格導航