using System; using System.ComponentModel; namespace HL_FristAidPlatform_Public { /// /// 动画定时器类 /// [Category("动画定时器类")] [DefaultProperty("Options")] [DefaultEvent("Animationing")] [TypeConverter(typeof(EmptyExpandableObjectConverter))] public class AnimationTimer : IDisposable { #region 新增事件 public delegate void AnimationEventHandler(object sender, AnimationEventArgs e); private event AnimationEventHandler animationStart = null; /// /// 动画开始前事件 /// [Description("动画开始前事件")] public event AnimationEventHandler AnimationStart { add { this.animationStart += value; } remove { this.animationStart -= value; } } private event AnimationEventHandler animationing = null; /// /// 动画时间间隔发生事件 /// [Description("动画时间间隔发生事件")] public event AnimationEventHandler Animationing { add { this.animationing += value; } remove { this.animationing -= value; } } private event AnimationEventHandler animationEnding = null; /// /// 动画结束时事件 /// [Description("动画结束时事件")] public event AnimationEventHandler AnimationEnding { add { this.animationEnding += value; } remove { this.animationEnding -= value; } } private event AnimationEventHandler animationRepetition = null; /// /// 动画重复间隔时事件 /// [Description("动画重复间隔时事件")] public event AnimationEventHandler AnimationRepetition { add { this.animationRepetition += value; } remove { this.animationRepetition -= value; } } #endregion 新增事件 #region 新增属性 public AnimationTypes animationType = AnimationTypes.EaseIn; /// /// 动画类型(默认值EaseIn) /// [Description("动画类型")] [DefaultValue(AnimationTypes.EaseIn)] public AnimationTypes AnimationType { get { return this.animationType; } set { this.animationType = value; } } public System.Windows.Forms.Control _control = null; /// /// 动画所属控件 /// [Description("动画所属控件")] [DefaultValue(null)] public System.Windows.Forms.Control Control { get { return this._control; } set { this._control = value; } } private AnimationOptions options; /// /// 动画设置参数 /// [Description("动画设置参数")] public AnimationOptions Options { get { return this.options; } set { this.options = value; } } private int interval = 20; /// /// 动画定时器时间间隔(默认值20毫秒) /// [Description("动画定时器时间间隔")] [DefaultValue(20)] public int Interval { get { return this.interval; } set { if (this.interval == value) return; this.interval = value; if (this.timer != null) this.timer.Interval = this.interval; } } private double animationUsedTime = 0.0; /// /// 动画已经使用了多少时间(默认值0.0毫秒) /// [Description("动画已经使用了多少时间(默认值0.0毫秒)")] [Browsable(false)] [DefaultValue(0.0)] public double AnimationUsedTime { get { return this.animationUsedTime; } } #endregion 新增属性 #region 字段 private bool disposed = false; /// /// 动画定时器 /// private System.Windows.Forms.Timer timer = null; /// /// 添加还是减少动画时间间隔(决定动画方向) /// private AnimationIntervalTypes intervalTypes = AnimationIntervalTypes.Add; /// /// 动画进行中时间累计器 /// [DefaultValue(0.0)] private double runTime = 0.0; #endregion 字段 #region 析构 /// /// 用于组件的初始化 /// [EditorBrowsable(EditorBrowsableState.Never)] public AnimationTimer() { } /// /// /// /// 要变化动画的控件 /// 动画配置 public AnimationTimer(System.Windows.Forms.Control _control, AnimationOptions _options) { this._control = _control; this.options = _options; } #endregion 析构 #region 公开方法 /// /// 动画开始 /// /// 添加还是减少动画时间间隔(决定动画方向) /// 动画已经使用了多少时间(默认值0.0毫秒) public void Start(AnimationIntervalTypes _intervalTypes, double _usedTime) { this.intervalTypes = _intervalTypes; this.Stop(); this.runTime = _usedTime; if (this.animationStart != null) { this.animationStart.Invoke(this._control, new AnimationEventArgs() { Data = this.options.Data, AllTransformValue = this.options.AllTransformValue, AnimationUsedTime = this.runTime, ProgressValue = GetProgress(this.AnimationType, this.options, this.runTime) }); } if (this.timer == null || this.options.EveryNewTimer) { this.timer = new System.Windows.Forms.Timer(); this.timer.Tick += new EventHandler(this.timer_Tick); this.timer.Interval = this.interval; } this.timer.Start(); } /// /// 动画停止 /// public void Stop() { if (this.timer != null) { this.timer.Enabled = false; if (this.options.EveryNewTimer) { this.timer.Dispose(); } } } /// /// 暂停 /// public void Suspend() { if (this.timer != null) { this.timer.Enabled = false; } } /// /// 继续 /// public void Continue() { if (this.timer != null) { this.timer.Enabled = true; } } /// /// 获取动画的进度(0.0-1.0) /// /// 动画类型 /// 动画参数 /// 动画已经使用了多少时间 /// public static double GetProgress(AnimationTypes _animationType, AnimationOptions _options, double _usedTime) { if (_usedTime <= 0) return 0.0; if (_usedTime >= _options.AllTransformTime) return 1.0; double result = 0.0; switch (_animationType) { case AnimationTypes.UniformMotion: result = AnimationCore.UniformMotionCore(_usedTime, _options.AllTransformTime); break; case AnimationTypes.EaseIn: result = AnimationCore.EaseInCore(_usedTime / _options.AllTransformTime, _options.Power); break; case AnimationTypes.EaseOut: result = AnimationCore.EaseOutCore(_usedTime / _options.AllTransformTime, _options.Power); break; case AnimationTypes.EaseBoth: result = AnimationCore.EaseBothCore(_usedTime / _options.AllTransformTime, _options.Power); break; case AnimationTypes.BackIn: result = AnimationCore.BackInCore(_usedTime / _options.AllTransformTime, _options.Power, _options.Amplitude); break; case AnimationTypes.BackOut: result = AnimationCore.BackOutCore(_usedTime / _options.AllTransformTime, _options.Power, _options.Amplitude); break; case AnimationTypes.BackBoth: result = AnimationCore.BackBothCore(_usedTime / _options.AllTransformTime, _options.Power, _options.Amplitude); break; case AnimationTypes.BounceIn: result = AnimationCore.BounceInCore(_usedTime / _options.AllTransformTime, _options.Bounces, _options.Bounciness); break; case AnimationTypes.BounceOut: result = AnimationCore.BounceOutCore(_usedTime / _options.AllTransformTime, _options.Bounces, _options.Bounciness); break; case AnimationTypes.BounceBoth: result = AnimationCore.BounceBothCore(_usedTime / _options.AllTransformTime, _options.Bounces, _options.Bounciness); break; case AnimationTypes.ElasticIn: result = AnimationCore.ElasticInCore(_usedTime / _options.AllTransformTime, _options.Oscillations, _options.Springiness); break; case AnimationTypes.ElasticOut: result = AnimationCore.ElasticOutCore(_usedTime / _options.AllTransformTime, _options.Oscillations, _options.Springiness); break; case AnimationTypes.ElasticBoth: result = AnimationCore.ElasticBothCore(_usedTime / _options.AllTransformTime, _options.Oscillations, _options.Springiness); break; case AnimationTypes.QuadraticIn: result = AnimationCore.QuadraticInCore(_usedTime / _options.AllTransformTime); break; case AnimationTypes.QuadraticOut: result = AnimationCore.QuadraticOutCore(_usedTime / _options.AllTransformTime); break; } return result; } #endregion 公开方法 #region 私有方法 /// /// 动画定时更新 /// /// /// private void timer_Tick(object sender, EventArgs e) { if (this.intervalTypes == AnimationIntervalTypes.Add) this.runTime += this.timer.Interval; else this.runTime -= this.timer.Interval; if ((this.runTime >= 0 && this.runTime < this.options.AllTransformTime) || this.options.AnimationTimerType == AnimationTimerTypes.AlwaysAnimation) { if (this.animationing != null) { this.animationUsedTime = this.runTime; this.animationing.Invoke(this._control, new AnimationEventArgs() { Data = this.options.Data, AllTransformValue = this.options.AllTransformValue, AnimationUsedTime = this.runTime, ProgressValue = GetProgress(this.AnimationType, this.options, this.runTime) }); } } else { if (this.animationing != null)//保证最后一次百分百变化 { this.animationUsedTime = this.runTime < 0 ? 0.0 : this.options.AllTransformTime; this.animationing.Invoke(this._control, new AnimationEventArgs() { Data = this.options.Data, AllTransformValue = this.options.AllTransformValue, AnimationUsedTime = this.runTime, ProgressValue = GetProgress(this.AnimationType, this.options, this.runTime) }); } if (this.options.AnimationTimerType == AnimationTimerTypes.AlwaysRepeatAnimation) { this.runTime = 0.0; if (this.animationRepetition != null) { this.animationRepetition.Invoke(this._control, new AnimationEventArgs() { Data = this.options.Data, AllTransformValue = this.options.AllTransformValue, AnimationUsedTime = this.runTime, ProgressValue = GetProgress(this.AnimationType, this.options, this.runTime) }); } } else { this.Stop(); if (this.animationEnding != null) { this.animationUsedTime = this.runTime < 0 ? 0.0 : this.options.AllTransformTime; this.animationEnding.Invoke(this._control, new AnimationEventArgs() { Data = this.options.Data, AllTransformValue = this.options.AllTransformValue, AnimationUsedTime = this.animationUsedTime, ProgressValue = this.runTime < 0 ? 0.0 : 1.0 }); } } } } #endregion 私有方法 #region 析构器 ~AnimationTimer() { this.Dispose(false); } public void Dispose() { this.Dispose(true); GC.SuppressFinalize((object)this); } protected virtual void Dispose(bool disposing) { if (this.disposed) return; if (disposing) { if (this.timer != null) { this.timer.Dispose(); this.timer = (System.Windows.Forms.Timer)null; } } this.disposed = true; } #endregion 析构器 } #region 类 /// /// 动画参数设置 /// [Description("动画参数设置")] [TypeConverter(typeof(EmptyExpandableObjectConverter))] public class AnimationOptions { private bool everyNewTimer = true; /// /// 是否每一次调用Start方法是都重新创建一个Timer定时器实例(默认值为true) /// [Description("是否每一次调用Start方法是都重新创建一个Timer定时器实例(默认值为true)")] [DefaultValue(true)] public bool EveryNewTimer { get { return this.everyNewTimer; } set { this.everyNewTimer = value; } } private AnimationTimerTypes animationTimerType = AnimationTimerTypes.Normal; /// /// 动画定时器类型 /// [Description("动画定时器类型")] [DefaultValue(AnimationTimerTypes.Normal)] public AnimationTimerTypes AnimationTimerType { get { return this.animationTimerType; } set { this.animationTimerType = value; } } private double allTransformTime = 300.0; /// /// 动画要变换的总时间(默认值300.0) /// [Description("动画要变换的总时间(默认值300.0)")] [DefaultValue(300.0)] public double AllTransformTime { get { return this.allTransformTime; } set { this.allTransformTime = value; } } private double allTransformValue = 10.0; /// /// 动画要变换的总变化值(默认值10.0) /// [Description("动画要变换的总变化值(默认值10.0)")] [DefaultValue(10.0)] public double AllTransformValue { get { return this.allTransformValue; } set { this.allTransformValue = value; } } private object data = null; /// /// 自定义参数 /// [Description("自定义参数")] [Browsable(false)] public object Data { get { return this.data; } set { this.data = value; } } private double power = 3.0; /// /// 动画曲线幂(默认值3.0) /// (限于EaseIn、EaseOut、EaseBoth、BackIn、BackOut、BackBoth) /// [Description("动画曲线幂(默认值3)")] [DefaultValue(3.0)] public double Power { get { return this.power; } set { this.power = value; } } private double amplitude = 1.0; /// /// 收缩与相关联的幅度动画。此值必须大于或等于 0。 默认值为 1.0。 /// (限于BackIn、BackOut、BackBoth) /// [Description("收缩与相关联的幅度动画。此值必须大于或等于 0。 默认值为 1.0")] [DefaultValue(1.0)] public double Amplitude { get { return this.amplitude; } set { this.amplitude = value; } } private int bounces = 3; /// /// 反弹次数。值必须大于或等于零(默认值为3) /// (限于BounceIn、BounceOut、BounceBoth) /// [Description("反弹次数。值必须大于或等于零(默认值为3)")] [DefaultValue(3)] public int Bounces { get { return this.bounces; } set { this.bounces = value; } } private double bounciness = 2.0; /// /// 指定反弹动画的弹性大小。虽然较高的值都会导致反弹 (弹性较小),此属性中的结果很少或者反弹低值会丢失反弹 (弹性较大) 之间的高度。此值必须是正数(默认值为 2.0) /// (限于BounceIn、BounceOut、BounceBoth) /// [Description("指定反弹动画的弹性大小。虽然较高的值都会导致反弹 (弹性较小),此属性中的结果很少或者反弹低值会丢失反弹 (弹性较大) 之间的高度。此值必须是正数(默认值为 2.0)")] [DefaultValue(2.0)] public double Bounciness { get { return this.bounciness; } set { this.bounciness = value; } } private int oscillations = 3; /// /// 目标来回滑过动画目标的次数。此值必须大于或等于0 (默认值为3) /// (限于ElasticIn、ElasticOut、ElasticBoth) /// [Description("目标来回滑过动画目标的次数。此值必须大于或等于0 (默认值为3)")] [DefaultValue(3)] public int Oscillations { get { return this.oscillations; } set { this.oscillations = value; } } private double springiness = 3.0; /// /// 弹簧铡度。 越小的 Springiness 值为,严格 spring,通过每个振动的强度减小的速度越快弹性。一个正数(默认值为3.0) /// (限于ElasticIn、ElasticOut、ElasticBoth) /// [Description("弹簧铡度。 越小的 Springiness 值为,严格 spring,通过每个振动的强度减小的速度越快弹性。一个正数(默认值为3.0)")] [DefaultValue(3.0)] public double Springiness { get { return this.springiness; } set { this.springiness = value; } } } /// /// 动画事件数据 /// [Description("动画事件数据")] public class AnimationEventArgs : EventArgs { /// /// 动画要变换的总变化值 /// public double AllTransformValue { get; set; } /// /// 已进行了多少动画时间 /// public double AnimationUsedTime { get; set; } /// /// 动画总变化值的进度(0.0-1.0) /// public double ProgressValue { get; set; } /// /// 自定义参数 /// public object Data { get; set; } } #endregion 类 #region 枚举 /// /// 动画定时器类型 /// [Description("动画定时器类型")] public enum AnimationTimerTypes { /// /// 一次性动画 /// Normal, /// /// 永久动画 /// AlwaysAnimation, /// /// 永久重复动画 /// AlwaysRepeatAnimation } /// /// 动画时间操作类型(决定动画方向) /// [Description("动画时间操作类型(决定动画方向)")] public enum AnimationIntervalTypes { /// /// 添加 /// Add, /// /// 减少 /// Subtrac } #endregion 枚举 #region Design /// /// 展开属性选型去除描述 /// [Description("展开属性选型去除描述")] public class EmptyExpandableObjectConverter : ExpandableObjectConverter { /// /// 当该属性为展开属性选型时,属性编辑器删除该属性的描述 /// /// /// /// /// /// public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { if (destinationType == typeof(string)) return (object)""; return base.ConvertTo(context, culture, value, destinationType); } } #endregion Design }