当前位置: 首页 > news >正文

C# Avalonia 15- Animation- AnimationPlayerTest

自己实现一个AnimationPlayer类

AnimationPlayer类

    public partial class AnimationPlayer : ObservableObject{private readonly DispatcherTimer timer;private DateTime? startTime;private DateTime? pauseTime;private bool isRunning;[ObservableProperty]private double _speed = 1.0;[ObservableProperty]private TimeSpan _duration = TimeSpan.FromSeconds(10);[ObservableProperty]private double _progress;[ObservableProperty]private string _timeText = "[[ stopped ]]";[ObservableProperty]private bool _canPause = false;[ObservableProperty]private bool _canResume = false;[ObservableProperty]private bool _canStop = false;// 用户定义的属性应用逻辑public Action<double>? ApplyAction { get; set; }public AnimationPlayer(){timer = new DispatcherTimer{Interval = TimeSpan.FromMilliseconds(50)};timer.Tick += (_, __) => UpdateProgress();}// 开始播放public void Start(){startTime = DateTime.Now;pauseTime = null;isRunning = true;timer.Start();UpdateStates();}// 暂停播放public void Pause(){if (!isRunning) return;pauseTime = DateTime.Now;isRunning = false;timer.Stop();UpdateStates();}// 恢复播放public void Resume(){if (isRunning || startTime == null || pauseTime == null) return;var pausedDuration = DateTime.Now - pauseTime.Value;startTime += pausedDuration;pauseTime = null;isRunning = true;timer.Start();UpdateStates();}// 停止播放public void Stop(){isRunning = false;timer.Stop();startTime = null;pauseTime = null;Progress = 0;TimeText = "[[ stopped ]]";ApplyAction?.Invoke(0);UpdateStates();}// 跳转到指定时间点public void Seek(TimeSpan offset){if (startTime == null) return;startTime = DateTime.Now - TimeSpan.FromTicks((long)(offset.Ticks / Speed));}private void UpdateProgress(){if (startTime == null) return;TimeSpan elapsed;if (isRunning){elapsed = (DateTime.Now - startTime.Value) * Speed;}else if (pauseTime != null){elapsed = (pauseTime.Value - startTime.Value) * Speed;}else{elapsed = TimeSpan.Zero;}if (elapsed >= Duration){elapsed = Duration;isRunning = false;timer.Stop();}Progress = Math.Clamp(elapsed.TotalSeconds / Duration.TotalSeconds, 0, 1);// 带毫秒TimeText = elapsed.ToString(@"hh\:mm\:ss\.ffff");ApplyAction?.Invoke(Progress);UpdateStates();}// 更新 CanPause/CanResume/CanStop 状态private void UpdateStates(){CanPause = isRunning;CanResume = !isRunning && startTime != null && pauseTime != null;CanStop = startTime != null;}}

AnimationPlayerTest.axaml代码

<Window xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"Height="396" Width="360.8"x:Class="AvaloniaUI.AnimationPlayerTest"xmlns:local="using:Shares.Avalonia"x:DataType="local:AnimationPlayer"Title="AnimationPlayerTest"><Grid RowDefinitions="auto,auto,auto,auto,auto"><Grid><Image Source="avares://AvaloniaUI/Resources/Images/night.jpg"/><Image Source="avares://AvaloniaUI/Resources/Images/day.jpg" Name="imgDay"/></Grid><StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" Margin="5" VerticalAlignment="Top"><Button Name="cmdStart" Content="Start"/><Button Name="cmdPause" Content="Pause" IsEnabled="{Binding CanPause}"/><Button Name="cmdResume" Content="Resume" IsEnabled="{Binding CanResume}"/><Button Name="cmdStop" Content="Stop" IsEnabled="{Binding CanStop}"/><Button Name="cmdMiddle" Content="Move To Middle"/></StackPanel><TextBlock Grid.Row="2" Name="lblTime" HorizontalAlignment="Center"></TextBlock><Grid Grid.Row="3" Margin="5" ColumnDefinitions="auto,*">    <TextBlock Margin="0,15,5,0">Speed:</TextBlock><Slider Grid.Column="1" Name="sldSpeed" Minimum="0.1" Maximum="3" Value="1" TickPlacement="BottomRight" TickFrequency="0.1"/></Grid><ProgressBar Grid.Row="4" Margin="0,5,0,0" Height="10" Name="progressBar" Minimum="0" Maximum="1"/></Grid>
</Window>

AnimationPlayerTest.axaml.cs代码

using Avalonia;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Shares.Avalonia;
using System;namespace AvaloniaUI;public partial class AnimationPlayerTest : Window
{private readonly AnimationPlayer? player;public AnimationPlayerTest(){InitializeComponent();player = new AnimationPlayer{Duration = TimeSpan.FromSeconds(10),Speed = 1.0,ApplyAction = progress =>{// 控制 imgDay 的透明度[1,0]imgDay.Opacity = 1 - progress;// 更新进度条progressBar.Value = progress;// 更新时间文本lblTime.Text = player?.TimeText;}};// 绑定按钮cmdStart.Click += (_, _) => player.Start();cmdPause.Click += (_, _) => player.Pause();cmdResume.Click += (_, _) => player.Resume();cmdStop.Click += (_, _) => player.Stop();cmdMiddle.Click += (_, _) => player.Seek(TimeSpan.FromSeconds(5));// 绑定速度sldSpeed.ValueChanged += (_, _) =>{player.Speed = sldSpeed.Value;};this.DataContext = player;}
}

运行效果

image

 

http://www.hskmm.com/?act=detail&tid=10526

相关文章:

  • 基于Python+Vue开发的体育场馆预约管理系统源码+运行步骤
  • JSONArray集合根据某个字段查询对象
  • 详细介绍:Parasoft C/C++test 针对嵌入式开发的内存错误检测解决方案
  • [WC2006] 水管局长
  • 02-Media-7-uvc.py 应用软件解码的USB摄像头(UVC)捕获视频并显示的程序
  • YOLO入门理解 3YOLOv1 思路与细节
  • YOLO入门理解 评估指标
  • 清除win+r“运行”对话框中的历史记录
  • [ICPC 2024 Yokohama R] Peculiar Protocol
  • YOLO入门理解 基础概念
  • The 2025 ICPC Asia East Continent Online Contest (II)(C,D,E,H,I)
  • 2022年十大Web黑客技术提名开启
  • 13. LangChain4j + 加入检索增加生成 RAG(知识库) - Rainbow
  • 终旅之始——2025 . 9 . 20
  • 深入理解Django Admin只读字段与保存模型的自定义操作 - 详解
  • 深度学习(视觉注意力SeNet/CbmaNet/SkNet/EcaNet)
  • 起床
  • qoj6277 Linear Congruential Generator
  • docker+k8s
  • 多模型适配突围:JBoltAI如何重构企业数智化转型新范式?
  • JBoltAI赋能制造业数智化转型:AI从概念到落地的Java实践
  • JBoltAI赋能医疗数智化转型:AI大模型如何重塑医疗健康新范式
  • JBoltAI多模态赋能:制造业数智化升级的新引擎
  • 深入解析:YARN架构解析:深入理解Hadoop资源管理核心
  • JBoltAI:破解Java企业级AI应用落地难题的利器
  • 直播软件开发,单例设计模式很简单吗? - 云豹科技
  • Java开发者的AI革命:如何用JBoltAI应对数智化转型挑战
  • JBoltAI:赋能Java老项目快速接入AI能力的创新之道
  • Day04 C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\David\operator Demo01-08+Doc
  • 实用指南:养老专业实训室建设方案的分级设计与人才培养适配