public ScalingWindow(IServiceLocator services) : base(services) { Title = "ScalingWindow"; Width = 200; Height = 100; Content = new TextBlock { Margin = new Vector4F(8), Text = "The 'RenderScale' of this window is animated.", WrapText = true, }; // Set the center of the scale transformation to the center of the window. RenderTransformOrigin = new Vector2F(0.5f, 0.5f); LoadingAnimation = new Vector2FFromToByAnimation { TargetProperty = "RenderScale", // Animate the property UIControl.RenderScale From = new Vector2F(0, 0), // from (0, 0) to its actual value (1, 1) Duration = TimeSpan.FromSeconds(0.3), // over 0.3 seconds. EasingFunction = new ElasticEase { Mode = EasingMode.EaseOut, Oscillations = 1 }, }; ClosingAnimation = new Vector2FFromToByAnimation { TargetProperty = "RenderScale", // Animate the property UIControl.RenderScale To = new Vector2F(0, 0), // from its current value to (0, 0) Duration = TimeSpan.FromSeconds(0.3), // over 0.3 seconds. EasingFunction = new HermiteEase { Mode = EasingMode.EaseIn }, }; }
public void AnimateTo() { var animation = new Vector2FFromToByAnimation(); animation.From = null; animation.To = new Vector2F(2.0f, 20.0f); animation.By = null; Assert.AreEqual(new Vector2F(0.0f, 0.0f), animation.GetValue(TimeSpan.FromSeconds(0.0), new Vector2F(0.0f, 0.0f), new Vector2F(10.0f, 100.0f))); Assert.AreEqual(new Vector2F(1.0f, 10.0f), animation.GetValue(TimeSpan.FromSeconds(0.5), new Vector2F(0.0f, 0.0f), new Vector2F(10.0f, 100.0f))); Assert.AreEqual(new Vector2F(2.0f, 20.0f), animation.GetValue(TimeSpan.FromSeconds(1.0), new Vector2F(0.0f, 0.0f), new Vector2F(10.0f, 100.0f))); }
public void ShouldIgnoreByIfToIsSet() { var animation = new Vector2FFromToByAnimation(); animation.From = null; animation.To = new Vector2F(4.0f, 40.0f); animation.By = new Vector2F(10.0f, 100.0f); Assert.AreEqual(new Vector2F(0.0f, 0.0f), animation.GetValue(TimeSpan.FromSeconds(0.0), new Vector2F(0.0f, 0.0f), new Vector2F(10.0f, 100.0f))); Assert.AreEqual(new Vector2F(2.0f, 20.0f), animation.GetValue(TimeSpan.FromSeconds(0.5), new Vector2F(0.0f, 0.0f), new Vector2F(10.0f, 100.0f))); Assert.AreEqual(new Vector2F(4.0f, 40.0f), animation.GetValue(TimeSpan.FromSeconds(1.0), new Vector2F(0.0f, 0.0f), new Vector2F(10.0f, 100.0f))); }
// The following code contains two helper methods to animate the opacity and offset // of a group of UI controls. The methods basically do the same, they animate the // properties from/to a specific value. However the methods demonstrate two different // approaches. // // The AnimateFrom method uses a more direct approach. It directly starts an // animation for each UI control in list, thereby creating several independently // running animations. // // The AnimateTo method uses a more declarative approach. All animations are // defined and assigned to the target objects by setting the name of the UI control // in the TargetObject property. Then all animations are grouped together into // a single animation. When the resulting animation is started the animation system // creates the required animation instances and assigns the instances to the correct // objects and properties by matching the TargetObject and TargetProperty with the // name of the UI controls and their properties. // // Both methods achieve a similar result. The advantage of the first method is more // direct control. The advantage of the seconds method is that only a single animation // controller is required to control all animations at once. /// <summary> /// Animates the opacity and offset of a group of controls from the specified value to their /// current value. /// </summary> /// <param name="controls">The UI controls to be animated.</param> /// <param name="opacity">The initial opacity.</param> /// <param name="offset">The initial offset.</param> private void AnimateFrom(IList <UIControl> controls, float opacity, Vector2F offset) { TimeSpan duration = TimeSpan.FromSeconds(0.8); // First, let's define the animation that is going to be applied to a control. // Animate the "Opacity" from the specified value to its current value. var opacityAnimation = new SingleFromToByAnimation { TargetProperty = "Opacity", From = opacity, Duration = duration, EasingFunction = new CubicEase { Mode = EasingMode.EaseOut }, }; // Animate the "RenderTranslation" property from the specified offset to its // its current value, which is usually (0, 0). var offsetAnimation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", From = offset, Duration = duration, EasingFunction = new CubicEase { Mode = EasingMode.EaseOut }, }; // Group the opacity and offset animation together using a TimelineGroup. var timelineGroup = new TimelineGroup(); timelineGroup.Add(opacityAnimation); timelineGroup.Add(offsetAnimation); // Run the animation on each control using a negative delay to give the first controls // a slight head start. var numberOfControls = controls.Count; for (int i = 0; i < controls.Count; i++) { var clip = new TimelineClip(timelineGroup) { Delay = TimeSpan.FromSeconds(-0.04 * (numberOfControls - i)), FillBehavior = FillBehavior.Stop, // Stop and remove the animation when it is done. }; var animationController = AnimationService.StartAnimation(clip, controls[i]); animationController.UpdateAndApply(); // Enable "auto-recycling" to ensure that the animation resources are recycled once // the animation stops or the target objects are garbage collected. animationController.AutoRecycle(); } }
public void CheckDefaultValues() { var animation = new Vector2FFromToByAnimation(); Assert.AreEqual(TimeSpan.FromSeconds(1.0), animation.Duration); Assert.AreEqual(FillBehavior.Hold, animation.FillBehavior); Assert.IsNull(animation.TargetProperty); Assert.IsFalse(animation.From.HasValue); Assert.IsFalse(animation.To.HasValue); Assert.IsFalse(animation.By.HasValue); Assert.IsFalse(animation.IsAdditive); Assert.IsNull(animation.EasingFunction); }
// Animates the buttons to slide in from the left. private void PlayStartAnimation() { // Create an animation that animates the RenderTranslation of a UIControl: Vector2FFromToByAnimation animation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", // Animate the property UIControl.RenderTranslation From = new Vector2F(-400, 0), // from (-400, 0) to its default value Duration = TimeSpan.FromSeconds(0.8), // over a duration of 0.8 seconds. EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; // We apply this animation to all buttons. Each animation should be started with a // different delay. The delay is negative, which means that a part of the animation // beginning is skipped. // To add a delay we wrap the animation in TimelineClips. The TimelineClips can be // grouped together in a TimelineGroup. const float delay = 0.05f; TimelineGroup timelineGroup = new TimelineGroup { new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-6 * delay), TargetObject = "Button0" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-5 * delay), TargetObject = "Button1" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-4 * delay), TargetObject = "Button2" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-3 * delay), TargetObject = "Button3" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-2 * delay), TargetObject = "Button4" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-1 * delay), TargetObject = "Button5" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(0 * delay), TargetObject = "Button6" }, }; // The animation can be removed after it has finished. timelineGroup.FillBehavior = FillBehavior.Stop; // Start the animation. var animationController = AnimationService.StartAnimation(timelineGroup, (IEnumerable<IAnimatableObject>)_buttonStackPanel.Children.OfType<Button>()); #else var animationController = AnimationService.StartAnimation(timelineGroup, _buttonStackPanel.Children.OfType<Button>().Cast<IAnimatableObject>()); // Note: The animation effectively starts when AnimationManager.Update() and Apply() are // called. To start the animation immediately we can call UpdateAndApply() manually. animationController.UpdateAndApply(); }
// Animates the buttons to slide out to the left. public void PlayExitAnimation() { // An animation that animates the RenderTranslation of a UIControl: Vector2FFromToByAnimation animation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", To = new Vector2F(-400, 0), Duration = TimeSpan.FromSeconds(0.8), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; // We apply this animation to all buttons. Each animation should be started with a // different delay. // To add a delay we wrap the animation in TimelineClips. The TimelineClips can be // grouped together in a TimelineGroup. const float delay = 0.05f; TimelineGroup timelineGroup = new TimelineGroup { new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(6 * delay), TargetObject = "Button0" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(5 * delay), TargetObject = "Button1" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(4 * delay), TargetObject = "Button2" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(3 * delay), TargetObject = "Button3" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(2 * delay), TargetObject = "Button4" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(1 * delay), TargetObject = "Button5" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(0 * delay), TargetObject = "Button6" }, }; // The animation should hold the animation value after it is finished (the buttons should // not jump back onto the screen). timelineGroup.FillBehavior = FillBehavior.Hold; // Start the animation and keep the animation controller. We need it to query the // state of the animation in Update(). _exitAnimationController = AnimationService.StartAnimation(timelineGroup, _buttonStackPanel.Children.OfType<Button>()); #else _exitAnimationController = AnimationService.StartAnimation(timelineGroup, _buttonStackPanel.Children.OfType<Button>().Cast<IAnimatableObject>()); }
/// <summary> /// Animates the opacity and offset of a group of controls from their current value to the /// specified value. /// </summary> /// <param name="controls">The UI controls to be animated.</param> /// <param name="opacity">The opacity.</param> /// <param name="offset">The offset.</param> private AnimationController AnimateTo(IList<UIControl> controls, float opacity, Vector2F offset) { TimeSpan duration = TimeSpan.FromSeconds(0.6f); // First, let's define the animation that is going to be applied to a control. // Animate the "Opacity" from its current value to the specified value. var opacityAnimation = new SingleFromToByAnimation { TargetProperty = "Opacity", To = opacity, Duration = duration, EasingFunction = new CubicEase { Mode = EasingMode.EaseIn }, }; // Animate the "RenderTranslation" property from its current value, which is // usually (0, 0), to the specified value. var offsetAnimation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", To = offset, Duration = duration, EasingFunction = new CubicEase { Mode = EasingMode.EaseIn }, }; // Group the opacity and offset animation together using a TimelineGroup. var timelineGroup = new TimelineGroup(); timelineGroup.Add(opacityAnimation); timelineGroup.Add(offsetAnimation); // Now we duplicate this animation by creating new TimelineClips that wrap the TimelineGroup. // A TimelineClip is assigned to a target by setting the TargetObject property. var storyboard = new TimelineGroup(); for (int i = 0; i < controls.Count; i++) { var clip = new TimelineClip(timelineGroup) { TargetObject = controls[i].Name, // Assign the clip to the i-th control. Delay = TimeSpan.FromSeconds(0.04f * i), FillBehavior = FillBehavior.Hold, // Hold the last value of the animation when it }; // because we don't want to opacity and offset to // jump back to their original value. storyboard.Add(clip); } // Now we apply the "storyboard" to the group of UI controls. The animation system // will automatically assign individual animations to the right objects and // properties. var animationController = AnimationService.StartAnimation(storyboard, controls); #else var animationController = AnimationService.StartAnimation(storyboard, controls.Cast<IAnimatableObject>()); animationController.UpdateAndApply(); // The returned animation controller can be used to start, stop, pause, ... all // animations at once. (Note that we don't set AutoRecycle here, because we will // explicitly stop and recycle the animations in the code above.) return animationController; }
// Animates the buttons to slide out to the left. public void PlayExitAnimation() { // An animation that animates the RenderTranslation of a UIControl: Vector2FFromToByAnimation animation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", To = new Vector2F(-400, 0), Duration = TimeSpan.FromSeconds(0.8), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; // We apply this animation to all buttons. Each animation should be started with a // different delay. // To add a delay we wrap the animation in TimelineClips. The TimelineClips can be // grouped together in a TimelineGroup. const float delay = 0.05f; TimelineGroup timelineGroup = new TimelineGroup { new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(6 * delay), TargetObject = "Button0" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(5 * delay), TargetObject = "Button1" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(4 * delay), TargetObject = "Button2" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(3 * delay), TargetObject = "Button3" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(2 * delay), TargetObject = "Button4" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(1 * delay), TargetObject = "Button5" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(0 * delay), TargetObject = "Button6" }, }; // The animation should hold the animation value after it is finished (the buttons should // not jump back onto the screen). timelineGroup.FillBehavior = FillBehavior.Hold; // Start the animation and keep the animation controller. We need it to query the // state of the animation in Update(). #if !XBOX && !WP7 _exitAnimationController = AnimationService.StartAnimation(timelineGroup, _buttonStackPanel.Children.OfType<Button>()); #else _exitAnimationController = AnimationService.StartAnimation(timelineGroup, _buttonStackPanel.Children.OfType<Button>().Cast<IAnimatableObject>()); #endif }
// Animates the buttons to slide in from the left. private void PlayStartAnimation() { // Create an animation that animates the RenderTranslation of a UIControl: Vector2FFromToByAnimation animation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", // Animate the property UIControl.RenderTranslation From = new Vector2F(-400, 0), // from (-400, 0) to its default value Duration = TimeSpan.FromSeconds(0.8), // over a duration of 0.8 seconds. EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; // We apply this animation to all buttons. Each animation should be started with a // different delay. The delay is negative, which means that a part of the animation // beginning is skipped. // To add a delay we wrap the animation in TimelineClips. The TimelineClips can be // grouped together in a TimelineGroup. const float delay = 0.05f; TimelineGroup timelineGroup = new TimelineGroup { new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-6 * delay), TargetObject = "Button0" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-5 * delay), TargetObject = "Button1" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-4 * delay), TargetObject = "Button2" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-3 * delay), TargetObject = "Button3" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-2 * delay), TargetObject = "Button4" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(-1 * delay), TargetObject = "Button5" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(0 * delay), TargetObject = "Button6" }, }; // The animation can be removed after it has finished. timelineGroup.FillBehavior = FillBehavior.Stop; // Start the animation. #if !XBOX && !WP7 var animationController = AnimationService.StartAnimation(timelineGroup, (IEnumerable<IAnimatableObject>)_buttonStackPanel.Children.OfType<Button>()); #else var animationController = AnimationService.StartAnimation(timelineGroup, _buttonStackPanel.Children.OfType<Button>().Cast<IAnimatableObject>()); #endif // Note: The animation effectively starts when AnimationManager.Update() and Apply() are // called. To start the animation immediately we can call UpdateAndApply() manually. animationController.UpdateAndApply(); }
/// <summary> /// Animates the opacity and offset of a group of controls from their current value to the /// specified value. /// </summary> /// <param name="controls">The UI controls to be animated.</param> /// <param name="opacity">The opacity.</param> /// <param name="offset">The offset.</param> private AnimationController AnimateTo(IList<UIControl> controls, float opacity, Vector2F offset) { TimeSpan duration = TimeSpan.FromSeconds(0.6f); // First, let's define the animation that is going to be applied to a control. // Animate the "Opacity" from its current value to the specified value. var opacityAnimation = new SingleFromToByAnimation { TargetProperty = "Opacity", To = opacity, Duration = duration, EasingFunction = new CubicEase { Mode = EasingMode.EaseIn }, }; // Animate the "RenderTranslation" property from its current value, which is // usually (0, 0), to the specified value. var offsetAnimation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", To = offset, Duration = duration, EasingFunction = new CubicEase { Mode = EasingMode.EaseIn }, }; // Group the opacity and offset animation together using a TimelineGroup. var timelineGroup = new TimelineGroup(); timelineGroup.Add(opacityAnimation); timelineGroup.Add(offsetAnimation); // Now we duplicate this animation by creating new TimelineClips that wrap the TimelineGroup. // A TimelineClip is assigned to a target by setting the TargetObject property. var storyboard = new TimelineGroup(); for (int i = 0; i < controls.Count; i++) { var clip = new TimelineClip(timelineGroup) { TargetObject = controls[i].Name, // Assign the clip to the i-th control. Delay = TimeSpan.FromSeconds(0.04f * i), FillBehavior = FillBehavior.Hold, // Hold the last value of the animation when it }; // because we don't want to opacity and offset to // jump back to their original value. storyboard.Add(clip); } // Now we apply the "storyboard" to the group of UI controls. The animation system // will automatically assign individual animations to the right objects and // properties. #if !XBOX && !WP7 var animationController = AnimationService.StartAnimation(storyboard, controls); #else var animationController = AnimationService.StartAnimation(storyboard, controls.Cast<IAnimatableObject>()); #endif animationController.UpdateAndApply(); // The returned animation controller can be used to start, stop, pause, ... all // animations at once. (Note that we don't set AutoRecycle here, because we will // explicitly stop and recycle the animations in the code above.) return animationController; }
// The following code contains two helper methods to animate the opacity and offset // of a group of UI controls. The methods basically do the same, they animate the // properties from/to a specific value. However the methods demonstrate two different // approaches. // // The AnimateFrom method uses a more direct approach. It directly starts an // animation for each UI control in list, thereby creating several independently // running animations. // // The AnimateTo method uses a more declarative approach. All animations are // defined and assigned to the target objects by setting the name of the UI control // in the TargetObject property. Then all animations are grouped together into // a single animation. When the resulting animation is started the animation system // creates the required animation instances and assigns the instances to the correct // objects and properties by matching the TargetObject and TargetProperty with the // name of the UI controls and their properties. // // Both methods achieve a similar result. The advantage of the first method is more // direct control. The advantage of the seconds method is that only a single animation // controller is required to control all animations at once. /// <summary> /// Animates the opacity and offset of a group of controls from the specified value to their /// current value. /// </summary> /// <param name="controls">The UI controls to be animated.</param> /// <param name="opacity">The initial opacity.</param> /// <param name="offset">The initial offset.</param> private void AnimateFrom(IList<UIControl> controls, float opacity, Vector2F offset) { TimeSpan duration = TimeSpan.FromSeconds(0.8); // First, let's define the animation that is going to be applied to a control. // Animate the "Opacity" from the specified value to its current value. var opacityAnimation = new SingleFromToByAnimation { TargetProperty = "Opacity", From = opacity, Duration = duration, EasingFunction = new CubicEase { Mode = EasingMode.EaseOut }, }; // Animate the "RenderTranslation" property from the specified offset to its // its current value, which is usually (0, 0). var offsetAnimation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", From = offset, Duration = duration, EasingFunction = new CubicEase { Mode = EasingMode.EaseOut }, }; // Group the opacity and offset animation together using a TimelineGroup. var timelineGroup = new TimelineGroup(); timelineGroup.Add(opacityAnimation); timelineGroup.Add(offsetAnimation); // Run the animation on each control using a negative delay to give the first controls // a slight head start. var numberOfControls = controls.Count; for (int i = 0; i < controls.Count; i++) { var clip = new TimelineClip(timelineGroup) { Delay = TimeSpan.FromSeconds(-0.04 * (numberOfControls - i)), FillBehavior = FillBehavior.Stop, // Stop and remove the animation when it is done. }; var animationController = AnimationService.StartAnimation(clip, controls[i]); animationController.UpdateAndApply(); // Enable "auto-recycling" to ensure that the animation resources are recycled once // the animation stops or the target objects are garbage collected. animationController.AutoRecycle(); } }