5 changed files with 88 additions and 10 deletions
@ -0,0 +1,68 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reactive.Disposables; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles all animations on properties
|
|||
/// with <see cref="IBrush"/> as their type and
|
|||
/// redirect them to the properly registered
|
|||
/// animators in this class.
|
|||
/// </summary>
|
|||
public class BaseBrushAnimator : Animator<IBrush> |
|||
{ |
|||
private IAnimator _targetAnimator; |
|||
|
|||
private static readonly List<(Func<Type, bool> Match, Type AnimatorType)> _brushAnimators = new(); |
|||
|
|||
/// <summary>
|
|||
/// Register an <see cref="Animator{T}"/> that handles a specific
|
|||
/// <see cref="IBrush"/>'s descendant value type.
|
|||
/// </summary>
|
|||
/// <param name="condition">
|
|||
/// The condition to which the <see cref="Animator{T}"/>
|
|||
/// is to be activated and used.
|
|||
/// </param>
|
|||
/// <typeparam name="TAnimator">
|
|||
/// The type of the animator to instantiate.
|
|||
/// </typeparam>
|
|||
public static void RegisterBrushAnimator<TAnimator>(Func<Type, bool> condition) |
|||
where TAnimator : IAnimator |
|||
{ |
|||
_brushAnimators.Insert(0, (condition, typeof(TAnimator))); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override IDisposable Apply(Animation animation, Animatable control, IClock clock, |
|||
IObservable<bool> match, Action onComplete) |
|||
{ |
|||
foreach (var valueType in _brushAnimators |
|||
.Where(valueType => valueType.Match(this[0].Value.GetType()))) |
|||
{ |
|||
_targetAnimator = (IAnimator)Activator.CreateInstance(valueType.AnimatorType); |
|||
|
|||
foreach (var keyframe in this) |
|||
{ |
|||
_targetAnimator.Add(keyframe); |
|||
} |
|||
|
|||
_targetAnimator.Property = this.Property; |
|||
|
|||
_targetAnimator.Apply(animation, control, clock, match, onComplete); |
|||
} |
|||
|
|||
Logger.TryGet(LogEventLevel.Error, LogArea.Animations)?.Log( |
|||
this, |
|||
"The animation's keyframe values didn't match any brush animators registered in BaseBrushAnimator."); |
|||
|
|||
return Disposable.Empty; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override IBrush Interpolate(double progress, IBrush oldValue, IBrush newValue) => null; |
|||
} |
|||
} |
|||
@ -1,21 +1,19 @@ |
|||
using System; |
|||
using System.Reactive.Disposables; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Immutable; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="SolidColorBrush"/>.
|
|||
/// Animator that handles <see cref="SolidColorBrush"/> values.
|
|||
/// </summary>
|
|||
public class SolidColorBrushAnimator : Animator<IBrush> |
|||
{ |
|||
public override IBrush Interpolate(double progress, IBrush oldValue, IBrush newValue) |
|||
{ |
|||
if (!(oldValue is ISolidColorBrush oldValS) || !(newValue is ISolidColorBrush newValS)) |
|||
if (!(oldValue is ISolidColorBrush oldSCB) || !(newValue is ISolidColorBrush newSCB)) |
|||
return Brushes.Transparent; |
|||
|
|||
return new ImmutableSolidColorBrush(ColorAnimator.InterpolateCore(progress, oldValS.Color, newValS.Color)); |
|||
|
|||
return new ImmutableSolidColorBrush(ColorAnimator.InterpolateCore(progress, oldSCB.Color, newSCB.Color)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue