Beispiel #1
0
 T GetKeyFrame(ref ExpressionEvaluationContext ctx, ServerKeyFrame <T> f)
 {
     if (f.Expression != null)
     {
         return(f.Expression.Evaluate(ref ctx).CastOrDefault <T>());
     }
     else
     {
         return(f.Value);
     }
 }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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
                                                )));
        }