コード例 #1
0
        protected override ExpressionVariant EvaluateCore(TimeSpan now, ExpressionVariant currentValue)
        {
            var starting = ExpressionVariant.Create(_startingValue);
            var ctx      = new ExpressionEvaluationContext
            {
                Parameters               = Parameters,
                Target                   = TargetObject,
                CurrentValue             = currentValue,
                FinalValue               = _finalValue ?? starting,
                StartingValue            = starting,
                ForeignFunctionInterface = BuiltInExpressionFfi.Instance
            };
            var elapsed = now - _startedAt;
            var res     = EvaluateImpl(elapsed, currentValue, ref ctx);

            if (_iterationBehavior == AnimationIterationBehavior.Count &&
                !_finished &&
                elapsed > _totalDuration)
            {
                // Active check?
                TargetObject.Compositor.RemoveFromClock(this);
                _finished = true;
            }
            return(res);
        }
コード例 #2
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
                                                )));
        }