T GetKeyFrame(ref ExpressionEvaluationContext ctx, ServerKeyFrame <T> f) { if (f.Expression != null) { return(f.Expression.Evaluate(ref ctx).CastOrDefault <T>()); } else { return(f.Value); } }
public ServerKeyFrame <T>[] Snapshot() { var frames = new ServerKeyFrame <T> [Count]; for (var c = 0; c < Count; c++) { var f = this[c]; frames[c] = new ServerKeyFrame <T> { Expression = f.Expression, Value = f.Value, EasingFunction = f.EasingFunction, Key = f.NormalizedProgressKey }; } return(frames); }
private ExpressionVariant EvaluateImpl(TimeSpan elapsed, ExpressionVariant currentValue, ref ExpressionEvaluationContext ctx) { if (elapsed < _delayTime) { if (_delayBehavior == AnimationDelayBehavior.SetInitialValueBeforeDelay) { return(ExpressionVariant.Create(GetKeyFrame(ref ctx, _keyFrames[0]))); } return(currentValue); } elapsed -= _delayTime; var iterationNumber = elapsed.Ticks / _duration.Ticks; if (_iterationBehavior == AnimationIterationBehavior.Count && iterationNumber >= _iterationCount) { return(ExpressionVariant.Create(GetKeyFrame(ref ctx, _keyFrames[_keyFrames.Length - 1]))); } var evenIterationNumber = iterationNumber % 2 == 0; elapsed = TimeSpan.FromTicks(elapsed.Ticks % _duration.Ticks); var reverse = _direction == PlaybackDirection.Alternate ? !evenIterationNumber : _direction == PlaybackDirection.AlternateReverse ? evenIterationNumber : _direction == PlaybackDirection.Reverse; var iterationProgress = elapsed.TotalSeconds / _duration.TotalSeconds; if (reverse) { iterationProgress = 1 - iterationProgress; } var left = new ServerKeyFrame <T> { Value = _startingValue }; var right = _keyFrames[_keyFrames.Length - 1]; for (var c = 0; c < _keyFrames.Length; c++) { var kf = _keyFrames[c]; if (kf.Key < iterationProgress) { // this is the last frame if (c == _keyFrames.Length - 1) { return(ExpressionVariant.Create(GetKeyFrame(ref ctx, kf))); } left = kf; right = _keyFrames[c + 1]; break; } } var keyProgress = Math.Max(0, Math.Min(1, (iterationProgress - left.Key) / (right.Key - left.Key))); var easedKeyProgress = (float)right.EasingFunction.Ease(keyProgress); if (float.IsNaN(easedKeyProgress) || float.IsInfinity(easedKeyProgress)) { return(currentValue); } return(ExpressionVariant.Create(_interpolator.Interpolate( GetKeyFrame(ref ctx, left), GetKeyFrame(ref ctx, right), easedKeyProgress ))); }