You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

151 lines
4.2 KiB

using AuroraDesk.Presentation.ViewModels.Base;
using ReactiveUI;
using System.Collections.Generic;
using System.Linq;
namespace AuroraDesk.Presentation.ViewModels.Pages;
/// <summary>
/// 基于 Skottie 的呼吸动画页面 ViewModel
/// </summary>
public class BreathePageViewModel : RoutableViewModel
{
private readonly IList<AnimationOption> _availableAnimations;
private int _repeatCount = Avalonia.Skia.Lottie.Lottie.Infinity;
private string _animationPath = "avares://AuroraDesk.Presentation/Resources/Animations/breathe.json";
private string _pageTitle = "呼吸动画";
private string _pageDescription = "演示如何在 Avalonia 中使用 Skottie 播放 Lottie 动画。";
private AnimationOption? _selectedAnimation;
private bool _isUpdatingSelection;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="hostScreen">宿主 Screen</param>
public BreathePageViewModel(IScreen hostScreen)
: base(hostScreen, "BreatheAnimation")
{
_availableAnimations =
[
new AnimationOption("呼吸引导", "avares://AuroraDesk.Presentation/Resources/Animations/breathe.json"),
new AnimationOption("呼吸引导 V2", "avares://AuroraDesk.Presentation/Resources/Animations/breatheV2.json"),
new AnimationOption("科技律动 V3", "avares://AuroraDesk.Presentation/Resources/Animations/breathe_V3.json"),
];
_selectedAnimation = _availableAnimations.FirstOrDefault(x => x.Path == _animationPath)
?? _availableAnimations.FirstOrDefault();
if (_selectedAnimation is not null && _selectedAnimation.Path != _animationPath)
{
_animationPath = _selectedAnimation.Path;
}
}
/// <summary>
/// 动画文件的资源路径(avares URI)
/// </summary>
public string AnimationPath
{
get => _animationPath;
set
{
if (value == _animationPath)
{
return;
}
this.RaiseAndSetIfChanged(ref _animationPath, value);
if (_isUpdatingSelection)
{
return;
}
try
{
_isUpdatingSelection = true;
var match = _availableAnimations.FirstOrDefault(x => x.Path == value);
SelectedAnimation = match;
}
finally
{
_isUpdatingSelection = false;
}
}
}
/// <summary>
/// 动画重复次数,默认无限循环
/// </summary>
public int RepeatCount
{
get => _repeatCount;
set => this.RaiseAndSetIfChanged(ref _repeatCount, value);
}
/// <summary>
/// 页面标题
/// </summary>
public string PageTitle
{
get => _pageTitle;
set => this.RaiseAndSetIfChanged(ref _pageTitle, value);
}
/// <summary>
/// 页面描述
/// </summary>
public string PageDescription
{
get => _pageDescription;
set => this.RaiseAndSetIfChanged(ref _pageDescription, value);
}
/// <summary>
/// 可供选择的动画资源列表
/// </summary>
public IReadOnlyList<AnimationOption> AvailableAnimations => (IReadOnlyList<AnimationOption>)_availableAnimations;
/// <summary>
/// 当前选中的动画资源
/// </summary>
public AnimationOption? SelectedAnimation
{
get => _selectedAnimation;
set
{
if (ReferenceEquals(_selectedAnimation, value))
{
return;
}
this.RaiseAndSetIfChanged(ref _selectedAnimation, value);
if (_isUpdatingSelection)
{
return;
}
if (value is null)
{
return;
}
try
{
_isUpdatingSelection = true;
AnimationPath = value.Path;
}
finally
{
_isUpdatingSelection = false;
}
}
}
/// <summary>
/// 表示可选动画的显示名称与路径
/// </summary>
public record AnimationOption(string DisplayName, string Path);
}