diff --git a/samples/RenderTest/Pages/AnimationsPage.xaml b/samples/RenderTest/Pages/AnimationsPage.xaml index 5532383aac..f8d486bfc4 100644 --- a/samples/RenderTest/Pages/AnimationsPage.xaml +++ b/samples/RenderTest/Pages/AnimationsPage.xaml @@ -7,7 +7,6 @@ - - - - - - - - Hover to activate Transform Keyframe Animations. + + + Hover to activate Transform Keyframe Animations. + diff --git a/src/Avalonia.Animation/Keyframes/DoubleKeyFrames.cs b/src/Avalonia.Animation/Keyframes/DoubleKeyFrames.cs index 107b736b8b..6c23658d40 100644 --- a/src/Avalonia.Animation/Keyframes/DoubleKeyFrames.cs +++ b/src/Avalonia.Animation/Keyframes/DoubleKeyFrames.cs @@ -30,43 +30,56 @@ namespace Avalonia.Animation.Keyframes // Get a pair of keyframes to make the interpolation. KeyValuePair firstCue, lastCue; - firstCue = sortedkeyValues.First(); - lastCue = sortedkeyValues.Last(); + // This should be changed later for a much more efficient one if (sortedkeyValues.Count() > 2) { - bool isWithinRange_Start = DoubleUtils.AboutEqual(x, 0.0) || x > 0.0; - bool isWithinRange_End = DoubleUtils.AboutEqual(x, 1.0) || x < 1.0; + bool OutsideRange_Start = DoubleUtils.AboutEqual(x, 0.0) || x < 0.0; + bool OutsideRange_End = DoubleUtils.AboutEqual(x, 1.0) || x > 1.0; + var kyF = sortedkeyValues.ToArray(); - if (isWithinRange_Start && isWithinRange_End) - { - firstCue = sortedkeyValues.Where(j => j.Key <= x).Last(); - lastCue = sortedkeyValues.Where(j => j.Key >= x).First(); - } - else if (!isWithinRange_Start) + if (OutsideRange_Start) { - firstCue = sortedkeyValues.First(); - lastCue = sortedkeyValues.Skip(1).First(); + firstCue = kyF[0]; + lastCue = kyF[1]; } - else if (!isWithinRange_End) + else if (OutsideRange_End) { - firstCue = sortedkeyValues.Skip(sortedkeyValues.Count() - 1).First(); - lastCue = sortedkeyValues.Last(); + var count = kyF.Count(); + firstCue = kyF[count - 2]; + lastCue = kyF[count - 1]; } else { - throw new InvalidOperationException - ($"Can't find KeyFrames within the specified Easing time {x}"); + firstCue = sortedkeyValues.Where(j => j.Key <= x).Last(); + lastCue = sortedkeyValues.Where(j => j.Key >= x).First(); } } + else + { + firstCue = sortedkeyValues.First(); + lastCue = sortedkeyValues.Last(); + } + + double x0, y0, x1, y1; - // Piecewise Linear interpolation, courtesy of wikipedia - var y0 = firstCue.Value; - var x0 = firstCue.Key; - var y1 = lastCue.Value; - var x1 = lastCue.Key; - var y = ((y0 * (x1 - x)) + (y1 * (x - x0))) / x1 - x0; + // Swap interpolants if its descending + // if (firstCue.Value > lastCue.Value) + // // { + // y1 = firstCue.Value; + // x1 = firstCue.Key; + // y0 = lastCue.Value; + // x0 = lastCue.Key; + // } + // else + // { + y0 = firstCue.Value; + x0 = firstCue.Key; + y1 = lastCue.Value; + x1 = lastCue.Key; + + var y = y0 + ((x - x0)/(x1 - x0)) * (y1-y0); return y; }