public EasingSample(Microsoft.Xna.Framework.Game game) : base(game) { // Initialize array of easing functions. _easingFunctions = new EasingFunction[] { null, new BackEase { Amplitude = 0.5f }, new BounceEase { Bounces = 3, Bounciness = 3 }, new CircleEase(), new CubicEase(), new ElasticEase { Oscillations = 3, Springiness = 10 }, new ExponentialEase(), new LogarithmicEase(), new HermiteEase(), new PowerEase { Power = 2 }, new QuadraticEase(), new QuinticEase(), new SineEase() }; // Create and start a horizontal from/to animation. Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; _fromToAnimation = new SingleFromToByAnimation { From = bounds.Left + 200, To = bounds.Right - 200, Duration = TimeSpan.FromSeconds(1.5), EasingFunction = _easingFunctions[_selectedEasingFunctionIndex], }; _animationController = AnimationService.StartAnimation(_fromToAnimation, _animatableFloat); _animationController.UpdateAndApply(); }
public void CreateInstanceTest() { var animation1 = new SingleFromToByAnimation(); var animation2 = new SingleFromToByAnimation(); var animation3 = new SingleFromToByAnimation(); var childGroup = new TimelineGroup(); childGroup.Add(animation2); childGroup.Add(animation3); var rootGroup = new TimelineGroup(); rootGroup.Add(animation1); rootGroup.Add(childGroup); var animationInstance = rootGroup.CreateInstance(); Assert.IsNotNull(animationInstance); Assert.AreEqual(2, animationInstance.Children.Count); Assert.That(animationInstance.Children[0], Is.TypeOf<AnimationInstance<float>>()); Assert.That(animationInstance.Children[0].Animation, Is.EqualTo(animation1)); Assert.That(animationInstance.Children[1], Is.TypeOf<AnimationInstance>()); Assert.That(animationInstance.Children[1].Animation, Is.EqualTo(childGroup)); Assert.That(animationInstance.Children[1].Children[0], Is.TypeOf<AnimationInstance<float>>()); Assert.That(animationInstance.Children[1].Children[0].Animation, Is.EqualTo(animation2)); Assert.That(animationInstance.Children[1].Children[1], Is.TypeOf<AnimationInstance<float>>()); Assert.That(animationInstance.Children[1].Children[1].Animation, Is.EqualTo(animation3)); }
public void AnimationWeight() { var manager = new AnimationManager(); var property = new AnimatableProperty <float>(); var animation = new SingleFromToByAnimation { Duration = TimeSpan.FromSeconds(1.0), From = 100.0f, To = 200.0f, }; var controller = manager.StartAnimation(animation, property); controller.AutoRecycle(); controller.UpdateAndApply(); Assert.AreEqual(1.0f, controller.Weight); Assert.AreEqual(100.0f, property.Value); controller.Weight = 0.5f; manager.Update(TimeSpan.Zero); manager.ApplyAnimations(); Assert.AreEqual(50.0f, property.Value); controller.Stop(); Assert.IsNaN(controller.Weight); }
public FadingWindow(IServiceLocator services) : base(services) { Title = "FadingWindow"; Width = 200; Height = 100; Content = new TextBlock { Margin = new Vector4(8), Text = "The 'Opacity' of this window is animated.", WrapText = true, }; LoadingAnimation = new SingleFromToByAnimation { TargetProperty = "Opacity", // Transition the property UIControl.Opacity From = 0, // from 0 to its actual value Duration = TimeSpan.FromSeconds(0.3), // over a duration of 0.3 seconds. }; ClosingAnimation = new SingleFromToByAnimation { TargetProperty = "Opacity", // Transition the property UIControl.Opacity To = 0, // from its current value to 0 Duration = TimeSpan.FromSeconds(0.3), // over a duration 0.3 seconds. }; }
public void EasingFunctionTest() { var animation = new SingleFromToByAnimation(); animation.From = 0.0f; animation.To = 100.0f; animation.EasingFunction = new CubicEase { Mode = EasingMode.EaseIn }; Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f)); Assert.Greater(25.0f, animation.GetValue(TimeSpan.FromSeconds(0.25), 0.0f, 100.0f)); Assert.Greater(50.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f)); Assert.Greater(75.0f, animation.GetValue(TimeSpan.FromSeconds(0.75), 0.0f, 100.0f)); Assert.AreEqual(100.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f)); animation.EasingFunction = new CubicEase { Mode = EasingMode.EaseOut }; Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f)); Assert.Less(25.0f, animation.GetValue(TimeSpan.FromSeconds(0.25), 0.0f, 100.0f)); Assert.Less(50.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f)); Assert.Less(75.0f, animation.GetValue(TimeSpan.FromSeconds(0.75), 0.0f, 100.0f)); Assert.AreEqual(100.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f)); animation.EasingFunction = new CubicEase { Mode = EasingMode.EaseInOut }; Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f)); Assert.Greater(25.0f, animation.GetValue(TimeSpan.FromSeconds(0.25), 0.0f, 100.0f)); Assert.AreEqual(50.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f)); Assert.Less(75.0f, animation.GetValue(TimeSpan.FromSeconds(0.75), 0.0f, 100.0f)); Assert.AreEqual(100.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f)); }
public void FadeOutAnimation() { var manager = new AnimationManager(); var property = new AnimatableProperty <float>(); var animation = new SingleFromToByAnimation { Duration = TimeSpan.Zero, To = 100.0f, }; var controller = manager.StartAnimation(animation, property); controller.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.AreEqual(AnimationState.Playing, controller.State); controller.Stop(TimeSpan.FromSeconds(1.0)); Assert.AreEqual(100.0f, property.Value); Assert.AreEqual(AnimationState.Playing, controller.State); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(50.0f, property.Value); Assert.AreEqual(AnimationState.Filling, controller.State); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(0.0f, property.Value); Assert.AreEqual(AnimationState.Filling, controller.State); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(0.0f, property.Value); Assert.AreEqual(AnimationState.Stopped, controller.State); }
public void CreateInstanceTest() { var animation1 = new SingleFromToByAnimation(); var animation2 = new SingleFromToByAnimation(); var animation3 = new SingleFromToByAnimation(); var childGroup = new TimelineGroup(); childGroup.Add(animation2); childGroup.Add(animation3); var rootGroup = new TimelineGroup(); rootGroup.Add(animation1); rootGroup.Add(childGroup); var animationInstance = rootGroup.CreateInstance(); Assert.IsNotNull(animationInstance); Assert.AreEqual(2, animationInstance.Children.Count); Assert.That(animationInstance.Children[0], Is.TypeOf <AnimationInstance <float> >()); Assert.That(animationInstance.Children[0].Animation, Is.EqualTo(animation1)); Assert.That(animationInstance.Children[1], Is.TypeOf <AnimationInstance>()); Assert.That(animationInstance.Children[1].Animation, Is.EqualTo(childGroup)); Assert.That(animationInstance.Children[1].Children[0], Is.TypeOf <AnimationInstance <float> >()); Assert.That(animationInstance.Children[1].Children[0].Animation, Is.EqualTo(animation2)); Assert.That(animationInstance.Children[1].Children[1], Is.TypeOf <AnimationInstance <float> >()); Assert.That(animationInstance.Children[1].Children[1].Animation, Is.EqualTo(animation3)); }
public void InvalidParameters() { var objectA = new AnimatableObject("ObjectA"); var objectB = new AnimatableObject("ObjectA"); var property = new AnimatableProperty <float>(); var animation = new SingleFromToByAnimation(); var objects = new[] { objectA, objectB }; var manager = new AnimationManager(); // Should throw exception. Assert.That(() => { manager.IsAnimated((IAnimatableObject)null); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.IsAnimated((IAnimatableProperty)null); }, Throws.TypeOf <ArgumentNullException>()); // Should throw exception. Assert.That(() => { manager.CreateController(null, objects); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.CreateController(animation, (IEnumerable <IAnimatableObject>)null); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.CreateController(null, objectA); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.CreateController(animation, (IAnimatableObject)null); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.CreateController(null, property); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.CreateController(animation, (IAnimatableProperty)null); }, Throws.TypeOf <ArgumentNullException>()); // Should throw exception. Assert.That(() => { manager.StartAnimation(null, objects); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(animation, (IEnumerable <IAnimatableObject>)null); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(null, objectA); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(animation, (IAnimatableObject)null); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(null, property); }, Throws.TypeOf <ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(animation, (IAnimatableProperty)null); }, Throws.TypeOf <ArgumentNullException>()); // Should not throw exception. Assert.That(() => manager.StopAnimation((IEnumerable <IAnimatableObject>)null), Throws.Nothing); Assert.That(() => manager.StopAnimation((IAnimatableObject)null), Throws.Nothing); Assert.That(() => manager.StopAnimation((IAnimatableProperty)null), Throws.Nothing); }
public void AnimationWeight() { var manager = new AnimationManager(); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation { Duration = TimeSpan.FromSeconds(1.0), From = 100.0f, To = 200.0f, }; var controller = manager.StartAnimation(animation, property); controller.AutoRecycle(); controller.UpdateAndApply(); Assert.AreEqual(1.0f, controller.Weight); Assert.AreEqual(100.0f, property.Value); controller.Weight = 0.5f; manager.Update(TimeSpan.Zero); manager.ApplyAnimations(); Assert.AreEqual(50.0f, property.Value); controller.Stop(); Assert.IsNaN(controller.Weight); }
public void CopyTo() { var blendGroup = new BlendGroup(); ITimeline[] array = new ITimeline[0]; Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(null, 0), Throws.TypeOf <ArgumentNullException>()); Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(array, -1), Throws.TypeOf <ArgumentOutOfRangeException>()); Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(array, 1), Throws.ArgumentException); Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(array, 0), Throws.Nothing); var animation0 = new SingleFromToByAnimation(); var animation1 = new SingleFromToByAnimation(); blendGroup = new BlendGroup { animation0, animation1 }; array = new ITimeline[1]; Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(array, 0), Throws.ArgumentException); array = new ITimeline[2]; ((IList <ITimeline>)blendGroup).CopyTo(array, 0); Assert.AreEqual(animation0, array[0]); Assert.AreEqual(animation1, array[1]); array = new ITimeline[3]; ((IList <ITimeline>)blendGroup).CopyTo(array, 1); Assert.AreEqual(null, array[0]); Assert.AreEqual(animation0, array[1]); Assert.AreEqual(animation1, array[2]); }
// Called when the "Animate" button was clicked. private void OnButtonClicked(object sender, EventArgs eventArgs) { // Get the selected easing function from the DropDownButton. EasingFunction easingFunction = (EasingFunction)_functionDropDown.Items[_functionDropDown.SelectedIndex]; // Set the selected easing mode. easingFunction.Mode = (EasingMode)_modeDropDown.Items[_modeDropDown.SelectedIndex]; // The current slider value: float startValue = _slider.Value; // Set the slider to the target value. _slider.Value = (startValue > 0.5f) ? 0 : 1; // Create a from-animation that uses the easing function. It animates the slider // value from startValue to the new value. SingleFromToByAnimation animation = new SingleFromToByAnimation { TargetProperty = "Value", From = startValue, Duration = TimeSpan.FromSeconds(1), EasingFunction = easingFunction, FillBehavior = FillBehavior.Stop, // Stop the animation when it is finished. }; // Start the animation. // (Use the Replace transition to replace any currently running animations. // This is necessary because the user could press the Animate button while // an animation is running.) _animationService.StartAnimation(animation, _slider, AnimationTransitions.Replace()) .UpdateAndApply(); // Apply new animation value immediately. }
public void GetSelfAndAncestors() { var animationA = new TimelineGroup(); var animationB = new SingleFromToByAnimation(); var animationC = new SingleFromToByAnimation(); var animationD = new TimelineGroup(); var animationE = new TimelineGroup(); var animationF = new SingleFromToByAnimation(); var animationG = new TimelineGroup(); animationA.Add(animationB); animationA.Add(animationC); animationA.Add(animationD); animationD.Add(animationE); animationD.Add(animationF); animationE.Add(animationG); Assert.That(() => AnimationHelper.GetSelfAndAncestors(null), Throws.TypeOf <ArgumentNullException>()); var animationInstance = animationA.CreateInstance(); var ancestors = animationInstance.Children[2].Children[0].GetSelfAndAncestors().ToArray(); Assert.AreEqual(3, ancestors.Length); Assert.AreEqual(animationInstance.Children[2].Children[0], ancestors[0]); Assert.AreEqual(animationInstance.Children[2], ancestors[1]); Assert.AreEqual(animationInstance, ancestors[2]); }
public FadingWindow(IServiceLocator services) : base(services) { Title = "FadingWindow"; Width = 200; Height = 100; Content = new TextBlock { Margin = new Vector4F(8), Text = "The 'Opacity' of this window is animated.", WrapText = true, }; LoadingAnimation = new SingleFromToByAnimation { TargetProperty = "Opacity", // Transition the property UIControl.Opacity From = 0, // from 0 to its actual value Duration = TimeSpan.FromSeconds(0.3), // over a duration of 0.3 seconds. }; ClosingAnimation = new SingleFromToByAnimation { TargetProperty = "Opacity", // Transition the property UIControl.Opacity To = 0, // from its current value to 0 Duration = TimeSpan.FromSeconds(0.3), // over a duration 0.3 seconds. }; }
public void StartStopAnimationWithinOneFrame() { var property = new AnimatableProperty <float> { Value = 123.4f }; var manager = new AnimationManager(); var animation = new SingleFromToByAnimation { Duration = TimeSpan.Zero, To = 234.5f, FillBehavior = FillBehavior.Stop, }; var controller = manager.CreateController(animation, property); Assert.AreEqual(123.4f, property.Value); // Start controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(234.5f, property.Value); // Stop controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(123.4f, property.Value); }
public void GetDescendantsDepthFirst() { var animationA = new TimelineGroup(); var animationB = new SingleFromToByAnimation(); var animationC = new SingleFromToByAnimation(); var animationD = new TimelineGroup(); var animationE = new TimelineGroup(); var animationF = new SingleFromToByAnimation(); var animationG = new TimelineGroup(); animationA.Add(animationB); animationA.Add(animationC); animationA.Add(animationD); animationD.Add(animationE); animationD.Add(animationF); animationE.Add(animationG); Assert.That(() => AnimationHelper.GetDescendants(null), Throws.TypeOf <ArgumentNullException>()); var animationInstance = animationA.CreateInstance(); var descendants = animationInstance.GetDescendants().ToArray(); Assert.AreEqual(6, descendants.Length); Assert.AreEqual(animationInstance.Children[0], descendants[0]); Assert.AreEqual(animationInstance.Children[1], descendants[1]); Assert.AreEqual(animationInstance.Children[2], descendants[2]); Assert.AreEqual(animationInstance.Children[2].Children[0], descendants[3]); Assert.AreEqual(animationInstance.Children[2].Children[0].Children[0], descendants[4]); Assert.AreEqual(animationInstance.Children[2].Children[1], descendants[5]); }
public void ShouldDoNothingIfInvalid() { var manager = new AnimationManager(); var property = new AnimatableProperty <float>(); var animation = new SingleFromToByAnimation(); var controller = manager.CreateController(animation, property); controller.Recycle(); Assert.IsFalse(controller.IsValid); // The following has no effect. controller.AutoRecycleEnabled = false; controller.Time = TimeSpan.Zero; controller.AutoRecycle(); controller.Recycle(); controller.Pause(); controller.Resume(); controller.Stop(); controller.Stop(TimeSpan.Zero); controller.Stop(TimeSpan.FromSeconds(1.0)); // Only Start and UpdateAndApply should throw an exceptions. Assert.That(() => controller.Start(), Throws.TypeOf <AnimationException>()); Assert.That(() => controller.UpdateAndApply(), Throws.TypeOf <AnimationException>()); }
public BasicAnimationSample(Microsoft.Xna.Framework.Game game) : base(game) { var titleSafeArea = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; float minX = titleSafeArea.Left + 100; float maxX = titleSafeArea.Right - 100; // A from/to/by animation that animates a float value from minX to maxX over 2 seconds // using an easing function smooth movement. SingleFromToByAnimation xAnimation = new SingleFromToByAnimation { From = minX, To = maxX, Duration = TimeSpan.FromSeconds(2), EasingFunction = new CubicEase { Mode = EasingMode.EaseInOut }, }; // From-To-By animations do not loop by default. // Use an AnimationClip to turn the 2 second xAnimation into an animation that // oscillates forever. _oscillatingXAnimation = new AnimationClip<float>(xAnimation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; // A color key-frame animation. ColorKeyFrameAnimation colorAnimation = new ColorKeyFrameAnimation { //EnableInterpolation = true, // Interpolation is enabled by default. }; // Add the key-frames. colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(0.0), Color.Red)); colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(0.5), Color.Orange)); colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(1.0), Color.Yellow)); colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(1.5), Color.Green)); colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(2.0), Color.Blue)); colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(2.5), Color.Indigo)); colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(3.0), Color.Violet)); // The last-key frame defines the length of the animation (3.5 seconds). This is a // "loop frame", which means the value is the same as in the first key to create a looping // animation. colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(3.5), Color.Red)); // If the key-frames are not sorted, call Sort(). //colorAnimation.KeyFrames.Sort(); // Use an AnimationClip to turn the 3.5 second colorAnimation into an animation that // loops forever. _loopedColorAnimation = new AnimationClip<Color>(colorAnimation) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; StartAnimations(); }
public void CreateInstanceTest() { var animationInstance = new SingleFromToByAnimation().CreateInstance(); Assert.IsNotNull(animationInstance); var timelineInstance = ((ITimeline)new SingleFromToByAnimation()).CreateInstance(); Assert.IsNotNull(timelineInstance); }
public void AnimateProperty() { var property = new AnimatableProperty <float> { Value = 10.0f }; var animationA = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, TargetObject = "ObjectA", // Should be ignored. TargetProperty = "PropertyA", // Should be ignored. }; var animationB = new SingleFromToByAnimation { From = 200.0f, To = 300.0f, TargetObject = "ObjectB", // Should be ignored. TargetProperty = "PropertyB", // Should be ignored. }; var animationGroup = new TimelineGroup(); animationGroup.Add(animationA); animationGroup.Add(animationB); var manager = new AnimationManager(); // Should assign both animations to 'property'. var controller = manager.CreateController(animationGroup, property); Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[0]).Property); Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[1]).Property); Assert.IsFalse(manager.IsAnimated(property)); // When started then animationB (last in the composition chain) should be active. controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(200.0f, property.Value); Assert.IsTrue(manager.IsAnimated(property)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(10.0f, property.Value); Assert.IsFalse(manager.IsAnimated(property)); // Same test for AnimationManager.StartAnimation() controller = manager.StartAnimation(animationGroup, property); controller.UpdateAndApply(); Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[0]).Property); Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(200.0f, property.Value); Assert.IsTrue(manager.IsAnimated(property)); manager.StopAnimation(property); manager.UpdateAndApplyAnimation(property); Assert.AreEqual(10.0f, property.Value); Assert.IsFalse(manager.IsAnimated(property)); }
public void BlendGroupWithTwoAnimationsSynchronized() { var property1 = new AnimatableProperty <float> { Value = 123.45f }; var blendGroup = new BlendGroup { FillBehavior = FillBehavior.Stop }; var animation1 = new SingleFromToByAnimation { From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0) }; var animation2 = new SingleFromToByAnimation { From = 100, To = 300, Duration = TimeSpan.FromSeconds(2.0) }; blendGroup.Add(animation1); blendGroup.Add(animation2); Assert.AreEqual(1.0f, blendGroup.GetWeight(0)); Assert.AreEqual(1.0f, blendGroup.GetWeight(1)); Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration()); blendGroup.SynchronizeDurations(); Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration()); var manager = new AnimationManager(); var controller = manager.StartAnimation(blendGroup, property1); controller.UpdateAndApply(); Assert.AreEqual(50.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.75)); // t = 0.75 manager.ApplyAnimations(); Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration()); Assert.AreEqual(0.5f * 50.0f + 0.5f * 200.0f, property1.Value); blendGroup.SetWeight(0, 0); Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.FromSeconds(0.25)); // t = 1.0 manager.ApplyAnimations(); Assert.AreEqual(200.0f, property1.Value); blendGroup.SetWeight(0, 10); blendGroup.SetWeight(1, 0); Assert.AreEqual(TimeSpan.FromSeconds(1.0), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.Zero); // t = 1.0 manager.ApplyAnimations(); Assert.AreEqual(100.0f, property1.Value); blendGroup.SetWeight(0, 10); blendGroup.SetWeight(1, 1); Assert.AreEqual(new TimeSpan((long)((1.0f * 10.0f / 11.0f + 2.0f * 1.0f / 11.0f) * TimeSpan.TicksPerSecond)), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.FromSeconds(0.5)); // t = 1.5 manager.ApplyAnimations(); Assert.AreEqual(123.45f, property1.Value); Assert.AreEqual(AnimationState.Stopped, controller.State); }
public void ComposeAfterWithFadeIn() { var property = new AnimatableProperty <float> { Value = 100.0f }; var animationA = new SingleFromToByAnimation { Duration = TimeSpan.Zero, To = 200.0f, }; var manager = new AnimationManager(); var controllerA = manager.CreateController(animationA, property); Assert.AreEqual(100.0f, property.Value); controllerA.Start(AnimationTransitions.Compose(TimeSpan.FromSeconds(1.0))); Assert.AreEqual(100.0f, property.Value); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(150.0f, property.Value); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(200.0f, property.Value); var animationB = new SingleFromToByAnimation { Duration = TimeSpan.Zero, By = 10.0f, }; var controllerB = manager.CreateController(animationB, property); Assert.AreEqual(200.0f, property.Value); controllerB.Start(AnimationTransitions.Compose(controllerA.AnimationInstance, TimeSpan.FromSeconds(1.0))); Assert.AreEqual(200.0f, property.Value); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(205.0f, property.Value); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(210.0f, property.Value); controllerA.Stop(); controllerA.UpdateAndApply(); Assert.AreEqual(110.0f, property.Value); controllerB.Stop(); controllerB.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); }
/// <summary> /// Called every frame when "Start" state is active. /// </summary> private void OnUpdateStartScreen(object sender, StateEventArgs eventArgs) { if (_exitAnimationIsPlaying) { return; } bool transitionToMenu = false; // Check if the user presses A or START on any connected gamepad. for (var controller = PlayerIndex.One; controller <= PlayerIndex.Four; controller++) { if (InputService.IsDown(Buttons.A, controller) || InputService.IsDown(Buttons.Start, controller)) { // A or START was pressed. Assign this controller to the first "logical player". InputService.SetLogicalPlayer(LogicalPlayerIndex.One, controller); transitionToMenu = true; } } if (InputService.IsDown(MouseButtons.Left) || InputService.IsDown(Keys.Enter) || InputService.IsDown(Keys.Escape) || InputService.IsDown(Keys.Space)) { // The users has pressed the left mouse button or a key on the keyboard. if (!InputService.GetLogicalPlayer(LogicalPlayerIndex.One).HasValue) { // No controller has been assigned to the first "logical player". Maybe // there is no gamepad connected. // --> Just guess which controller is the primary player and continue. InputService.SetLogicalPlayer(LogicalPlayerIndex.One, PlayerIndex.One); } transitionToMenu = true; } if (transitionToMenu) { // Play a fade-out animation which changes the opacity from its current // value to 0. var fadeOutAnimation = new SingleFromToByAnimation { To = 0, // Animate the opacity from the current value to 0 Duration = TimeSpan.FromSeconds(0.5), // over a duration of 0.5 seconds. }; var opacityProperty = _startTextBlock.Properties.Get <float>(TextBlock.OpacityPropertyId).AsAnimatable(); _exitAnimationController = AnimationService.StartAnimation(fadeOutAnimation, opacityProperty); // When the fade-out animation finished trigger the transition from the "Start" // screen to the "Menu" screen. _exitAnimationController.Completed += (s, e) => _stateMachine.States.ActiveState.Transitions["StartToMenu"].Fire(); _exitAnimationIsPlaying = true; } }
public void AnimateTo() { var animation = new SingleFromToByAnimation(); animation.From = null; animation.To = 20.0f; animation.By = null; Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f)); Assert.AreEqual(10.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f)); Assert.AreEqual(20.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f)); }
public void CreateInstanceTest() { var animationInstance = new SingleFromToByAnimation().CreateInstance(); Assert.IsNotNull(animationInstance); var timelineInstance = ((ITimeline) new SingleFromToByAnimation()).CreateInstance(); Assert.IsNotNull(timelineInstance); }
// 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 ShouldIgnoreByIfToIsSet() { var animation = new SingleFromToByAnimation(); animation.From = null; animation.To = 40.0f; animation.By = 100.0f; Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f)); Assert.AreEqual(20.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f)); Assert.AreEqual(40.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f)); }
public void TargetObjectTest() { var animation = new SingleFromToByAnimation(); Assert.IsNull(animation.TargetObject); animation.TargetObject = ""; Assert.IsEmpty(animation.TargetObject); animation.TargetObject = "Object XY"; Assert.AreEqual("Object XY", animation.TargetObject); }
public void SetAnimationTime() { var manager = new AnimationManager(); var property = new AnimatableProperty <float>(); var animation = new SingleFromToByAnimation(); var controller = manager.StartAnimation(animation, property); Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time); controller.Time = TimeSpan.FromSeconds(0.5); Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.Time); Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.AnimationInstance.Time); }
public void TargetPropertyTest() { var animation = new SingleFromToByAnimation(); Assert.IsNull(animation.TargetProperty); animation.TargetProperty = ""; Assert.IsEmpty(animation.TargetProperty); animation.TargetProperty = "Property XY"; Assert.AreEqual("Property XY", animation.TargetProperty); }
/// <inheritdoc/> protected override void OnInitialize(AnimationManager animationManager) { // Start fade-out animation on animation weight. var fadeOutAnimation = new SingleFromToByAnimation { To = 0, Duration = _fadeOutDuration, EasingFunction = DefaultEase, FillBehavior = FillBehavior.Stop, }; _fadeOutController = animationManager.StartAnimation(fadeOutAnimation, AnimationInstance.WeightProperty); }
public void BlendGroupWithOneAnimation() { var property1 = new AnimatableProperty <float> { Value = 123.45f }; var blendGroup = new BlendGroup { FillBehavior = FillBehavior.Stop }; var animation = new SingleFromToByAnimation { From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0) }; blendGroup.Add(animation); Assert.AreEqual(1.0f, blendGroup.GetWeight(0)); Assert.AreEqual(1.0f, blendGroup.GetWeight(animation)); blendGroup.SetWeight(0, 10.0f); Assert.AreEqual(10.0f, blendGroup.GetWeight(0)); Assert.AreEqual(10.0f, blendGroup.GetWeight(animation)); blendGroup.SetWeight(animation, 0.5f); Assert.AreEqual(0.5f, blendGroup.GetWeight(0)); Assert.AreEqual(0.5f, blendGroup.GetWeight(animation)); var manager = new AnimationManager(); var controller = manager.StartAnimation(blendGroup, property1); controller.UpdateAndApply(); Assert.AreEqual(0.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(25.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(50.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(75.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(100.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(123.45f, property1.Value); Assert.AreEqual(AnimationState.Stopped, controller.State); }
private AnimationController _exitAnimationController; // Controls the fade-out animation. /// <summary> /// Called when "Start" state is entered. /// </summary> private void OnEnterStartScreen(object sender, StateEventArgs eventArgs) { // Show the "Press Start button" text centered on the screen. _startTextBlock = new TextBlock { Name = "StartTextBlock", Text = "Press Start button", HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }; _uiScreen.Children.Add(_startTextBlock); // The text should pulse to indicate that a user interaction is required. // To achieve this we can animate the opacity of the TextBlock. var opacityAnimation = new SingleFromToByAnimation { From = 1, // Animate from opaque (Opacity == 1) To = 0.25f, // to nearly transparent (Opacity == 0.25) Duration = TimeSpan.FromSeconds(0.5), // over a duration of 0.5 seconds. EasingFunction = new SineEase { Mode = EasingMode.EaseInOut } }; // A SingleFromToByAnimation plays only once, but the animation should be // played back-and-forth until the user presses a button. // We need wrap the SingleFromToByAnimation in an AnimationClip or TimelineClip. // Animation clips can be used to cut and loop other animations. var loopingOpacityAnimation = new AnimationClip <float>(opacityAnimation) { LoopBehavior = LoopBehavior.Oscillate, // Play back-and-forth. Duration = TimeSpan.MaxValue // Loop forever. }; // We want to apply the animation to the "Opacity" property of the TextBlock. // All "game object properties" of a UIControl can be made "animatable". // First, get a handle to the "Opacity" property. var opacityProperty = _startTextBlock.Properties.Get <float>(TextBlock.OpacityPropertyId); // Then cast the "Opacity" property to an IAnimatableProperty. var animatableOpacityProperty = opacityProperty.AsAnimatable(); // Start the pulse animation. var animationController = AnimationService.StartAnimation(loopingOpacityAnimation, animatableOpacityProperty); // Enable "automatic recycling". This step is optional. It ensures that the // associated resources are recycled when either the animation is stopped or // the target object (the TextBlock) is garbage collected. // (The associated resources will be reused by future animations, which will // reduce the number of required memory allocations at runtime.) animationController.AutoRecycle(); }
public void CheckDefaultValues() { var animation = new SingleFromToByAnimation(); 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); }
public void ShouldThrowWhenAnimationWeightIsOutOfRange() { var animationInstance = new SingleFromToByAnimation().CreateInstance(); // Valid range. animationInstance.Weight = 0.0f; animationInstance.Weight = 1.0f; // Invalid range. Assert.That(() => animationInstance.Weight = -0.1f, Throws.TypeOf <ArgumentOutOfRangeException>()); Assert.That(() => animationInstance.Weight = 1.1f, Throws.TypeOf <ArgumentOutOfRangeException>()); Assert.That(() => animationInstance.Weight = float.NaN, Throws.TypeOf <ArgumentOutOfRangeException>()); }
public void ShouldThrowWhenAnimationWeightIsOutOfRange() { var animationInstance = new SingleFromToByAnimation().CreateInstance(); // Valid range. animationInstance.Weight = 0.0f; animationInstance.Weight = 1.0f; // Invalid range. Assert.That(() => animationInstance.Weight = -0.1f, Throws.TypeOf<ArgumentOutOfRangeException>()); Assert.That(() => animationInstance.Weight = 1.1f, Throws.TypeOf<ArgumentOutOfRangeException>()); Assert.That(() => animationInstance.Weight = float.NaN, Throws.TypeOf<ArgumentOutOfRangeException>()); }
/// <inheritdoc/> protected override void OnInitialize(AnimationManager animationManager) { // Start fade-in animation on animation weight. var fadeInAnimation = new SingleFromToByAnimation { From = 0, Duration = _fadeInDuration, EasingFunction = DefaultEase, FillBehavior = FillBehavior.Stop, }; animationManager.StartAnimation(fadeInAnimation, AnimationInstance.WeightProperty); animationManager.Add(AnimationInstance, HandoffBehavior.Compose, _previousAnimation); animationManager.Remove(this); }
public void ShouldRemoveAnimationsIfInactive() { var obj = new AnimatableObject("TestObject"); var property = new AnimatableProperty <float>(); obj.Properties.Add("Value", property); var animation = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, TargetProperty = "Value", }; var manager = new AnimationManager(); var controllerA = manager.StartAnimation(animation, obj); controllerA.AutoRecycle(); controllerA.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.IsTrue(controllerA.IsValid); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(150.0f, property.Value); Assert.IsTrue(controllerA.IsValid); // Replace animation instance with new instance. var controllerB = manager.StartAnimation(animation, obj); controllerB.AutoRecycle(); controllerB.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.IsTrue(controllerA.IsValid); Assert.IsTrue(controllerB.IsValid); // controllerA should be removed automatically. // (Note: Cleanup is done incrementally, not every frame. // It is okay if it takes a few updates.) manager.Update(TimeSpan.FromSeconds(0.1)); manager.Update(TimeSpan.FromSeconds(0.1)); manager.Update(TimeSpan.FromSeconds(0.1)); manager.Update(TimeSpan.FromSeconds(0.1)); manager.Update(TimeSpan.FromSeconds(0.1)); manager.ApplyAnimations(); Assert.AreEqual(150.0f, property.Value); Assert.IsFalse(controllerA.IsValid); Assert.IsTrue(controllerB.IsValid); }
/// <inheritdoc/> protected override void OnInitialize(AnimationManager animationManager) { // Start fade-in animation on animation weight. var fadeInAnimation = new SingleFromToByAnimation { From = 0, Duration = _fadeInDuration, EasingFunction = DefaultEase, FillBehavior = FillBehavior.Stop, }; _fadeInController = animationManager.StartAnimation(fadeInAnimation, AnimationInstance.WeightProperty); // Add animation. animationManager.Add(AnimationInstance, HandoffBehavior.Compose, null); }
public void AutoRecycleEnabled() { var manager = new AnimationManager(); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation(); var controller = manager.CreateController(animation, property); controller.Start(); controller.Stop(); Assert.IsTrue(controller.IsValid); controller.AutoRecycleEnabled = true; controller.Start(); controller.Stop(); Assert.IsFalse(controller.IsValid); }
public void AdditiveAnimation() { var property = new AnimatableProperty<float> { Value = 123.4f }; var manager = new AnimationManager(); // Start base animation. var animation0 = new SingleFromToByAnimation { Duration = TimeSpan.FromSeconds(1.0), To = 234.5f, FillBehavior = FillBehavior.Stop, }; var controller0 = manager.StartAnimation(animation0, property); Assert.AreEqual(123.4f, property.Value); // Start additive animation. var animation1 = new SingleFromToByAnimation { Duration = TimeSpan.FromSeconds(1.0), From = 0.0f, To = 10.0f, IsAdditive = true, FillBehavior = FillBehavior.Hold, }; var controller1 = manager.StartAnimation(animation1, property, AnimationTransitions.Compose()); Assert.AreEqual(123.4f, property.Value); manager.Update(TimeSpan.FromSeconds(1.0)); Assert.AreEqual(123.4f, property.Value); manager.ApplyAnimations(); Assert.AreEqual(234.5f + 10.0f, property.Value); manager.Update(new TimeSpan(166666)); Assert.AreEqual(234.5f + 10.0f, property.Value); manager.ApplyAnimations(); Assert.AreEqual(123.4f + 10.0f, property.Value); // Stop additive animation. controller1.Stop(); controller1.UpdateAndApply(); Assert.AreEqual(123.4f, property.Value); }
public void BlendGroupWithOneAnimation() { var property1 = new AnimatableProperty<float> { Value = 123.45f }; var blendGroup = new BlendGroup { FillBehavior = FillBehavior.Stop }; var animation = new SingleFromToByAnimation { From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0) }; blendGroup.Add(animation); Assert.AreEqual(1.0f, blendGroup.GetWeight(0)); Assert.AreEqual(1.0f, blendGroup.GetWeight(animation)); blendGroup.SetWeight(0, 10.0f); Assert.AreEqual(10.0f, blendGroup.GetWeight(0)); Assert.AreEqual(10.0f, blendGroup.GetWeight(animation)); blendGroup.SetWeight(animation, 0.5f); Assert.AreEqual(0.5f, blendGroup.GetWeight(0)); Assert.AreEqual(0.5f, blendGroup.GetWeight(animation)); var manager = new AnimationManager(); var controller = manager.StartAnimation(blendGroup, property1); controller.UpdateAndApply(); Assert.AreEqual(0.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(25.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(50.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(75.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(100.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(123.45f, property1.Value); Assert.AreEqual(AnimationState.Stopped, controller.State); }
public void AnimateProperty() { var testObject = new TestObject { Value = 10.0f }; Func<float> getter = () => testObject.Value; Action<float> setter = f => { testObject.Value = f; }; var property = new DelegateAnimatableProperty<float>(null, null); var animation = new SingleFromToByAnimation { From = 100, To = 200, Duration = TimeSpan.FromSeconds(1.0), IsAdditive = true, }; var manager = new AnimationManager(); var controller = manager.StartAnimation(animation, property); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); property.GetValue = getter; property.SetValue = setter; manager.ApplyAnimations(); Assert.AreEqual(150.0f, testObject.Value); Assert.IsTrue(((IAnimatableProperty)property).IsAnimated); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(200.0f, testObject.Value); Assert.IsTrue(((IAnimatableProperty)property).IsAnimated); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(200.0f, testObject.Value); Assert.IsFalse(((IAnimatableProperty)property).IsAnimated); }
protected override void LoadContent() { Rectangle bounds = GraphicsDevice.Viewport.TitleSafeArea; // A single from/to animation. SingleFromToByAnimation fromToAnimation = new SingleFromToByAnimation { From = bounds.Top + 200, To = bounds.Bottom - 200, Duration = TimeSpan.FromSeconds(2), EasingFunction = new SineEase { Mode = EasingMode.EaseInOut }, }; // Create an animation that oscillates forever. AnimationClip<float> loopedSingleAnimationX = new AnimationClip<float>(fromToAnimation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; // Create an animation that oscillates forever. The animations starts 1 second into // the fromToAnimation - that means, loopedSingleAnimationX is 1 second "behind" this // animation. AnimationClip<float> loopedSingleAnimationY = new AnimationClip<float>(fromToAnimation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, Delay = TimeSpan.FromSeconds(-1), }; // Create a composite animation that combines the two float animations to animate // a Vector2 value. Vector2Animation compositeAnimation = new Vector2Animation(loopedSingleAnimationX, loopedSingleAnimationY); // Start animation. AnimationService.StartAnimation(compositeAnimation, _animatablePosition); base.LoadContent(); }
public void ComposeAfter() { var property = new AnimatableProperty<float> { Value = 100.0f }; var animationA = new SingleFromToByAnimation { Duration = TimeSpan.Zero, To = 200.0f, }; var manager = new AnimationManager(); var controllerA = manager.CreateController(animationA, property); Assert.AreEqual(100.0f, property.Value); controllerA.Start(AnimationTransitions.Compose()); controllerA.UpdateAndApply(); Assert.AreEqual(200.0f, property.Value); var animationB = new SingleFromToByAnimation { Duration = TimeSpan.Zero, By = 10.0f, }; var controllerB = manager.CreateController(animationB, property); Assert.AreEqual(200.0f, property.Value); controllerB.Start(AnimationTransitions.Compose(controllerB.AnimationInstance)); controllerB.UpdateAndApply(); Assert.AreEqual(210.0f, property.Value); controllerA.Stop(); controllerA.UpdateAndApply(); Assert.AreEqual(110.0f, property.Value); controllerB.Stop(); controllerB.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); }
public void AnimationBlending() { var animation = new SingleFromToByAnimation { From = 100, To = 200, IsAdditive = true, Duration = TimeSpan.FromSeconds(1), }; var animationInstance = animation.CreateInstance() as AnimationInstance<float>; animationInstance.Time = TimeSpan.FromSeconds(0.5); animationInstance.Weight = 0.0f; Assert.AreEqual(1.0f, animationInstance.GetValue(1.0f, 2.0f)); animationInstance.Weight = 1.0f; Assert.AreEqual(151.0f, animationInstance.GetValue(1.0f, 2.0f)); animationInstance.Weight = 0.75f; Assert.AreEqual(1.0f + 0.75f * 150.0f, animationInstance.GetValue(1.0f, 2.0f)); }
public void StopAnimationImmediately() { var manager = new AnimationManager(); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, }; var controller = manager.StartAnimation(animation, property); controller.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); controller.Stop(TimeSpan.Zero); controller.UpdateAndApply(); Assert.AreEqual(0.0f, property.Value); }
public void CopyTo() { var blendGroup = new BlendGroup(); ITimeline[] array = new ITimeline[0]; Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(null, 0), Throws.TypeOf<ArgumentNullException>()); Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(array, -1), Throws.TypeOf<ArgumentOutOfRangeException>()); Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(array, 1), Throws.ArgumentException); Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(array, 0), Throws.Nothing); var animation0 = new SingleFromToByAnimation(); var animation1 = new SingleFromToByAnimation(); blendGroup = new BlendGroup { animation0, animation1 }; array = new ITimeline[1]; Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(array, 0), Throws.ArgumentException); array = new ITimeline[2]; ((IList<ITimeline>)blendGroup).CopyTo(array, 0); Assert.AreEqual(animation0, array[0]); Assert.AreEqual(animation1, array[1]); array = new ITimeline[3]; ((IList<ITimeline>)blendGroup).CopyTo(array, 1); Assert.AreEqual(null, array[0]); Assert.AreEqual(animation0, array[1]); Assert.AreEqual(animation1, array[2]); }
public void ShouldDoNothingIfInvalid() { var manager = new AnimationManager(); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation(); var controller = manager.CreateController(animation, property); controller.Recycle(); Assert.IsFalse(controller.IsValid); // The following has no effect. controller.AutoRecycleEnabled = false; controller.Time = TimeSpan.Zero; controller.AutoRecycle(); controller.Recycle(); controller.Pause(); controller.Resume(); controller.Stop(); controller.Stop(TimeSpan.Zero); controller.Stop(TimeSpan.FromSeconds(1.0)); // Only Start and UpdateAndApply should throw an exceptions. Assert.That(() => controller.Start(), Throws.TypeOf<AnimationException>()); Assert.That(() => controller.UpdateAndApply(), Throws.TypeOf<AnimationException>()); }
public void Speed() { var manager = new AnimationManager(); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation { Duration = TimeSpan.FromSeconds(1), From = 100.0f, To = 200.0f, }; var controller = manager.StartAnimation(animation, property); controller.AutoRecycle(); controller.UpdateAndApply(); Assert.AreEqual(1.0f, controller.Speed); // Normal speed. controller.Speed = 1.0f; Assert.AreEqual(100.0f, property.Value); manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(125.0f, property.Value); // Double speed. controller.Speed = 2.0f; manager.Update(TimeSpan.FromSeconds(0.25)); manager.ApplyAnimations(); Assert.AreEqual(175.0f, property.Value); // Half speed. controller.Speed = 0.5f; manager.Update(TimeSpan.FromSeconds(0.2)); manager.ApplyAnimations(); Assert.AreEqual(185.0f, property.Value); // Negative speed. controller.Speed = -0.5f; manager.Update(TimeSpan.FromSeconds(0.2)); manager.ApplyAnimations(); Assert.AreEqual(175.0f, property.Value); controller.Stop(); Assert.IsNaN(controller.Speed); }
public void StartAnimation() { var manager = new AnimationManager(); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation(); var controller = manager.StartAnimation(animation, property); Assert.AreEqual(manager, controller.AnimationService); Assert.AreEqual(animation, controller.AnimationInstance.Animation); Assert.IsFalse(controller.AutoRecycleEnabled); Assert.IsTrue(controller.IsValid); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Playing, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time); }
public void EnumeratorTest() { var blendGroup = new BlendGroup(); Assert.AreEqual(0, blendGroup.Count()); var animation0 = new SingleFromToByAnimation(); var animation1 = new SingleFromToByAnimation(); blendGroup = new BlendGroup { animation0, animation1 }; Assert.AreEqual(2, blendGroup.Count()); Assert.AreEqual(animation0, blendGroup.ElementAt(0)); Assert.AreEqual(animation1, blendGroup.ElementAt(1)); }
public void BlendGroupWithTwoAnimationsSynchronized() { var property1 = new AnimatableProperty<float> { Value = 123.45f }; var blendGroup = new BlendGroup { FillBehavior = FillBehavior.Stop }; var animation1 = new SingleFromToByAnimation { From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0) }; var animation2 = new SingleFromToByAnimation { From = 100, To = 300, Duration = TimeSpan.FromSeconds(2.0) }; blendGroup.Add(animation1); blendGroup.Add(animation2); Assert.AreEqual(1.0f, blendGroup.GetWeight(0)); Assert.AreEqual(1.0f, blendGroup.GetWeight(1)); Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration()); blendGroup.SynchronizeDurations(); Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration()); var manager = new AnimationManager(); var controller = manager.StartAnimation(blendGroup, property1); controller.UpdateAndApply(); Assert.AreEqual(50.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.75)); // t = 0.75 manager.ApplyAnimations(); Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration()); Assert.AreEqual(0.5f * 50.0f + 0.5f * 200.0f, property1.Value); blendGroup.SetWeight(0, 0); Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.FromSeconds(0.25)); // t = 1.0 manager.ApplyAnimations(); Assert.AreEqual(200.0f, property1.Value); blendGroup.SetWeight(0, 10); blendGroup.SetWeight(1, 0); Assert.AreEqual(TimeSpan.FromSeconds(1.0), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.Zero); // t = 1.0 manager.ApplyAnimations(); Assert.AreEqual(100.0f, property1.Value); blendGroup.SetWeight(0, 10); blendGroup.SetWeight(1, 1); Assert.AreEqual(new TimeSpan((long)((1.0f * 10.0f / 11.0f + 2.0f * 1.0f / 11.0f) * TimeSpan.TicksPerSecond)), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.FromSeconds(0.5)); // t = 1.5 manager.ApplyAnimations(); Assert.AreEqual(123.45f, property1.Value); Assert.AreEqual(AnimationState.Stopped, controller.State); }
public void ControlAnimation() { var manager = new AnimationManager(); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, }; var controller = manager.CreateController(animation, property); Assert.AreEqual(0.0f, property.Value); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Stopped, controller.State); Assert.IsFalse(controller.Time.HasValue); controller.Pause(); Assert.AreEqual(0.0f, property.Value); Assert.IsTrue(controller.IsPaused); Assert.AreEqual(AnimationState.Stopped, controller.State); Assert.IsFalse(controller.Time.HasValue); controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.IsTrue(controller.IsPaused); Assert.AreEqual(AnimationState.Playing, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(100.0f, property.Value); Assert.IsTrue(controller.IsPaused); Assert.AreEqual(AnimationState.Playing, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time); controller.Resume(); Assert.AreEqual(100.0f, property.Value); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Playing, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(150.0f, property.Value); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Playing, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.Time); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(200.0f, property.Value); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Playing, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(1.0), controller.Time); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(200.0f, property.Value); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Filling, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(1.5), controller.Time); Assert.That(() => controller.Start(), Throws.TypeOf<AnimationException>()); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(0.0f, property.Value); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Stopped, controller.State); Assert.IsFalse(controller.Time.HasValue); // Restart controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Playing, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(150.0f, property.Value); Assert.IsFalse(controller.IsPaused); Assert.AreEqual(AnimationState.Playing, controller.State); Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.Time); }
public void SetAnimationTime() { var manager = new AnimationManager(); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation(); var controller = manager.StartAnimation(animation, property); Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time); controller.Time = TimeSpan.FromSeconds(0.5); Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.Time); Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.AnimationInstance.Time); }
public void ShouldDoNothingWhenWeightsAreZero() { var blendGroup = new BlendGroup { FillBehavior = FillBehavior.Stop }; var animation1 = new SingleFromToByAnimation { From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0) }; var animation2 = new SingleFromToByAnimation { From = 100, To = 300, Duration = TimeSpan.FromSeconds(2.0) }; blendGroup.Add(animation1); blendGroup.Add(animation2); blendGroup.SetWeight(0, 0); blendGroup.SetWeight(1, 0); Assert.That(() => blendGroup.SynchronizeDurations(), Throws.Nothing); blendGroup.Update(); Assert.AreEqual(0.0f, blendGroup.GetNormalizedWeight(0)); Assert.AreEqual(0.0f, blendGroup.GetNormalizedWeight(1)); }
// OnLoad() is called when the GameObject is added to the IGameObjectService. protected override void OnLoad() { // ----- Create prototype of a lava ball: // Use a sphere for physics simulation. _bodyPrototype = new RigidBody(new SphereShape(0.5f)); // Load the graphics model. var content = _services.GetInstance<ContentManager>(); _modelPrototype = content.Load<ModelNode>("LavaBall/LavaBall").Clone(); // Attach a point light to the model. The light projects the glowing lava // veins (cube map texture) onto the environment. _pointLight = new PointLight { Color = new Vector3F(1, 1, 1), DiffuseIntensity = 2, SpecularIntensity = 2, Range = 1.5f, Attenuation = 0.5f, Texture = content.Load<TextureCube>("LavaBall/LavaCubeMap"), }; var pointLightNode = new LightNode(_pointLight); _modelPrototype.Children.Add(pointLightNode); // Get the emissive color binding of the material because the emissive color // will be animated. // The model contains one mesh node with a single material. var meshNode = (MeshNode)_modelPrototype.Children[0]; var mesh = meshNode.Mesh; var material = mesh.Materials[0]; // The material contains several effect bindings. The "EmissiveColor" is applied // in the "Material" pass. // (For reference see material definition file: Samples\Media\LavaBall\Lava.drmat) _emissiveColorBinding = (ConstParameterBinding<Vector3>)material["Material"].ParameterBindings["EmissiveColor"]; // Use the animation service to animate glow intensity of the lava. var animationService = _services.GetInstance<IAnimationService>(); // Create an AnimatableProperty<float>, which stores the animation value. _glowIntensity = new AnimatableProperty<float>(); // Create sine animation and play the animation back-and-forth. var animation = new SingleFromToByAnimation { From = 0.3f, To = 3.0f, Duration = TimeSpan.FromSeconds(1), EasingFunction = new SineEase { Mode = EasingMode.EaseInOut }, }; var clip = new AnimationClip<float> { Animation = animation, Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Oscillate }; animationService.StartAnimation(clip, _glowIntensity).AutoRecycle(); }