/// <summary> /// Stops all animations that affect the animation tree (such as animations that control the /// speed ratios or animation weights). /// </summary> /// <param name="animationManager">The <see cref="AnimationManager"/>.</param> internal void StopSecondaryAnimations(AnimationManager animationManager) { if (((IAnimatableProperty <float>)_speedProperty).IsAnimated) { animationManager.StopAnimation(_speedProperty); animationManager.UpdateAndApplyAnimation(_speedProperty); } if (((IAnimatableProperty <float>)_weightProperty).IsAnimated) { animationManager.StopAnimation(_weightProperty); animationManager.UpdateAndApplyAnimation(_weightProperty); } foreach (var child in Children) { child.StopSecondaryAnimations(animationManager); } }
//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- /// <inheritdoc/> public void Update(AnimationManager animationManager) { IAnimatableProperty <T> property = Property; if (property == null) { // The animated object has been garbage collected. return; } int numberOfAnimations = Items.Count; if (numberOfAnimations == 0) { // All animations have stopped or were removed. if (property is ImmediateAnimatableProperty <T> ) { // Special: Certain properties need to be set immediately. // All other properties are set in Apply(); ResetProperty(property); } return; } // Get the property's base value. T baseValue; if (property.HasBaseValue) { // The animatable property has a base value. baseValue = property.BaseValue; } else { // The animatable property does not have a base value. // Use identity. (Create a temporary object if necessary.) _traits.Create(ref _value, out baseValue); _traits.SetIdentity(ref baseValue); } // Get the start value of the composition chain. if (_hasSnapshot) { // An animation snapshot has been taken previously. // Start composition chain with animation snapshot. _traits.Copy(ref _snapshot, ref _value); } else { // Start the composition chain with the base value. _traits.Copy(ref baseValue, ref _value); } // Compose the animations in the composition chain. for (int i = 0; i < numberOfAnimations; i++) { var animationInstance = Items[i]; // The source value is the output of the previous stage in the composition chain: _value. // The target value is the base value of the animated property: baseValue. // Store the output of the current stage in _value. animationInstance.GetValue(ref _value, ref baseValue, ref _value); } if (!property.HasBaseValue) { // Recycle baseValue which was created previously. _traits.Recycle(ref baseValue); } if (property is ImmediateAnimatableProperty <T> ) { // Special: Certain properties need to be set immediately. // All other properties are set in Apply(); SetProperty(property); } }
/// <inheritdoc/> internal override void AddToCompositionChains(AnimationManager animationManager, HandoffBehavior handoffBehavior, AnimationInstance previousInstance) { var property = Property; if (property == null) { return; } // Get (or create) the animation composition chain. var compositionChain = animationManager.GetCompositionChain(property, Animation.Traits, true); if (handoffBehavior == HandoffBehavior.SnapshotAndReplace) { // Make a snapshot of the current animation value. compositionChain.TakeSnapshot(); } if (handoffBehavior == HandoffBehavior.Replace || handoffBehavior == HandoffBehavior.SnapshotAndReplace) { // Remove all previous animations. if (compositionChain.Count > 0) { var rootInstance = this.GetRoot(); for (int i = compositionChain.Count - 1; i >= 0; i--) { var animationInstance = compositionChain[i]; // Do not remove animation instances of the same animation tree! if (animationInstance.GetRoot() != rootInstance) { compositionChain.RemoveAt(i); } } } } AnimationInstance <T> referenceInstance = null; if (previousInstance != null) { // previousInstance is either a single animation instance or an animation tree that // should be replaced. Find the instance that is assigned to the current property. referenceInstance = previousInstance.GetAssignedInstance(Property) as AnimationInstance <T>; } if (referenceInstance == null) { // Add at the end of the animation composition chain. compositionChain.Add(this); } else { // Insert in animation composition chain at a certain index. int index = compositionChain.IndexOf(referenceInstance); if (index == -1) { // The referenceInstance has not been applied to the current property. compositionChain.Add(this); } else { // Insert after referenceInstance. index++; // Other animation instances of the same animation tree might have already been // inserted after referenceInstance. To maintain the correct order we need to add // this instance after the other instances of the same tree. var rootInstance = this.GetRoot(); var numberOfInstances = compositionChain.Count; while (index < numberOfInstances && compositionChain[index].GetRoot() == rootInstance) { index++; } compositionChain.Insert(index, this); } } }