/// <summary>Call this to halt the animation early.</summary> /// <param name="runEvent">Optionally run the finished event if there is one.</param> public void Stop(bool runEvent) { if (FinishedPlaying) { return; } // Fire the cancelled event: AnimationEvent e = new AnimationEvent("cancel"); dispatchEvent(e); // Find all properties belonging to this animation: AnimatedProperty current = FirstProperty; while (current != null) { // Grab the next one, just incase stop gets called: AnimatedProperty next = current.PropertyAfter; if (current.Animation == this) { current.Stop(); } // Hop to the next one: current = next; } if (runEvent) { // Call finished: Finished(); } }
/// <summary>Starts animating the named property and target value.</summary> /// <param name="property">The property to update. May be an alias or composite.</param> /// <param name="value">The target value of the property.</param> /// <param name="updateCss">True if this property should update CSS/ the screen when it's progressed.</param> private void Animate(CssProperty property, Css.Value value, bool updateCss) { // Check if this property is already animated - if so, interrupt it and override with our new values. // There won't be many actively animated properties, so looping through the update queue is fast anyway. AnimatedProperty animProperty = GetAnimatedProperty(Animating, property); if (animProperty != null) { animProperty.Animate(this, value, TimeCurve, updateCss); } else { // Otherwise we want to create one or more AnimatedProperties and stick them into the queue. // Get or create the initial value: Css.Value hostValue; Css.Value rawValue = property.GetOrCreateValue(Animating, ComputedStyle, false, out hostValue); if (rawValue is Css.ValueSet) { // A special case is when animating a value set. Each one needs to actually animate separately. // E.g. padding:40px 20px; then animating to just padding:30px; for (int i = 0; i < rawValue.Count; i++) { // Create it now: animProperty = new AnimatedProperty(this, property.GetAliased(i, true)); // Setup the value: animProperty.SetupValue(hostValue, rawValue[i]); // Get the target value: Css.Value target = (value is Css.ValueSet) ? value[i] : value; // Animate it now: animProperty.Animate(this, target, TimeCurve, updateCss); animProperty.AddToQueue(); } } else { // Create it now: animProperty = new AnimatedProperty(this, property); // Setup the value: animProperty.SetupValue(hostValue, rawValue); // Animate it now: animProperty.Animate(this, value, TimeCurve, updateCss); animProperty.AddToQueue(); } } }
public void AddToQueue() { // Don't call if it's known to already be in the update queue. if (UIAnimation.FirstProperty == null) { UIAnimation.FirstProperty = UIAnimation.LastProperty = this; } else { PropertyBefore = UIAnimation.LastProperty; UIAnimation.LastProperty = UIAnimation.LastProperty.PropertyAfter = this; } }
/// <summary>Called at the UI update rate to progress the currently animated properties.</summary> public static void Update(float frameTime) { if (FirstProperty == null) { return; } AnimatedProperty current = FirstProperty; while (current != null) { current.Update(frameTime); current = current.PropertyAfter; } }
/// <summary>Starts animating the named property and target value. Must not be composite properties. /// (e.g. color-overlay-r instead of color-overlay)</summary> /// <param name="property">The property to update.</param> /// <param name="innerIndex">The inner index of the property to update.</param> /// <param name="value">The target value of the property.</param> /// <param name="updateCss">True if this property should update CSS/ the screen when it's progressed.</param> private void Animate(CssProperty property, int innerIndex, Css.Value value, bool updateCss) { // Check if this property is already animated - if so, interrupt it and override with our new values. // There won't be many actively animated properties, so looping through the update queue is fast anyway. AnimatedProperty animProperty = GetAnimatedProperty(Animating, property, innerIndex); if (animProperty != null) { animProperty.Animate(this, value, ConstantSpeedTime, TimeToAccelerateFor, TimeToDecelerateFor, updateCss); } else { // Otherwise we want to create a new AnimatedProperty and stick it into the queue: animProperty = new AnimatedProperty(this, property, innerIndex, value, ConstantSpeedTime, TimeToAccelerateFor, TimeToDecelerateFor, updateCss); animProperty.AddToQueue(); } }
/// <summary>Searches the current animated properties for the named property on the given element.</summary> /// <param name="animating">The element being animated.</param> /// <param name="property">The CSS property to look for.</param> /// <returns>An AnimatedProperty if it was found; Null otherwise.</returns> public static AnimatedProperty GetAnimatedProperty(Node animating, CssProperty property) { if (FirstProperty == null) { return(null); } AnimatedProperty current = FirstProperty; while (current != null) { if (current.Animating == animating && current.InnerPropertyInfo == property) { return(current); } current = current.PropertyAfter; } return(null); }
/// <summary>Searches the current animated properties for the named property on the given element.</summary> /// <param name="animating">The element being animated.</param> /// <param name="property">The CSS property to look for. Note: Must not be a composite property such as color-overlay. /// Must be a full property such as color-overlay-r.</param> /// <returns>An AnimatedProperty if it was found; Null otherwise.</returns> public static AnimatedProperty GetAnimatedProperty(Element animating, CssProperty property, int innerIndex) { if (FirstProperty == null) { return(null); } AnimatedProperty current = FirstProperty; while (current != null) { if (current.Animating == animating && current.PropertyInfo == property && current.InnerIndex == innerIndex) { return(current); } current = current.PropertyAfter; } return(null); }
/// <summary>Animates this property now.</summary> /// <param name="animation">The animation that this property is a part of.</param> /// <param name="targetValue">The parsed value that this property will be when the animation is over.</param> /// <param name="constantSpeedTime">How long the animation will change the value at a constant speed for.</param> /// <param name="timeToAccelerateFor">How long the animation will accelerate for. This produces a smoother animation.</param> /// <param name="timeToDecelerateFor">How long the animation will decelerate for. This produces a smoother animation.</param> /// <param name="updateCss">True if this particular property should flush its changes to css/the screen.</param> public void Animate(UIAnimation animation, Css.Value targetValue, float constantSpeedTime, float timeToAccelerateFor, float timeToDecelerateFor, bool updateCss) { Animation = animation; ValueObject.Type = targetValue.Type; Stage = 0; Speed = 0f; CurrentTime = 0f; UpdateCss = updateCss; PropertyAfter = PropertyBefore = null; // Find the max speed. This is what we accelerate to. // Speed (y) / time (x) graph: // /| |-| |\ // A B C. A = accelerate, b=constant, c=decelerate. // Max speed = top y value. // Distance travelled = area of the graph. This should match target - current value. TargetValue = targetValue.ToFloat(); float unitsDelta = TargetValue - ActiveValue; MaxSpeed = (unitsDelta * UI.RedrawRate) / ((0.5f * timeToAccelerateFor) + constantSpeedTime + (0.5f * timeToDecelerateFor)); if (timeToAccelerateFor == 0f) { // Skip acceleration stage. Stage = 1; Speed = MaxSpeed; } else { Acceleration = MaxSpeed * UI.RedrawRate / timeToAccelerateFor; } if (timeToDecelerateFor != 0f) { Deceleration = MaxSpeed * UI.RedrawRate / timeToDecelerateFor; } }
/// <summary>Removes all active animations.</summary> public static void Clear(){ LastProperty=FirstProperty=null; }
/// <summary>Starts animating the named property and target value. Must not be composite properties. /// (e.g. color-overlay-r instead of color-overlay)</summary> /// <param name="property">The property to update.</param> /// <param name="innerIndex">The inner index of the property to update.</param> /// <param name="value">The target value of the property.</param> /// <param name="updateCss">True if this property should update CSS/ the screen when it's progressed.</param> private void Animate(CssProperty property,int innerIndex,Css.Value value,bool updateCss){ // Check if this property is already animated - if so, interrupt it and override with our new values. // There won't be many actively animated properties, so looping through the update queue is fast anyway. AnimatedProperty animProperty=GetAnimatedProperty(Animating,property,innerIndex); if(animProperty!=null){ animProperty.Animate(this,value,ConstantSpeedTime,TimeToAccelerateFor,TimeToDecelerateFor,updateCss); }else{ // Otherwise we want to create a new AnimatedProperty and stick it into the queue: animProperty=new AnimatedProperty(this,property,innerIndex,value,ConstantSpeedTime,TimeToAccelerateFor,TimeToDecelerateFor,updateCss); animProperty.AddToQueue(); } }
/// <summary>Removes all active animations.</summary> public static void Clear() { LastProperty = FirstProperty = null; }
public void AddToQueue(){ // Don't call if it's known to already be in the update queue. if(UIAnimation.FirstProperty==null){ UIAnimation.FirstProperty=UIAnimation.LastProperty=this; }else{ PropertyBefore=UIAnimation.LastProperty; UIAnimation.LastProperty = UIAnimation.LastProperty.PropertyAfter = this; } }
/// <summary>Animates this property now.</summary> /// <param name="animation">The animation that this property is a part of.</param> /// <param name="targetValue">The parsed value that this property will be when the animation is over.</param> /// <param name="constantSpeedTime">How long the animation will change the value at a constant speed for.</param> /// <param name="timeToAccelerateFor">How long the animation will accelerate for. This produces a smoother animation.</param> /// <param name="timeToDecelerateFor">How long the animation will decelerate for. This produces a smoother animation.</param> /// <param name="updateCss">True if this particular property should flush its changes to css/the screen.</param> public void Animate(UIAnimation animation,Css.Value targetValue,float constantSpeedTime,float timeToAccelerateFor,float timeToDecelerateFor,bool updateCss){ Animation=animation; ValueObject.Type=targetValue.Type; Stage=0; Speed=0f; CurrentTime=0f; UpdateCss=updateCss; PropertyAfter=PropertyBefore=null; // Find the max speed. This is what we accelerate to. // Speed (y) / time (x) graph: // /| |-| |\ // A B C. A = accelerate, b=constant, c=decelerate. // Max speed = top y value. // Distance travelled = area of the graph. This should match target - current value. TargetValue=targetValue.ToFloat(); float unitsDelta=TargetValue - ActiveValue; MaxSpeed=(unitsDelta*UI.RedrawRate) / ( (0.5f*timeToAccelerateFor) + constantSpeedTime + (0.5f*timeToDecelerateFor) ); if(timeToAccelerateFor==0f){ // Skip acceleration stage. Stage=1; Speed=MaxSpeed; }else{ Acceleration=MaxSpeed*UI.RedrawRate / timeToAccelerateFor; } if(timeToDecelerateFor!=0f){ Deceleration=MaxSpeed*UI.RedrawRate / timeToDecelerateFor; } }