public void Start() { Pause(); _lastMilliseconds = 0; _frames = 0; if (!animationManager.Ticker.SystemEnabled) { FinishImmediately(); return; } _timer = animationManager.Insert(step => { if (step == long.MaxValue) { // We're being forced to finish Value = 1.0; } else { long ms = step + _lastMilliseconds; Value = Math.Min(1.0f, ms / (double)Length); _lastMilliseconds = ms; } long wantedFrames = (_lastMilliseconds / Rate) + 1; if (wantedFrames > _frames || Value >= 1.0f) { ValueUpdated?.Invoke(this, EventArgs.Empty); } _frames = wantedFrames; if (Value >= 1.0f) { if (Loop) { _lastMilliseconds = 0; Value = 0.0f; return(true); } Finished?.Invoke(this, EventArgs.Empty); Value = 0.0f; _timer = 0; return(false); } return(true); }); if (!animationManager.Ticker.IsRunning) { animationManager.Ticker.Start(); } }
static void AnimateKineticInternal(IAnimatable self, IAnimationManager animationManager, string name, Func <double, double, bool> callback, double velocity, double drag, Action finished = null) { var key = new AnimatableKey(self, name); AbortKinetic(key); double sign = velocity / Math.Abs(velocity); velocity = Math.Abs(velocity); int tick = 0; tick = animationManager.Insert(step => { long ms = step; velocity -= drag * ms; velocity = Math.Max(0, velocity); var result = false; if (velocity > 0) { result = callback(sign * velocity * ms, velocity); } if (!result) { finished?.Invoke(); s_kinetics.Remove(key); animationManager.Remove(tick); } return(result); }); s_kinetics[key] = tick; if (!animationManager.Ticker.IsRunning) { animationManager.Ticker.Start(); } }