Browse Source

Use KeySpline in Animation

pull/3844/head
Deadpikle 6 years ago
parent
commit
24870351fa
  1. 2
      src/Avalonia.Animation/Animation.cs
  2. 9
      src/Avalonia.Animation/AnimatorKeyFrame.cs
  3. 3
      src/Avalonia.Animation/Animators/Animator`1.cs
  4. 20
      src/Avalonia.Animation/KeyFrame.cs
  5. 36
      src/Avalonia.Animation/KeySpline.cs

2
src/Avalonia.Animation/Animation.cs

@ -254,7 +254,7 @@ namespace Avalonia.Animation
cue = new Cue(keyframe.KeyTime.TotalSeconds / Duration.TotalSeconds);
}
var newKF = new AnimatorKeyFrame(handler, cue);
var newKF = new AnimatorKeyFrame(handler, cue, keyframe.KeySpline);
subscriptions.Add(newKF.BindSetter(setter, control));

9
src/Avalonia.Animation/AnimatorKeyFrame.cs

@ -24,11 +24,20 @@ namespace Avalonia.Animation
{
AnimatorType = animatorType;
Cue = cue;
KeySpline = null;
}
public AnimatorKeyFrame(Type animatorType, Cue cue, KeySpline keySpline)
{
AnimatorType = animatorType;
Cue = cue;
KeySpline = keySpline;
}
internal bool isNeutral;
public Type AnimatorType { get; }
public Cue Cue { get; }
public KeySpline KeySpline { get; }
public AvaloniaProperty Property { get; private set; }
private object _value;

3
src/Avalonia.Animation/Animators/Animator`1.cs

@ -89,6 +89,9 @@ namespace Avalonia.Animation.Animators
else
newValue = (T)lastKeyframe.Value;
if (lastKeyframe.KeySpline != null) // TODO: do we use firstKeyFrame or lastKeyframe?!
progress = lastKeyframe.KeySpline.GetSplineProgress(progress);
return Interpolate(progress, oldValue, newValue);
}

20
src/Avalonia.Animation/KeyFrame.cs

@ -19,6 +19,7 @@ namespace Avalonia.Animation
{
private TimeSpan _ktimeSpan;
private Cue _kCue;
private KeySpline _kKeySpline;
public KeyFrame()
{
@ -74,6 +75,25 @@ namespace Avalonia.Animation
}
}
/// <summary>
/// Gets or sets the KeySpline of this <see cref="KeyFrame"/>.
/// </summary>
/// <value>The key spline.</value>
public KeySpline KeySpline
{
get
{
return _kKeySpline;
}
set
{
_kKeySpline = value;
if (value != null && !value.IsValid())
{
throw new ArgumentException($"{nameof(KeySpline)} must have X coordinates >= 0.0 and <= 1.0.");
}
}
}
}

36
src/Avalonia.Animation/KeySpline.cs

@ -66,7 +66,17 @@ namespace Avalonia.Animation
public double ControlPointX1
{
get => _controlPointX1;
set => _controlPointX1 = value;
set
{
if (IsValidXValue(value))
{
_controlPointX1 = value;
}
else
{
throw new ArgumentException("Invalid KeySpline X1 value. Must be >= 0.0 and <= 1.0.");
}
}
}
public double ControlPointY1
@ -78,7 +88,17 @@ namespace Avalonia.Animation
public double ControlPointX2
{
get => _controlPointX2;
set => _controlPointX2 = value;
set
{
if (IsValidXValue(value))
{
_controlPointX2 = value;
}
else
{
throw new ArgumentException("Invalid KeySpline X2 value. Must be >= 0.0 and <= 1.0.");
}
}
}
public double ControlPointY2
@ -94,8 +114,6 @@ namespace Avalonia.Animation
/// <returns>the spline progress</returns>
public double GetSplineProgress(double linearProgress)
{
//ReadPreamble();
if (_isDirty)
{
Build();
@ -113,6 +131,16 @@ namespace Avalonia.Animation
}
}
public bool IsValid()
{
return IsValidXValue(_controlPointX1) && IsValidXValue(_controlPointX2);
}
private bool IsValidXValue(double value)
{
return value >= 0.0 && value <= 1.0;
}
/// <summary>
/// Compute cached coefficients.
/// </summary>

Loading…
Cancel
Save