public static void BeginAnimation(this IAnimatable animatable, DependencyProperty dependencyProperty, AnimationTimeline animation, HandoffBehavior handoffBehavior = HandoffBehavior.SnapshotAndReplace, object layerOwner = null) { AnimationTimelineClock animationClock = (AnimationTimelineClock)animation.CreateClock(); animatable.ApplyAnimationClock(dependencyProperty, animationClock, handoffBehavior, layerOwner); animationClock.Begin(animatable.RootClock); }
private void ColorAnimationBasicTest(AnimationTimeline animation, Color defaultOriginValue, Color defaultDestinationValue, Color expectedStartValue, Color expectedMiddleValue, Color expectedEndValue) { AnimationTimelineClock clock = (AnimationTimelineClock)animation.CreateClock(); TestRootClock rootClock = new TestRootClock(); clock.Begin(rootClock); rootClock.Tick(TimeSpan.Zero); Assert.AreEqual(expectedStartValue, (Color)animation.GetCurrentValue(defaultOriginValue, defaultDestinationValue, clock)); rootClock.Tick(animation.Duration.TimeSpan.Scale(0.5)); Assert.AreEqual(expectedMiddleValue, (Color)animation.GetCurrentValue(defaultOriginValue, defaultDestinationValue, clock)); rootClock.Tick(animation.Duration.TimeSpan); Assert.AreEqual(expectedEndValue, (Color)animation.GetCurrentValue(defaultOriginValue, defaultDestinationValue, clock)); }
internal static void BeginAnimation( DependencyObject d, DependencyProperty dp, AnimationTimeline animation, HandoffBehavior handoffBehavior) { // Caller should be validating animation. Debug.Assert(animation == null || IsAnimationValid(dp, animation)); Debug.Assert(IsPropertyAnimatable(d, dp)); Debug.Assert(HandoffBehaviorEnum.IsDefined(handoffBehavior), "Public API caller of this internal method is responsible for validating that the HandoffBehavior value is valid." ); AnimationStorage storage = GetStorage(d, dp); if (animation == null) { if ( storage == null || handoffBehavior == HandoffBehavior.Compose) { // Composing with a null animation is a no-op. return; } else { // When the incoming animation is passed in as null and // handoffBehavior == HandoffBehavior.SnapshotAndReplace it means // that we should stop any and all animation behavior for // this property. if (storage._hasStickySnapshotValue) { storage._hasStickySnapshotValue = false; storage._animationClocks[0].CurrentStateInvalidated -= new EventHandler(storage.OnCurrentStateInvalidated); } storage._snapshotValue = DependencyProperty.UnsetValue; storage.ClearAnimations(); } } else if (animation.BeginTime.HasValue) { // We have an animation AnimationClock animationClock; animationClock = animation.CreateClock(); // note that CreateClock also calls InternalBeginIn ApplyAnimationClocks(d, dp, new AnimationClock[] { animationClock }, handoffBehavior); // ApplyAnimationClocks has fixed up the storage and called // WritePostscript already so we can just return. return; } else if (storage == null) { // The user gave us an animation with a BeginTime of null which // means snapshot the current value and throw away all animations // for SnapshotAndReplace and means nothing for Compose. // But since we don't have any animations the current we don't // have to do anything for either of these cases. return; } else if (handoffBehavior == HandoffBehavior.SnapshotAndReplace) { // This block handles the case where the user has called // BeginAnimation with an animation that has a null begin time. // We handle this by taking a snapshot value and throwing // out the animation, which is the same as keeping it because // we know it will never start. // // If the handoffBehavior is Compose, we ignore the user's call // because it wouldn't mean anything unless they were planning // on changing the BeginTime of their animation later, which we // don't support. // If _hasStickySnapshotValue is set, unset it and remove our // event handler from the clock. The current snapshot value // will still be used. if (storage._hasStickySnapshotValue) { Debug.Assert(storage._animationClocks != null && storage._animationClocks.Count > 0, "If _hasStickySnapshotValue is set we should have at least one animation clock stored in the AnimationStorage."); storage._hasStickySnapshotValue = false; storage._animationClocks[0].CurrentStateInvalidated -= new EventHandler(storage.OnCurrentStateInvalidated); } // Otherwise take a new snapshot value. else { storage._snapshotValue = d.GetValue(dp); } storage.ClearAnimations(); } // If storage were null we would have returned already. storage.WritePostscript(); }
internal static void BeginAnimation( DependencyObject d, DependencyProperty dp, AnimationTimeline animation, HandoffBehavior handoffBehavior) { // Caller should be validating animation. Debug.Assert(animation == null || IsAnimationValid(dp, animation)); Debug.Assert(IsPropertyAnimatable(d, dp)); Debug.Assert(HandoffBehaviorEnum.IsDefined(handoffBehavior), "Public API caller of this internal method is responsible for validating that the HandoffBehavior value is valid."); AnimationStorage storage = GetStorage(d, dp); if (animation == null) { if (storage == null || handoffBehavior == HandoffBehavior.Compose) { // Composing with a null animation is a no-op. return; } else { // When the incoming animation is passed in as null and // handoffBehavior == HandoffBehavior.SnapshotAndReplace it means // that we should stop any and all animation behavior for // this property. if (storage._hasStickySnapshotValue) { storage._hasStickySnapshotValue = false; storage._animationClocks[0].CurrentStateInvalidated -= new EventHandler(storage.OnCurrentStateInvalidated); } storage._snapshotValue = DependencyProperty.UnsetValue; storage.ClearAnimations(); } } else if (animation.BeginTime.HasValue) { // We have an animation AnimationClock animationClock; animationClock = animation.CreateClock(); // note that CreateClock also calls InternalBeginIn ApplyAnimationClocks(d, dp, new AnimationClock[] { animationClock }, handoffBehavior); // ApplyAnimationClocks has fixed up the storage and called // WritePostscript already so we can just return. return; } else if (storage == null) { // The user gave us an animation with a BeginTime of null which // means snapshot the current value and throw away all animations // for SnapshotAndReplace and means nothing for Compose. // But since we don't have any animations the current we don't // have to do anything for either of these cases. return; } else if (handoffBehavior == HandoffBehavior.SnapshotAndReplace) { // This block handles the case where the user has called // BeginAnimation with an animation that has a null begin time. // We handle this by taking a snapshot value and throwing // out the animation, which is the same as keeping it because // we know it will never start. // // If the handoffBehavior is Compose, we ignore the user's call // because it wouldn't mean anything unless they were planning // on changing the BeginTime of their animation later, which we // don't support. // If _hasStickySnapshotValue is set, unset it and remove our // event handler from the clock. The current snapshot value // will still be used. if (storage._hasStickySnapshotValue) { Debug.Assert(storage._animationClocks != null && storage._animationClocks.Count > 0, "If _hasStickySnapshotValue is set we should have at least one animation clock stored in the AnimationStorage."); storage._hasStickySnapshotValue = false; storage._animationClocks[0].CurrentStateInvalidated -= new EventHandler(storage.OnCurrentStateInvalidated); } // Otherwise take a new snapshot value. else { storage._snapshotValue = d.GetValue(dp); } storage.ClearAnimations(); } // If storage were null we would have returned already. storage.WritePostscript(); }
/// <summary> /// Setup the animation for the point /// </summary> /// <param name="animatable">Element to run the animation on</param> /// <param name="prop">Property to run the animation on</param> /// <param name="anim">animation timeline</param> /// <param name="duration">animation duration</param> /// <param name="acceleration">acceleration rate</param> /// <param name="deceleration">deceleration rate</param> /// <param name="callbackFunc">callback function</param> private static AnimationClock AnimatePointEasingEquation( DependencyObject animatable, DependencyProperty prop, AnimationTimeline anim, int duration, double? acceleration, double? deceleration, EventHandler func ) { if (acceleration.HasValue) { anim.AccelerationRatio = acceleration.GetValueOrDefault(0); } if (deceleration.HasValue) { anim.DecelerationRatio = deceleration.GetValueOrDefault(0); } anim.Duration = TimeSpan.FromMilliseconds(duration); anim.Freeze(); AnimationClock animClock = anim.CreateClock(); // When animation is complete, remove animation and set the animation's "To" // value as the new value of the property. EventHandler eh = null; eh = delegate(object sender, EventArgs e) { animatable.SetValue(prop, animatable.GetValue(prop)); ((IAnimatable)animatable).ApplyAnimationClock(prop, null); animClock.Completed -= eh; }; animClock.Completed += eh; // assign completed eventHandler, if defined if (func != null) animClock.Completed += func; animClock.Controller.Begin(); // goferit ((IAnimatable)animatable).ApplyAnimationClock(prop, animClock); return animClock; }