public void GetDefaultDurationTest() { var timelineGroup = new TimelineGroup(); var animation = new Vector2FAnimation(); var animation2 = new AnimationClip <float> { Animation = new SingleFromToByAnimation(), Delay = TimeSpan.FromSeconds(10), }; var animation3 = new AnimationClip <float> { Animation = new SingleFromToByAnimation(), Delay = TimeSpan.FromSeconds(8), Duration = TimeSpan.FromSeconds(4), }; Assert.AreEqual(TimeSpan.FromSeconds(0.0), timelineGroup.GetTotalDuration()); timelineGroup.Add(animation); Assert.AreEqual(TimeSpan.FromSeconds(0.0), timelineGroup.GetTotalDuration()); timelineGroup.Add(animation2); Assert.AreEqual(TimeSpan.FromSeconds(11.0), timelineGroup.GetTotalDuration()); timelineGroup.Add(animation3); Assert.AreEqual(TimeSpan.FromSeconds(12.0), timelineGroup.GetTotalDuration()); }
public void GetDefaultDurationTest() { var timelineGroup = new TimelineGroup(); var animation = new Vector2FAnimation(); var animation2 = new AnimationClip<float> { Animation = new SingleFromToByAnimation(), Delay = TimeSpan.FromSeconds(10), }; var animation3 = new AnimationClip<float> { Animation = new SingleFromToByAnimation(), Delay = TimeSpan.FromSeconds(8), Duration = TimeSpan.FromSeconds(4), }; Assert.AreEqual(TimeSpan.FromSeconds(0.0), timelineGroup.GetTotalDuration()); timelineGroup.Add(animation); Assert.AreEqual(TimeSpan.FromSeconds(0.0), timelineGroup.GetTotalDuration()); timelineGroup.Add(animation2); Assert.AreEqual(TimeSpan.FromSeconds(11.0), timelineGroup.GetTotalDuration()); timelineGroup.Add(animation3); Assert.AreEqual(TimeSpan.FromSeconds(12.0), timelineGroup.GetTotalDuration()); }
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)); }
/// <summary> /// Add the supplied time line activity to the time lien groups /// </summary> /// <param name="timelineGroupModel">timline group model updated</param> /// <param name="activityOnMeme"></param> /// <param name="maxCount"></param> private void AddActivitytoTimeLineGroups(ref TimelineGroupModel timelineGroupModel, ITimeLine activityOnMeme, int maxCount) { // Find a time line group has has activity on thie meme already TimelineGroup existingTimelineGroup = timelineGroupModel.TimelineGroups.FirstOrDefault(x => x.Meme.Id == activityOnMeme.TimeLineRefId); if (existingTimelineGroup != null) { // Don't add more than 10 if (existingTimelineGroup.TimelineEntries.Count < maxCount) { // Don't re-add an timeline entry that is already there if (existingTimelineGroup.TimelineEntries.Any(x => x.TimelineId == activityOnMeme.Id) == false) { existingTimelineGroup.TimelineEntries.Add(GetTimelineEntryModel(activityOnMeme)); } } else { // If more than 10 just flag as having more existingTimelineGroup.HasMore = true; } } else { var timeLineGroup = new TimelineGroup(); timeLineGroup.TimeStamp = activityOnMeme.DateOfEntry; timeLineGroup.Meme = new MemeLiteModel(repository, repository.GetMeme(activityOnMeme.TimeLineRefId)); timeLineGroup.TimelineEntries = new List <TimelineEntryModel> { GetTimelineEntryModel(activityOnMeme) }; timelineGroupModel.TimelineGroups.Add(timeLineGroup); } }
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 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 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 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)); }
// 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(); } }
private void AnimatePossessionBar(TimelineGroup storyBoard, double possession, DependencyProperty property) { var animation = new DoubleAnimation { To = possession, Duration = TimeSpan.FromSeconds(AnimationDuration), }; Storyboard.SetTarget(animation, MatchAnimations); Storyboard.SetTargetProperty(animation, new PropertyPath(property)); storyBoard.Children.Add(animation); }
private static void AddFade(TimelineGroup storyboard, float duration, int from, int to) { var animation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(duration)), From = from, To = to }; Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity")); storyboard.Children.Add(animation); }
/// <summary> /// 比較関数 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> static public int Compare(TimelineGroup a, TimelineGroup b) { if (a.OrderId > b.OrderId) { return(1); } else if (a.OrderId < b.OrderId) { return(-1); } return(0); }
public CharacterCrossFadeSample(Microsoft.Xna.Framework.Game game) : base(game) { var modelNode = ContentManager.Load <ModelNode>("Marine/PlayerMarine"); _meshNode = modelNode.GetSubtree().OfType <MeshNode>().First().Clone(); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); Dictionary <string, SkeletonKeyFrameAnimation> animations = _meshNode.Mesh.Animations; // Create a looping 'Idle' animation. _idleAnimation = new AnimationClip <SkeletonPose>(animations["Idle"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a looping 'Run' animation. _runAnimation = new AnimationClip <SkeletonPose>(animations["Run"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Combine the 'Aim' and 'Shoot' animation. The 'Aim' animation should start immediately. // The 'Shoot' animation should start after 0.3 seconds. // (Animations can be combined by creating timeline groups. All timelines/animations // in a timeline group are played simultaneously. AnimationClips can be used to // arrange animations on a timeline. The property Delay, for example, can be used to // set the begin time.) _aimAndShootAnimation = new TimelineGroup(); _aimAndShootAnimation.Add(animations["Aim"]); _aimAndShootAnimation.Add(new AnimationClip <SkeletonPose>(animations["Shoot"]) { Delay = TimeSpan.FromSeconds(0.3) }); // Start 'Idle' animation. We use a Replace transition with a fade-in. _idleAnimationController = AnimationService.StartAnimation( _idleAnimation, (IAnimatableProperty)_meshNode.SkeletonPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.5))); _idleAnimationController.AutoRecycle(); }
public CustomAvatarAnimationSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); _cameraObject.ResetPose(new Vector3(0, 1, -3), ConstantsF.Pi, 0); GameObjectService.Objects.Add(_cameraObject); // Create a random avatar. _avatarDescription = AvatarDescription.CreateRandom(); _avatarRenderer = new AvatarRenderer(_avatarDescription); // Wrap the Stand0 AvatarAnimationPreset (see WrappedAnimationSample) to create an // infinitely looping stand animation. AvatarAnimation standAnimationPreset = new AvatarAnimation(AvatarAnimationPreset.Stand0); TimelineGroup standAnimation = new TimelineGroup { new WrappedAvatarExpressionAnimation(standAnimationPreset), new WrappedAvatarSkeletonAnimation(standAnimationPreset), }; _standAnimation = new TimelineClip(standAnimation) { LoopBehavior = LoopBehavior.Cycle, // Cycle the Stand animation... Duration = TimeSpan.MaxValue, // ...forever. }; // Load animations from content pipeline. _faintAnimation = ContentManager.Load <TimelineGroup>("XboxAvatars/Faint"); _jumpAnimation = ContentManager.Load <TimelineGroup>("XboxAvatars/Jump"); _kickAnimation = ContentManager.Load <TimelineGroup>("XboxAvatars/Kick"); _punchAnimation = ContentManager.Load <TimelineGroup>("XboxAvatars/Punch"); // The walk cycle should loop: Put it into a timeline clip and set a // loop-behavior. TimelineGroup walkAnimation = ContentManager.Load <TimelineGroup>("XboxAvatars/Walk"); _walkAnimation = new TimelineClip(walkAnimation) { LoopBehavior = LoopBehavior.Cycle, // Cycle the Walk animation... Duration = TimeSpan.MaxValue, // ...forever. }; }
public CustomAvatarAnimationSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); _cameraObject.ResetPose(new Vector3F(0, 1, -3), ConstantsF.Pi, 0); GameObjectService.Objects.Add(_cameraObject); // Create a random avatar. _avatarDescription = AvatarDescription.CreateRandom(); _avatarRenderer = new AvatarRenderer(_avatarDescription); // Wrap the Stand0 AvatarAnimationPreset (see WrappedAnimationSample) to create an // infinitely looping stand animation. AvatarAnimation standAnimationPreset = new AvatarAnimation(AvatarAnimationPreset.Stand0); TimelineGroup standAnimation = new TimelineGroup { new WrappedAvatarExpressionAnimation(standAnimationPreset), new WrappedAvatarSkeletonAnimation(standAnimationPreset), }; _standAnimation = new TimelineClip(standAnimation) { LoopBehavior = LoopBehavior.Cycle, // Cycle the Stand animation... Duration = TimeSpan.MaxValue, // ...forever. }; // Load animations from content pipeline. _faintAnimation = ContentManager.Load<TimelineGroup>("XboxAvatars/Faint"); _jumpAnimation = ContentManager.Load<TimelineGroup>("XboxAvatars/Jump"); _kickAnimation = ContentManager.Load<TimelineGroup>("XboxAvatars/Kick"); _punchAnimation = ContentManager.Load<TimelineGroup>("XboxAvatars/Punch"); // The walk cycle should loop: Put it into a timeline clip and set a // loop-behavior. TimelineGroup walkAnimation = ContentManager.Load<TimelineGroup>("XboxAvatars/Walk"); _walkAnimation = new TimelineClip(walkAnimation) { LoopBehavior = LoopBehavior.Cycle, // Cycle the Walk animation... Duration = TimeSpan.MaxValue, // ...forever. }; }
// 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(); }
public CharacterCrossFadeSample(Microsoft.Xna.Framework.Game game) : base(game) { var modelNode = ContentManager.Load<ModelNode>("Marine/PlayerMarine"); _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone(); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); Dictionary<string, SkeletonKeyFrameAnimation> animations = _meshNode.Mesh.Animations; // Create a looping 'Idle' animation. _idleAnimation = new AnimationClip<SkeletonPose>(animations["Idle"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a looping 'Run' animation. _runAnimation = new AnimationClip<SkeletonPose>(animations["Run"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Combine the 'Aim' and 'Shoot' animation. The 'Aim' animation should start immediately. // The 'Shoot' animation should start after 0.3 seconds. // (Animations can be combined by creating timeline groups. All timelines/animations // in a timeline group are played simultaneously. AnimationClips can be used to // arrange animations on a timeline. The property Delay, for example, can be used to // set the begin time.) _aimAndShootAnimation = new TimelineGroup(); _aimAndShootAnimation.Add(animations["Aim"]); _aimAndShootAnimation.Add(new AnimationClip<SkeletonPose>(animations["Shoot"]) { Delay = TimeSpan.FromSeconds(0.3) }); // Start 'Idle' animation. We use a Replace transition with a fade-in. _idleAnimationController = AnimationService.StartAnimation( _idleAnimation, (IAnimatableProperty)_meshNode.SkeletonPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.5))); _idleAnimationController.AutoRecycle(); }
/// <summary> /// <summary> /// Recursively counts up active clocks in this Timeline. /// </summary> /// <param name="clock">The current clock in a tree of clocks.</param> private void InitializeTimeline(Timeline timeline) { // The primary purpose of this method is to count up the number of clocks. this.clockCounter++; // This event handler will count down the number of completed clocks. Only when the counter reaches zero will the new 'Completed' event be raised // for this Timeline. timeline.Completed += this.ClockEnd; // If this clock is the parent of a group, then each of the children in the group will be examined for clocks. By this method, all the clocks in a // tree are recursively counted. if (timeline is TimelineGroup) { TimelineGroup timelineGroup = timeline as TimelineGroup; foreach (Timeline childTimeline in timelineGroup.Children) { InitializeTimeline(childTimeline); } } }
public AvatarAttachmentSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; // This sample uses Scene and MeshRenderer for rendering the attached models. _scene = new Scene(); _meshRenderer = new MeshRenderer(); // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); _cameraObject.ResetPose(new Vector3F(0, 1, -3), ConstantsF.Pi, 0); GameObjectService.Objects.Add(_cameraObject); // Create a random avatar. _avatarDescription = AvatarDescription.CreateRandom(); _avatarRenderer = new AvatarRenderer(_avatarDescription); // Load walk animation using the content pipeline. TimelineGroup animation = ContentManager.Load <TimelineGroup>("XboxAvatars/Walk"); // Create a looping walk animation. _walkAnimation = new TimelineClip(animation) { LoopBehavior = LoopBehavior.Cycle, // Cycle Walk animation... Duration = TimeSpan.MaxValue, // ...forever. }; var baseballBatModelNode = ContentManager.Load <ModelNode>("XboxAvatars/BaseballBat").Clone(); _baseballBatMeshNode = baseballBatModelNode.GetChildren().OfType <MeshNode>().First(); // If we only render the baseball bat, it appears black. We need to add it to // a scene with some lights. (The lights do not affect the avatar.) SceneSample.InitializeDefaultXnaLights(_scene); // We must detach the mesh node from its current parent (the model node) before // we can add it to the scene. _baseballBatMeshNode.Parent.Children.Remove(_baseballBatMeshNode); _scene.Children.Add(_baseballBatMeshNode); }
// 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>()); }
public void GetRoot() { 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.GetRoot(null), Throws.TypeOf <ArgumentNullException>()); var animationInstance = animationA.CreateInstance(); Assert.AreEqual(animationInstance, animationInstance.GetRoot()); Assert.AreEqual(animationInstance, animationInstance.Children[2].Children[0].GetRoot()); }
public EasingWindow(IServiceLocator services) : base(services) { _inputService = services.GetInstance <IInputService>(); _animationService = services.GetInstance <IAnimationService>(); Title = "EasingWindow"; StackPanel stackPanel = new StackPanel { Margin = new Vector4(8) }; Content = stackPanel; TextBlock textBlock = new TextBlock { Text = "Test different Easing Functions in this window.", Margin = new Vector4(0, 0, 0, 8), }; stackPanel.Children.Add(textBlock); StackPanel horizontalPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Vector4(0, 0, 0, 8) }; stackPanel.Children.Add(horizontalPanel); textBlock = new TextBlock { Text = "Easing Function:", Width = 80, Margin = new Vector4(0, 0, 8, 0), }; horizontalPanel.Children.Add(textBlock); _functionDropDown = new DropDownButton { Width = 100, // The DropDownButton automatically converts the items to string (using ToString) and // displays this string. This is not helpful for this sort of items. We want to display // the type name of the items instead. The following is a callback which creates a // TextBlock for each item. It is called when the drop-down list is opened. CreateControlForItem = item => new TextBlock { Text = item.GetType().Name }, }; horizontalPanel.Children.Add(_functionDropDown); _functionDropDown.Items.Add(new BackEase()); _functionDropDown.Items.Add(new BounceEase()); _functionDropDown.Items.Add(new CircleEase()); _functionDropDown.Items.Add(new CubicEase()); _functionDropDown.Items.Add(new ElasticEase()); _functionDropDown.Items.Add(new ExponentialEase()); _functionDropDown.Items.Add(new LogarithmicEase()); _functionDropDown.Items.Add(new HermiteEase()); _functionDropDown.Items.Add(new PowerEase()); _functionDropDown.Items.Add(new QuadraticEase()); _functionDropDown.Items.Add(new QuinticEase()); _functionDropDown.Items.Add(new SineEase()); _functionDropDown.SelectedIndex = 0; horizontalPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Vector4(0, 0, 0, 8) }; stackPanel.Children.Add(horizontalPanel); textBlock = new TextBlock { Text = "Easing Mode:", Width = 80, Margin = new Vector4(0, 0, 8, 0), }; horizontalPanel.Children.Add(textBlock); _modeDropDown = new DropDownButton { Width = 100, }; horizontalPanel.Children.Add(_modeDropDown); _modeDropDown.Items.Add(EasingMode.EaseIn); _modeDropDown.Items.Add(EasingMode.EaseOut); _modeDropDown.Items.Add(EasingMode.EaseInOut); _modeDropDown.SelectedIndex = 0; _slider = new Slider { Margin = new Vector4(0, 16, 0, 0), SmallChange = 0.01f, LargeChange = 0.1f, Minimum = -0.5f, Maximum = 1.5f, Width = 250, HorizontalAlignment = HorizontalAlignment.Center, }; stackPanel.Children.Add(_slider); // Display the current value of the slider. var valueLabel = new TextBlock { Text = _slider.Value.ToString("F2"), HorizontalAlignment = HorizontalAlignment.Center, Margin = new Vector4(0, 0, 0, 8), }; stackPanel.Children.Add(valueLabel); // Update the text every time the slider value changes. var valueProperty = _slider.Properties.Get <float>("Value"); valueProperty.Changed += (s, e) => valueLabel.Text = e.NewValue.ToString("F2"); Button button = new Button { Content = new TextBlock { Text = "Animate" }, HorizontalAlignment = HorizontalAlignment.Center, Margin = new Vector4(0, 0, 0, 8), }; button.Click += OnButtonClicked; stackPanel.Children.Add(button); textBlock = new TextBlock { Text = "(Press the Animate button to animate the slider\n" + "value using the selected EasingFunction.\n" + "The slider goes from -0.5 to 1.5. The animation\n" + "animates the value to 0 or to 1.)", }; stackPanel.Children.Add(textBlock); // When the window is loaded, the window appears under the mouse cursor and flies to // its position. Vector2F mousePosition = _inputService.MousePosition; // The loading animation is a timeline group of three animations: // - One animations animates the RenderScale from (0, 0) to its current value. // - The other animations animate the X and Y positions from the mouse position // to current values. // The base class AnimatedWindow will apply this timeline group on this window // when the window is loaded. TimelineGroup timelineGroup = new TimelineGroup { new Vector2FFromToByAnimation { TargetProperty = "RenderScale", From = new Vector2F(0, 0), Duration = TimeSpan.FromSeconds(0.3), EasingFunction = new HermiteEase { Mode = EasingMode.EaseOut }, }, new SingleFromToByAnimation { TargetProperty = "X", From = mousePosition.X, Duration = TimeSpan.FromSeconds(0.3), }, new SingleFromToByAnimation { TargetProperty = "Y", From = mousePosition.Y, Duration = TimeSpan.FromSeconds(0.3), EasingFunction = new QuadraticEase { Mode = EasingMode.EaseIn }, }, }; // The default FillBehavior is "Hold". But this animation can be removed when it is finished. // It should not "Hold" the animation value. If FillBehavior is set to Hold, we cannot // drag the window with the mouse because the animation overrides the value. timelineGroup.FillBehavior = FillBehavior.Stop; LoadingAnimation = timelineGroup; // The closing animation is a timeline group of three animations: // - One animations animates the RenderScale to (0, 0). // - The other animations animate the X and Y positions to the mouse position. // The base class AnimatedWindow will apply this timeline group on this window // when the window is loaded. ClosingAnimation = new TimelineGroup { new Vector2FFromToByAnimation { TargetProperty = "RenderScale", To = new Vector2F(0, 0), Duration = TimeSpan.FromSeconds(0.3), EasingFunction = new HermiteEase { Mode = EasingMode.EaseIn }, }, new SingleFromToByAnimation { TargetProperty = "X", To = mousePosition.X, Duration = TimeSpan.FromSeconds(0.3), }, new SingleFromToByAnimation { TargetProperty = "Y", To = mousePosition.Y, Duration = TimeSpan.FromSeconds(0.3), EasingFunction = new QuadraticEase { Mode = EasingMode.EaseOut }, }, }; }
// Create morph target animation in code. private static ITimeline CreateMorphingAnimation() { // The weight of each morph target is controlled by a keyframe animation. var browMad = new SingleKeyFrameAnimation { TargetProperty = "BROW-mad" }; browMad.KeyFrames.Add(new KeyFrame<float>(FrameToTime(15), 0)); browMad.KeyFrames.Add(new KeyFrame<float>(FrameToTime(30), 1)); browMad.KeyFrames.Add(new KeyFrame<float>(FrameToTime(65), 1)); browMad.KeyFrames.Add(new KeyFrame<float>(FrameToTime(80), 0)); var browSurp = new SingleKeyFrameAnimation { TargetProperty = "BROW-surp" }; browSurp.KeyFrames.Add(new KeyFrame<float>(FrameToTime(0), 0)); browSurp.KeyFrames.Add(new KeyFrame<float>(FrameToTime(15), 0.5f)); browSurp.KeyFrames.Add(new KeyFrame<float>(FrameToTime(30), 0)); browSurp.KeyFrames.Add(new KeyFrame<float>(FrameToTime(210), 0)); browSurp.KeyFrames.Add(new KeyFrame<float>(FrameToTime(220), 0.5f)); browSurp.KeyFrames.Add(new KeyFrame<float>(FrameToTime(230), 0.5f)); browSurp.KeyFrames.Add(new KeyFrame<float>(FrameToTime(250), 0)); var cheekIn = new SingleKeyFrameAnimation { TargetProperty = "CHEEK-in" }; cheekIn.KeyFrames.Add(new KeyFrame<float>(FrameToTime(0), 0)); cheekIn.KeyFrames.Add(new KeyFrame<float>(FrameToTime(15), 1)); cheekIn.KeyFrames.Add(new KeyFrame<float>(FrameToTime(30), 0)); var cheekOut = new SingleKeyFrameAnimation { TargetProperty = "CHEEK-out" }; cheekOut.KeyFrames.Add(new KeyFrame<float>(FrameToTime(25), 0)); cheekOut.KeyFrames.Add(new KeyFrame<float>(FrameToTime(35), 1)); cheekOut.KeyFrames.Add(new KeyFrame<float>(FrameToTime(65), 1)); cheekOut.KeyFrames.Add(new KeyFrame<float>(FrameToTime(80), 0)); var eyeClosed = new SingleKeyFrameAnimation { TargetProperty = "EYE-closed" }; eyeClosed.KeyFrames.Add(new KeyFrame<float>(FrameToTime(20), 0)); eyeClosed.KeyFrames.Add(new KeyFrame<float>(FrameToTime(25), 1)); eyeClosed.KeyFrames.Add(new KeyFrame<float>(FrameToTime(55), 0.2f)); eyeClosed.KeyFrames.Add(new KeyFrame<float>(FrameToTime(65), 0.2f)); eyeClosed.KeyFrames.Add(new KeyFrame<float>(FrameToTime(80), 0)); eyeClosed.KeyFrames.Add(new KeyFrame<float>(FrameToTime(230), 0)); eyeClosed.KeyFrames.Add(new KeyFrame<float>(FrameToTime(235), 1)); eyeClosed.KeyFrames.Add(new KeyFrame<float>(FrameToTime(240), 0)); var mouthE = new SingleKeyFrameAnimation { TargetProperty = "MOUTH-e" }; mouthE.KeyFrames.Add(new KeyFrame<float>(FrameToTime(115), 0)); mouthE.KeyFrames.Add(new KeyFrame<float>(FrameToTime(125), 0.7f)); mouthE.KeyFrames.Add(new KeyFrame<float>(FrameToTime(130), 0.7f)); mouthE.KeyFrames.Add(new KeyFrame<float>(FrameToTime(140), 0.9f)); mouthE.KeyFrames.Add(new KeyFrame<float>(FrameToTime(145), 0.9f)); mouthE.KeyFrames.Add(new KeyFrame<float>(FrameToTime(155), 0.0f)); var mouthU = new SingleKeyFrameAnimation { TargetProperty = "MOUTH-u" }; mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(25), 0)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(35), 0.5f)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(55), 0)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(145), 0)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(155), 0.5f)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(160), 0.5f)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(170), 0.9f)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(175), 0.9f)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(170), 0.9f)); mouthU.KeyFrames.Add(new KeyFrame<float>(FrameToTime(190), 0.0f)); var mouthSmile = new SingleKeyFrameAnimation { TargetProperty = "MOUTH-smile" }; mouthSmile.KeyFrames.Add(new KeyFrame<float>(FrameToTime(210), 0)); mouthSmile.KeyFrames.Add(new KeyFrame<float>(FrameToTime(220), 1)); mouthSmile.KeyFrames.Add(new KeyFrame<float>(FrameToTime(230), 1)); mouthSmile.KeyFrames.Add(new KeyFrame<float>(FrameToTime(250), 0)); // Combine the key frame animations into a single animation. var timelineGroup = new TimelineGroup(); timelineGroup.Add(browMad); timelineGroup.Add(browSurp); timelineGroup.Add(cheekIn); timelineGroup.Add(cheekOut); timelineGroup.Add(eyeClosed); timelineGroup.Add(mouthE); timelineGroup.Add(mouthU); timelineGroup.Add(mouthSmile); // Make an endless loop. return new TimelineClip(timelineGroup) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle }; }
public AnimatableObjectSample(Microsoft.Xna.Framework.Game game) : base(game) { Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; // ----- Create three named AnimatableSprite instances. _animatableSpriteA = new AnimatableSprite("SpriteA", SpriteBatch, Logo) { Position = new Vector2(bounds.Center.X, bounds.Center.Y / 2.0f), Color = Color.Red, }; _animatableSpriteB = new AnimatableSprite("SpriteB", SpriteBatch, Logo) { Position = new Vector2(bounds.Center.X, bounds.Center.Y), Color = Color.Green, }; _animatableSpriteC = new AnimatableSprite("SpriteC", SpriteBatch, Logo) { Position = new Vector2(bounds.Center.X, 3.0f * bounds.Center.Y / 2.0f), Color = Color.Blue, }; // Create a looping color key-frame animation. ColorKeyFrameAnimation colorAnimation = new ColorKeyFrameAnimation { TargetProperty = "Color", EnableInterpolation = true, }; 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)); colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(3.5), Color.Red)); AnimationClip<Color> loopedColorAnimation = new AnimationClip<Color>(colorAnimation) { TargetObject = "SpriteB", LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a oscillating from/to animation for the position. Vector2FromToByAnimation vector2Animation = new Vector2FromToByAnimation { TargetProperty = "Position", From = new Vector2(bounds.Left + 100, _animatableSpriteC.Position.Y), To = new Vector2(bounds.Right - 100, _animatableSpriteC.Position.Y), Duration = TimeSpan.FromSeconds(2), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; AnimationClip<Vector2> oscillatingVector2Animation = new AnimationClip<Vector2>(vector2Animation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; // Create a timeline group that contains both animations. TimelineGroup spriteCAnimation = new TimelineGroup { TargetObject = "SpriteC", }; spriteCAnimation.Add(loopedColorAnimation); spriteCAnimation.Add(oscillatingVector2Animation); // Create a timeline group that contains the animations for SpriteB and SpriteC. TimelineGroup allSpriteAnimations = new TimelineGroup(); allSpriteAnimations.Add(loopedColorAnimation); allSpriteAnimations.Add(spriteCAnimation); // There are several ways to apply animations to animatable objects and properties: // // Method 1: Apply to an IAnimatableProperty directly. // We either have direct access to a IAnimatableProperty or we can ask the IAnimatableObject // to give us a named IAnimatableProperty. // For example: // AnimationService.StartAnimation(loopedColorAnimation, _animatableSpriteB.GetAnimatableProperty<Color>("Color")); // AnimationService.StartAnimation(loopedColorAnimation, _animatableSpriteC.GetAnimatableProperty<Color>("Color")); // AnimationService.StartAnimation(oscillatingLeftRightAnimation, _animatableSpriteC.GetAnimatableProperty<Vector2>("Position")); // In this case, the "TargetObject" and the "TargetProperty" values of the timelines/animations do not matter. // // Method 2: Apply to an IAnimatableObject directly. // For example: // AnimationService.StartAnimation(loopedColorAnimation, _animatableSpriteB); // AnimationService.StartAnimation(spriteCAnimation, _animatableSpriteC); // The animation service checks the TargetProperty value of the animations to see which // IAnimatableProperty of the IAnimatableObjects should be animated by the animation. // The "TargetObject" values of the timelines are ignored. // // Method 3: Apply a timeline to a collection of IAnimatableObjects. // For example: var animationController = AnimationService.StartAnimation(allSpriteAnimations, new[] { _animatableSpriteA, _animatableSpriteB, _animatableSpriteC }); // The "TargetObject" and "TargetProperty" values are used to check which objects and // properties must be animated by which animation. // combinedSpriteAnimation is a "tree" of timelines: // // Type TargetObject TargetProperty // -------------------------------------------------------------------------------------------------- // allSpriteAnimations TimelineGroup - - // loopedColorAnimation AnimationClip<Color> "SpriteB" - // colorAnimation ColorKeyFrameAnimation - "Color" // spriteCAnimation TimelineGroup "SpriteC" - // loopedColorAnimation AnimationClip<Color> "SpriteB" - // colorAnimation ColorKeyFrameAnimation - "Color" // oscillatingVector2Animation AnimationClip<Vector2> - - // vector2Animation FromToByAnimation - "Position" // // No animation specifies "SpriteA" as its TargetObject, therefore no animation // are applied to SpriteA. // // The first loopedColorAnimation is applied to "SpriteB". And the contained // colorAnimation is applied to the Color property of SpriteB. // // The spriteCAnimation is applied to "SpriteC". Therefore, all "children" of // spriteCAnimation are also applied to this object! The TargetObject property of // the second loopedColorAnimation is ignored! The second loopedColorAnimation is // applied to SpriteC! animationController.UpdateAndApply(); }
protected ClockGroup (TimelineGroup timelineGroup) : base (timelineGroup) { throw new NotImplementedException (); }
// 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(); }
protected override void LoadContent() { _model = Game.Content.Load<Model>("PlayerMarine"); var additionalData = (Dictionary<string, object>)_model.Tag; var skeleton = (Skeleton)additionalData["Skeleton"]; _skeletonPose = SkeletonPose.Create(skeleton); var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"]; // Create a looping 'Idle' animation. _idleAnimation = new AnimationClip<SkeletonPose>(animations["Idle"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a looping 'Run' animation. _runAnimation = new AnimationClip<SkeletonPose>(animations["Run"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Combine the 'Aim' and 'Shoot' animation. The 'Aim' animation should start immediately. // The 'Shoot' animation should start after 0.3 seconds. // (Animations can be combined by creating timeline groups. All timelines/animations // in a timeline group are played simultaneously. AnimationClips can be used to // arrange animations on a timeline. The property Delay, for example, can be used to // set the begin time.) _aimAndShootAnimation = new TimelineGroup(); _aimAndShootAnimation.Add(animations["Aim"]); _aimAndShootAnimation.Add(new AnimationClip<SkeletonPose>(animations["Shoot"]) { Delay = TimeSpan.FromSeconds(0.3) }); // Start 'Idle' animation. We use a Replace transition with a fade-in. _idleAnimationController = AnimationService.StartAnimation( _idleAnimation, (IAnimatableProperty)_skeletonPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.5))); _idleAnimationController.AutoRecycle(); base.LoadContent(); }
public void AnimateObjects() { var objectA = new AnimatableObject("ObjectA"); var propertyA1 = new AnimatableProperty <float> { Value = 10.0f }; objectA.Properties.Add("Value", propertyA1); var propertyA2 = new AnimatableProperty <float> { Value = 20.0f }; objectA.Properties.Add("Value2", propertyA2); var objectB = new AnimatableObject("ObjectB"); var propertyB = new AnimatableProperty <float> { Value = 30.0f }; objectB.Properties.Add("Value", propertyB); var objectC = new AnimatableObject("ObjectC"); var propertyC = new AnimatableProperty <float> { Value = 40.0f }; objectC.Properties.Add("Value", propertyC); var animationA1 = new SingleFromToByAnimation // Should be assigned to ObjectA { From = 100.0f, To = 200.0f, TargetObject = "ObjectXyz", // Ignored because ObjectA is selected by animationGroup1. TargetProperty = "Value", // Required. }; var animationA2 = new SingleFromToByAnimation // Should be assigned to ObjectA { From = 200.0f, To = 300.0f, TargetObject = "ObjectB", // Ignored because ObjectA is selected by animationGroup1. TargetProperty = "Value", // Required. }; var animationA3 = new Vector3FFromToByAnimation // Ignored because of incompatible type. { From = new Vector3F(300.0f), To = new Vector3F(400.0f), TargetObject = "ObjectA", TargetProperty = "Value", }; var animationA4 = new SingleFromToByAnimation // Ignored because TargetProperty is not set. { From = 400.0f, To = 500.0f, TargetObject = "", TargetProperty = "", }; var animationGroupA = new TimelineGroup { TargetObject = "ObjectA" }; animationGroupA.Add(animationA1); animationGroupA.Add(animationA2); animationGroupA.Add(animationA3); animationGroupA.Add(animationA4); var animationB1 = new SingleFromToByAnimation // Should be assigned to ObjectB { From = 100.0f, To = 200.0f, TargetObject = "ObjectB", TargetProperty = "Value", }; var animationA5 = new SingleFromToByAnimation { From = 600.0f, To = 700.0f, TargetObject = "", TargetProperty = "Value", }; var animationGroupRoot = new TimelineGroup(); animationGroupRoot.Add(animationGroupA); animationGroupRoot.Add(animationB1); animationGroupRoot.Add(animationA5); var manager = new AnimationManager(); // CreateController() var controller = manager.CreateController(animationGroupRoot, new[] { objectA, objectB, objectC }); Assert.AreEqual(propertyA1, ((AnimationInstance <float>)controller.AnimationInstance.Children[0].Children[0]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance <float>)controller.AnimationInstance.Children[0].Children[1]).Property); Assert.AreEqual(null, ((AnimationInstance <Vector3F>)controller.AnimationInstance.Children[0].Children[2]).Property); Assert.AreEqual(null, ((AnimationInstance <float>)controller.AnimationInstance.Children[0].Children[3]).Property); Assert.AreEqual(propertyB, ((AnimationInstance <float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance <float>)controller.AnimationInstance.Children[2]).Property); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(600.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(100.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsTrue(manager.IsAnimated(objectA)); Assert.IsTrue(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsTrue(manager.IsAnimated(objectB)); Assert.IsTrue(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); // StartAnimation() controller = manager.StartAnimation(animationGroupRoot, new[] { objectA, objectB, objectC }); controller.UpdateAndApply(); Assert.AreEqual(propertyA1, ((AnimationInstance <float>)controller.AnimationInstance.Children[0].Children[0]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance <float>)controller.AnimationInstance.Children[0].Children[1]).Property); Assert.AreEqual(null, ((AnimationInstance <Vector3F>)controller.AnimationInstance.Children[0].Children[2]).Property); Assert.AreEqual(null, ((AnimationInstance <float>)controller.AnimationInstance.Children[0].Children[3]).Property); Assert.AreEqual(propertyB, ((AnimationInstance <float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance <float>)controller.AnimationInstance.Children[2]).Property); Assert.AreEqual(600.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(100.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsTrue(manager.IsAnimated(objectA)); Assert.IsTrue(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsTrue(manager.IsAnimated(objectB)); Assert.IsTrue(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); manager.StopAnimation(new[] { objectA, objectB, objectC }); manager.UpdateAndApplyAnimation(new[] { objectA, objectB, objectC }); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); }
// 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 }
public AnimatableObjectSample(Microsoft.Xna.Framework.Game game) : base(game) { Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; // ----- Create three named AnimatableSprite instances. _animatableSpriteA = new AnimatableSprite("SpriteA", SpriteBatch, Logo) { Position = new Vector2(bounds.Center.X, bounds.Center.Y / 2.0f), Color = Color.Red, }; _animatableSpriteB = new AnimatableSprite("SpriteB", SpriteBatch, Logo) { Position = new Vector2(bounds.Center.X, bounds.Center.Y), Color = Color.Green, }; _animatableSpriteC = new AnimatableSprite("SpriteC", SpriteBatch, Logo) { Position = new Vector2(bounds.Center.X, 3.0f * bounds.Center.Y / 2.0f), Color = Color.Blue, }; // Create a looping color key-frame animation. ColorKeyFrameAnimation colorAnimation = new ColorKeyFrameAnimation { TargetProperty = "Color", EnableInterpolation = true, }; 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)); colorAnimation.KeyFrames.Add(new KeyFrame <Color>(TimeSpan.FromSeconds(3.5), Color.Red)); AnimationClip <Color> loopedColorAnimation = new AnimationClip <Color>(colorAnimation) { TargetObject = "SpriteB", LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a oscillating from/to animation for the position. Vector2FromToByAnimation vector2Animation = new Vector2FromToByAnimation { TargetProperty = "Position", From = new Vector2(bounds.Left + 100, _animatableSpriteC.Position.Y), To = new Vector2(bounds.Right - 100, _animatableSpriteC.Position.Y), Duration = TimeSpan.FromSeconds(2), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; AnimationClip <Vector2> oscillatingVector2Animation = new AnimationClip <Vector2>(vector2Animation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; // Create a timeline group that contains both animations. TimelineGroup spriteCAnimation = new TimelineGroup { TargetObject = "SpriteC", }; spriteCAnimation.Add(loopedColorAnimation); spriteCAnimation.Add(oscillatingVector2Animation); // Create a timeline group that contains the animations for SpriteB and SpriteC. TimelineGroup allSpriteAnimations = new TimelineGroup(); allSpriteAnimations.Add(loopedColorAnimation); allSpriteAnimations.Add(spriteCAnimation); // There are several ways to apply animations to animatable objects and properties: // // Method 1: Apply to an IAnimatableProperty directly. // We either have direct access to a IAnimatableProperty or we can ask the IAnimatableObject // to give us a named IAnimatableProperty. // For example: // AnimationService.StartAnimation(loopedColorAnimation, _animatableSpriteB.GetAnimatableProperty<Color>("Color")); // AnimationService.StartAnimation(loopedColorAnimation, _animatableSpriteC.GetAnimatableProperty<Color>("Color")); // AnimationService.StartAnimation(oscillatingLeftRightAnimation, _animatableSpriteC.GetAnimatableProperty<Vector2>("Position")); // In this case, the "TargetObject" and the "TargetProperty" values of the timelines/animations do not matter. // // Method 2: Apply to an IAnimatableObject directly. // For example: // AnimationService.StartAnimation(loopedColorAnimation, _animatableSpriteB); // AnimationService.StartAnimation(spriteCAnimation, _animatableSpriteC); // The animation service checks the TargetProperty value of the animations to see which // IAnimatabelProperty of the IAnimtableObjects should be animated by the animation. // The "TargetObject" values of the timelines are ignored. // // Method 3: Apply a timeline to a collection of IAnimatableObjects. // For example: var animationController = AnimationService.StartAnimation(allSpriteAnimations, new[] { _animatableSpriteA, _animatableSpriteB, _animatableSpriteC }); // The "TargetObject" and "TargetProperty" values are used to check which objects and // properties must be animated by which animation. // combinedSpriteAnimation is a "tree" of timelines: // // Type TargetObject TargetProperty // -------------------------------------------------------------------------------------------------- // allSpriteAnimations TimelineGroup - - // loopedColorAnimation AnimationClip<Color> "SpriteB" - // colorAnimation ColorKeyFrameAnimation - "Color" // spriteCAnimation TimelineGroup "SpriteC" - // loopedColorAnimation AnimationClip<Color> "SpriteB" - // colorAnimation ColorKeyFrameAnimation - "Color" // oscillatingVector2Animation AnimationClip<Vector2> - - // vector2Animation FromToByAnimation - "Position" // // No animation specifies "SpriteA" as its TargetObject, therefore no animation // are applied to SpriteA. // // The first loopedColorAnimation is applied to "SpriteB". And the contained // colorAnimation is applied to the Color property of SpriteB. // // The spriteCAnimation is applied to "SpriteC". Therefore, all "children" of // spriteCAnimation are also applied to this object! The TargetObject property of // the second loopedColorAnimation is ignored! The second loopedColorAnimation is // applied to SpriteC! animationController.UpdateAndApply(); }
public void GetRoot() { 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.GetRoot(null), Throws.TypeOf<ArgumentNullException>()); var animationInstance = animationA.CreateInstance(); Assert.AreEqual(animationInstance, animationInstance.GetRoot()); Assert.AreEqual(animationInstance, animationInstance.Children[2].Children[0].GetRoot()); }
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 AnimateObject() { var obj = new AnimatableObject("TestObject"); var property = new AnimatableProperty<float> { Value = 10.0f }; obj.Properties.Add("Value", property); var property2 = new AnimatableProperty<float> { Value = 20.0f }; obj.Properties.Add("Value2", property2); var animationA = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, TargetObject = "ObjectA", // Should be ignored. TargetProperty = "Value", }; var animationB = new SingleFromToByAnimation { From = 200.0f, To = 300.0f, TargetObject = "ObjectB", // Should be ignored. TargetProperty = "", }; var animationGroup = new TimelineGroup(); animationGroup.Add(animationA); animationGroup.Add(animationB); var manager = new AnimationManager(); // Should assign animationA to 'obj'. var controller = manager.CreateController(animationGroup, obj); Assert.AreEqual(property, ((AnimationInstance<float>)controller.AnimationInstance.Children[0]).Property); Assert.AreEqual(null, ((AnimationInstance<float>)controller.AnimationInstance.Children[1]).Property); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); Assert.IsFalse(manager.IsAnimated(obj)); // When started then animationA should be active. controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsTrue(manager.IsAnimated(obj)); Assert.IsTrue(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(10.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsFalse(manager.IsAnimated(obj)); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); // Same test for AnimationManager.StartAnimation() controller = manager.StartAnimation(animationGroup, obj); controller.UpdateAndApply(); Assert.AreEqual(property, ((AnimationInstance<float>)controller.AnimationInstance.Children[0]).Property); Assert.AreEqual(null, ((AnimationInstance<float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(100.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsTrue(manager.IsAnimated(obj)); Assert.IsTrue(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); manager.StopAnimation(obj); manager.UpdateAndApplyAnimation(obj); Assert.AreEqual(10.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsFalse(manager.IsAnimated(obj)); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); }
/// <summary> /// Erstellt ein neues SelectionChangedEventArgs /// </summary> /// <param name="tg">ausgewählte TimelineGroup</param> /// <param name="te">ausgewählte TimelineGroup</param> public SelectionChangedEventArgs(TimelineGroup tg, TimelineEntry te) { this.m_selectedGroup = tg; this.m_selectedEntry = te; }
public RotatingWindow(IServiceLocator services) : base(services) { Title = "RotatingWindow"; Width = 250; Height = 100; Content = new TextBlock { Margin = new Vector4F(8), Text = "The 'RenderScale' and the 'RenderRotation' of this window are animated.", WrapText = true, }; // Set the center of the scale and rotation transformations to the center of the window. RenderTransformOrigin = new Vector2F(0.5f, 0.5f); // The loading animation is a timeline group of two animations. // One animations animates the RenderScale from (0, 0) to its current value. // The other animation animates the RenderRotation from 10 to its current value. // The base class AnimatedWindow will apply this timeline group on this window // when the window is loaded. LoadingAnimation = new TimelineGroup { new Vector2FFromToByAnimation { TargetProperty = "RenderScale", From = new Vector2F(0, 0), Duration = TimeSpan.FromSeconds(0.8), EasingFunction = new HermiteEase { Mode = EasingMode.EaseOut }, }, new SingleFromToByAnimation { TargetProperty = "RenderRotation", From = 10, Duration = TimeSpan.FromSeconds(0.8), EasingFunction = new HermiteEase { Mode = EasingMode.EaseOut }, } }; // The closing animation is a timeline group of two animations. // One animations animates the RenderScale from its current value to (0, 0). // The other animation animates the RenderRotation its current value to 10. // The base class AnimatedWindow will apply this timeline group on this window when // the window is loaded. ClosingAnimation = new TimelineGroup { new Vector2FFromToByAnimation { TargetProperty = "RenderScale", To = new Vector2F(0, 0), Duration = TimeSpan.FromSeconds(0.8), EasingFunction = new HermiteEase { Mode = EasingMode.EaseIn }, }, new SingleFromToByAnimation { TargetProperty = "RenderRotation", To = 10, Duration = TimeSpan.FromSeconds(0.8), EasingFunction = new HermiteEase { Mode = EasingMode.EaseIn }, } }; }
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]); }
/// <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; }
/// <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; }
public BlendedAnimationSample(Microsoft.Xna.Framework.Game game) : base(game) { Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; // Create the animatable object. _animatableSprite = new AnimatableSprite("SpriteA", SpriteBatch, Logo) { Position = new Vector2(bounds.Center.X, bounds.Center.Y / 2.0f), Color = Color.Red, }; Vector2FromToByAnimation slowLeftRightAnimation = new Vector2FromToByAnimation { TargetProperty = "Position", From = new Vector2(bounds.Left + 100, bounds.Top + 200), To = new Vector2(bounds.Right - 100, bounds.Top + 200), Duration = TimeSpan.FromSeconds(4), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; ColorKeyFrameAnimation redGreenAnimation = new ColorKeyFrameAnimation { TargetProperty = "Color", EnableInterpolation = true, }; redGreenAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(0), Color.Red)); redGreenAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(4), Color.Green)); TimelineGroup animationA = new TimelineGroup { slowLeftRightAnimation, redGreenAnimation, }; Vector2FromToByAnimation fastLeftRightAnimation = new Vector2FromToByAnimation { TargetProperty = "Position", From = new Vector2(bounds.Left + 100, bounds.Bottom - 200), To = new Vector2(bounds.Right - 100, bounds.Bottom - 200), Duration = TimeSpan.FromSeconds(1), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; ColorKeyFrameAnimation blackWhiteAnimation = new ColorKeyFrameAnimation { TargetProperty = "Color", EnableInterpolation = true, }; blackWhiteAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(0), Color.Black)); blackWhiteAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(1), Color.White)); TimelineGroup animationB = new TimelineGroup { fastLeftRightAnimation, blackWhiteAnimation, }; // Create a BlendGroup that blends animationA and animationB. // The BlendGroup uses the TargetProperty values of the contained animations to // to match the animations that should be blended: // slowLeftRightAnimation with fastLeftRightAnimation // redGreenAnimation with blackWhiteAnimation _blendedAnimation = new BlendGroup { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; _blendedAnimation.Add(animationA, 1); _blendedAnimation.Add(animationB, 0); _blendedAnimation.SynchronizeDurations(); // Start blended animation. AnimationService.StartAnimation(_blendedAnimation, _animatableSprite).UpdateAndApply(); }
public void AnimateObjects() { var objectA = new AnimatableObject("ObjectA"); var propertyA1 = new AnimatableProperty<float> { Value = 10.0f }; objectA.Properties.Add("Value", propertyA1); var propertyA2 = new AnimatableProperty<float> { Value = 20.0f }; objectA.Properties.Add("Value2", propertyA2); var objectB = new AnimatableObject("ObjectB"); var propertyB = new AnimatableProperty<float> { Value = 30.0f }; objectB.Properties.Add("Value", propertyB); var objectC = new AnimatableObject("ObjectC"); var propertyC = new AnimatableProperty<float> { Value = 40.0f }; objectC.Properties.Add("Value", propertyC); var animationA1 = new SingleFromToByAnimation // Should be assigned to ObjectA { From = 100.0f, To = 200.0f, TargetObject = "ObjectXyz", // Ignored because ObjectA is selected by animationGroup1. TargetProperty = "Value", // Required. }; var animationA2 = new SingleFromToByAnimation // Should be assigned to ObjectA { From = 200.0f, To = 300.0f, TargetObject = "ObjectB", // Ignored because ObjectA is selected by animationGroup1. TargetProperty = "Value", // Required. }; var animationA3 = new Vector3FFromToByAnimation // Ignored because of incompatible type. { From = new Vector3F(300.0f), To = new Vector3F(400.0f), TargetObject = "ObjectA", TargetProperty = "Value", }; var animationA4 = new SingleFromToByAnimation // Ignored because TargetProperty is not set. { From = 400.0f, To = 500.0f, TargetObject = "", TargetProperty = "", }; var animationGroupA = new TimelineGroup { TargetObject = "ObjectA" }; animationGroupA.Add(animationA1); animationGroupA.Add(animationA2); animationGroupA.Add(animationA3); animationGroupA.Add(animationA4); var animationB1 = new SingleFromToByAnimation // Should be assigned to ObjectB { From = 100.0f, To = 200.0f, TargetObject = "ObjectB", TargetProperty = "Value", }; var animationA5 = new SingleFromToByAnimation { From = 600.0f, To = 700.0f, TargetObject = "", TargetProperty = "Value", }; var animationGroupRoot = new TimelineGroup(); animationGroupRoot.Add(animationGroupA); animationGroupRoot.Add(animationB1); animationGroupRoot.Add(animationA5); var manager = new AnimationManager(); // CreateController() var controller = manager.CreateController(animationGroupRoot, new[] { objectA, objectB, objectC }); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[0]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[1]).Property); Assert.AreEqual(null, ((AnimationInstance<Vector3F>)controller.AnimationInstance.Children[0].Children[2]).Property); Assert.AreEqual(null, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[3]).Property); Assert.AreEqual(propertyB, ((AnimationInstance<float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[2]).Property); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(600.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(100.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsTrue(manager.IsAnimated(objectA)); Assert.IsTrue(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsTrue(manager.IsAnimated(objectB)); Assert.IsTrue(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); // StartAnimation() controller = manager.StartAnimation(animationGroupRoot, new[] { objectA, objectB, objectC }); controller.UpdateAndApply(); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[0]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[1]).Property); Assert.AreEqual(null, ((AnimationInstance<Vector3F>)controller.AnimationInstance.Children[0].Children[2]).Property); Assert.AreEqual(null, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[3]).Property); Assert.AreEqual(propertyB, ((AnimationInstance<float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[2]).Property); Assert.AreEqual(600.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(100.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsTrue(manager.IsAnimated(objectA)); Assert.IsTrue(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsTrue(manager.IsAnimated(objectB)); Assert.IsTrue(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); manager.StopAnimation(new[] { objectA, objectB, objectC }); manager.UpdateAndApplyAnimation(new[] { objectA, objectB, objectC }); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); }
private static void AddSlide(TimelineGroup storyboard, Timeline thicknessAnimation) { Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath("Margin")); storyboard.Children.Add(thicknessAnimation); }
protected override void LoadContent() { _avatarDescription = AvatarDescription.CreateRandom(); _avatarRenderer = new AvatarRenderer(_avatarDescription); // Wrap the Stand0 AvatarAnimationPreset (see WrappedAnimationSample) to create an // infinitely looping stand animation. AvatarAnimation standAnimationPreset = new AvatarAnimation(AvatarAnimationPreset.Stand0); TimelineGroup standAnimation = new TimelineGroup { new WrappedExpressionAnimation(standAnimationPreset), new WrappedSkeletonAnimation(standAnimationPreset), }; _standAnimation = new TimelineClip(standAnimation) { LoopBehavior = LoopBehavior.Cycle, // Cycle the Stand animation... Duration = TimeSpan.MaxValue, // ...forever. }; // Load animations from content pipeline. _faintAnimation = Game.Content.Load<TimelineGroup>("Faint"); _jumpAnimation = Game.Content.Load<TimelineGroup>("Jump"); _kickAnimation = Game.Content.Load<TimelineGroup>("Kick"); _punchAnimation = Game.Content.Load<TimelineGroup>("Punch"); // The walk cycle should loop: Put it into a timeline clip and set a // loop-behavior. TimelineGroup walkAnimation = Game.Content.Load<TimelineGroup>("Walk"); _walkAnimation = new TimelineClip(walkAnimation) { LoopBehavior = LoopBehavior.Cycle, // Cycle the Walk animation... Duration = TimeSpan.MaxValue, // ...forever. }; base.LoadContent(); }
public EasingWindow(IServiceLocator services) : base(services) { _inputService = services.GetInstance<IInputService>(); _animationService = services.GetInstance<IAnimationService>(); Title = "EasingWindow"; StackPanel stackPanel = new StackPanel { Margin = new Vector4F(8) }; Content = stackPanel; TextBlock textBlock = new TextBlock { Text = "Test different Easing Functions in this window.", Margin = new Vector4F(0, 0, 0, 8), }; stackPanel.Children.Add(textBlock); StackPanel horizontalPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Vector4F(0, 0, 0, 8) }; stackPanel.Children.Add(horizontalPanel); textBlock = new TextBlock { Text = "Easing Function:", Width = 80, Margin = new Vector4F(0, 0, 8, 0), }; horizontalPanel.Children.Add(textBlock); _functionDropDown = new DropDownButton { Width = 100, // The DropDownButton automatically converts the items to string (using ToString) and // displays this string. This is not helpful for this sort of items. We want to display // the type name of the items instead. The following is a callback which creates a // TextBlock for each item. It is called when the drop-down list is opened. CreateControlForItem = item => new TextBlock { Text = item.GetType().Name }, }; horizontalPanel.Children.Add(_functionDropDown); _functionDropDown.Items.Add(new BackEase()); _functionDropDown.Items.Add(new BounceEase()); _functionDropDown.Items.Add(new CircleEase()); _functionDropDown.Items.Add(new CubicEase()); _functionDropDown.Items.Add(new ElasticEase()); _functionDropDown.Items.Add(new ExponentialEase()); _functionDropDown.Items.Add(new LogarithmicEase()); _functionDropDown.Items.Add(new HermiteEase()); _functionDropDown.Items.Add(new PowerEase()); _functionDropDown.Items.Add(new QuadraticEase()); _functionDropDown.Items.Add(new QuinticEase()); _functionDropDown.Items.Add(new SineEase()); _functionDropDown.SelectedIndex = 0; horizontalPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Vector4F(0, 0, 0, 8) }; stackPanel.Children.Add(horizontalPanel); textBlock = new TextBlock { Text = "Easing Mode:", Width = 80, Margin = new Vector4F(0, 0, 8, 0), }; horizontalPanel.Children.Add(textBlock); _modeDropDown = new DropDownButton { Width = 100, }; horizontalPanel.Children.Add(_modeDropDown); _modeDropDown.Items.Add(EasingMode.EaseIn); _modeDropDown.Items.Add(EasingMode.EaseOut); _modeDropDown.Items.Add(EasingMode.EaseInOut); _modeDropDown.SelectedIndex = 0; _slider = new Slider { Margin = new Vector4F(0, 16, 0, 0), SmallChange = 0.01f, LargeChange = 0.1f, Minimum = -0.5f, Maximum = 1.5f, Width = 250, HorizontalAlignment = HorizontalAlignment.Center, }; stackPanel.Children.Add(_slider); // Display the current value of the slider. var valueLabel = new TextBlock { Text = _slider.Value.ToString("F2"), HorizontalAlignment = HorizontalAlignment.Center, Margin = new Vector4F(0, 0, 0, 8), }; stackPanel.Children.Add(valueLabel); // Update the text every time the slider value changes. var valueProperty = _slider.Properties.Get<float>("Value"); valueProperty.Changed += (s, e) => valueLabel.Text = e.NewValue.ToString("F2"); Button button = new Button { Content = new TextBlock { Text = "Animate" }, HorizontalAlignment = HorizontalAlignment.Center, Margin = new Vector4F(0, 0, 0, 8), }; button.Click += OnButtonClicked; stackPanel.Children.Add(button); textBlock = new TextBlock { Text = "(Press the Animate button to animate the slider\n" + "value using the selected EasingFunction.\n" + "The slider goes from -0.5 to 1.5. The animation\n" + "animates the value to 0 or to 1.)", }; stackPanel.Children.Add(textBlock); // When the window is loaded, the window appears under the mouse cursor and flies to // its position. Vector2F mousePosition = _inputService.MousePosition; // The loading animation is a timeline group of three animations: // - One animations animates the RenderScale from (0, 0) to its current value. // - The other animations animate the X and Y positions from the mouse position // to current values. // The base class AnimatedWindow will apply this timeline group on this window // when the window is loaded. TimelineGroup timelineGroup = new TimelineGroup { new Vector2FFromToByAnimation { TargetProperty = "RenderScale", From = new Vector2F(0, 0), Duration = TimeSpan.FromSeconds(0.3), EasingFunction = new HermiteEase { Mode = EasingMode.EaseOut }, }, new SingleFromToByAnimation { TargetProperty = "X", From = mousePosition.X, Duration = TimeSpan.FromSeconds(0.3), }, new SingleFromToByAnimation { TargetProperty = "Y", From = mousePosition.Y, Duration = TimeSpan.FromSeconds(0.3), EasingFunction = new QuadraticEase { Mode = EasingMode.EaseIn }, }, }; // The default FillBehavior is "Hold". But this animation can be removed when it is finished. // It should not "Hold" the animation value. If FillBehavior is set to Hold, we cannot // drag the window with the mouse because the animation overrides the value. timelineGroup.FillBehavior = FillBehavior.Stop; LoadingAnimation = timelineGroup; // The closing animation is a timeline group of three animations: // - One animations animates the RenderScale to (0, 0). // - The other animations animate the X and Y positions to the mouse position. // The base class AnimatedWindow will apply this timeline group on this window // when the window is loaded. ClosingAnimation = new TimelineGroup { new Vector2FFromToByAnimation { TargetProperty = "RenderScale", To = new Vector2F(0, 0), Duration = TimeSpan.FromSeconds(0.3), EasingFunction = new HermiteEase { Mode = EasingMode.EaseIn }, }, new SingleFromToByAnimation { TargetProperty = "X", To = mousePosition.X, Duration = TimeSpan.FromSeconds(0.3), }, new SingleFromToByAnimation { TargetProperty = "Y", To = mousePosition.Y, Duration = TimeSpan.FromSeconds(0.3), EasingFunction = new QuadraticEase { Mode = EasingMode.EaseOut }, }, }; }
public void GetSubtreeDepthFirst() { 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.GetSubtree(null), Throws.TypeOf<ArgumentNullException>()); var animationInstance = animationA.CreateInstance(); var descendants = animationInstance.Children[2].GetSubtree().ToArray(); Assert.AreEqual(4, descendants.Length); Assert.AreEqual(animationInstance.Children[2], descendants[0]); Assert.AreEqual(animationInstance.Children[2].Children[0], descendants[1]); Assert.AreEqual(animationInstance.Children[2].Children[0].Children[0], descendants[2]); Assert.AreEqual(animationInstance.Children[2].Children[1], descendants[3]); }
protected ClockGroup(TimelineGroup timelineGroup) : base(timelineGroup) { throw new NotImplementedException(); }
private void CreateAndStartAnimations() { // Get the scene nodes that we want to animate using their names (as defined // in the .fbx file). _frontWheelLeft = _tank.GetSceneNode("l_steer_geo"); _frontWheelLeftRestPose = _frontWheelLeft.PoseLocal; _frontWheelRight = _tank.GetSceneNode("r_steer_geo"); _frontWheelRightRestPose = _frontWheelRight.PoseLocal; _hatch = _tank.GetSceneNode("hatch_geo"); _hatchRestPose = _hatch.PoseLocal; _turret = _tank.GetSceneNode("turret_geo"); _turretRestPose = _turret.PoseLocal; _cannon = _tank.GetSceneNode("canon_geo"); _cannonRestPose = _cannon.PoseLocal; // Create and start some animations. For general information about the DigitalRune Animation // system, please check out the user documentation and the DigitalRune Animation samples. // The front wheel should rotate left/right; oscillating endlessly. var frontWheelSteeringAnimation = new AnimationClip <float>( new SingleFromToByAnimation { From = -0.3f, To = 0.3f, Duration = TimeSpan.FromSeconds(3), EasingFunction = new SineEase { Mode = EasingMode.EaseInOut } }) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Oscillate, }; AnimationService.StartAnimation(frontWheelSteeringAnimation, _frontWheelSteeringAngle) .AutoRecycle(); // The hatch opens using a bounce ease. var bounceOpenAnimation = new SingleFromToByAnimation { By = -0.8f, Duration = TimeSpan.FromSeconds(1), EasingFunction = new BounceEase { Mode = EasingMode.EaseOut } }; // Then it should close again. var bounceCloseAnimation = new SingleFromToByAnimation { By = 0.8f, Duration = TimeSpan.FromSeconds(0.5f), }; // We combine the open and close animation. The close animation should start // 2 seconds after the open animation (Delay = 2) and it should stay some // time in the final position (Duration = 2). var bounceOpenCloseAnimation = new TimelineGroup { bounceOpenAnimation, new TimelineClip(bounceCloseAnimation) { Delay = TimeSpan.FromSeconds(2), Duration = TimeSpan.FromSeconds(2) }, }; // The bounceOpenCloseAnimation should loop forever. var hatchAnimation = new TimelineClip(bounceOpenCloseAnimation) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle, }; AnimationService.StartAnimation(hatchAnimation, _hatchAngle) .AutoRecycle(); // The turret rotates left/right endlessly. var turretAnimation = new AnimationClip <float>( new SingleFromToByAnimation { From = -0.5f, To = 0.5f, Duration = TimeSpan.FromSeconds(4), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut } }) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Oscillate, }; AnimationService.StartAnimation(turretAnimation, _turretAngle) .AutoRecycle(); // The cannon rotates up/down endlessly. var cannonAnimation = new AnimationClip <float>( new SingleFromToByAnimation { By = -0.7f, Duration = TimeSpan.FromSeconds(6), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut } }) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Oscillate, }; AnimationService.StartAnimation(cannonAnimation, _cannonAngle) .AutoRecycle(); }
// Create morph target animation in code. private static ITimeline CreateMorphingAnimation() { // The weight of each morph target is controlled by a keyframe animation. var browMad = new SingleKeyFrameAnimation { TargetProperty = "BROW-mad" }; browMad.KeyFrames.Add(new KeyFrame <float>(FrameToTime(15), 0)); browMad.KeyFrames.Add(new KeyFrame <float>(FrameToTime(30), 1)); browMad.KeyFrames.Add(new KeyFrame <float>(FrameToTime(65), 1)); browMad.KeyFrames.Add(new KeyFrame <float>(FrameToTime(80), 0)); var browSurp = new SingleKeyFrameAnimation { TargetProperty = "BROW-surp" }; browSurp.KeyFrames.Add(new KeyFrame <float>(FrameToTime(0), 0)); browSurp.KeyFrames.Add(new KeyFrame <float>(FrameToTime(15), 0.5f)); browSurp.KeyFrames.Add(new KeyFrame <float>(FrameToTime(30), 0)); browSurp.KeyFrames.Add(new KeyFrame <float>(FrameToTime(210), 0)); browSurp.KeyFrames.Add(new KeyFrame <float>(FrameToTime(220), 0.5f)); browSurp.KeyFrames.Add(new KeyFrame <float>(FrameToTime(230), 0.5f)); browSurp.KeyFrames.Add(new KeyFrame <float>(FrameToTime(250), 0)); var cheekIn = new SingleKeyFrameAnimation { TargetProperty = "CHEEK-in" }; cheekIn.KeyFrames.Add(new KeyFrame <float>(FrameToTime(0), 0)); cheekIn.KeyFrames.Add(new KeyFrame <float>(FrameToTime(15), 1)); cheekIn.KeyFrames.Add(new KeyFrame <float>(FrameToTime(30), 0)); var cheekOut = new SingleKeyFrameAnimation { TargetProperty = "CHEEK-out" }; cheekOut.KeyFrames.Add(new KeyFrame <float>(FrameToTime(25), 0)); cheekOut.KeyFrames.Add(new KeyFrame <float>(FrameToTime(35), 1)); cheekOut.KeyFrames.Add(new KeyFrame <float>(FrameToTime(65), 1)); cheekOut.KeyFrames.Add(new KeyFrame <float>(FrameToTime(80), 0)); var eyeClosed = new SingleKeyFrameAnimation { TargetProperty = "EYE-closed" }; eyeClosed.KeyFrames.Add(new KeyFrame <float>(FrameToTime(20), 0)); eyeClosed.KeyFrames.Add(new KeyFrame <float>(FrameToTime(25), 1)); eyeClosed.KeyFrames.Add(new KeyFrame <float>(FrameToTime(55), 0.2f)); eyeClosed.KeyFrames.Add(new KeyFrame <float>(FrameToTime(65), 0.2f)); eyeClosed.KeyFrames.Add(new KeyFrame <float>(FrameToTime(80), 0)); eyeClosed.KeyFrames.Add(new KeyFrame <float>(FrameToTime(230), 0)); eyeClosed.KeyFrames.Add(new KeyFrame <float>(FrameToTime(235), 1)); eyeClosed.KeyFrames.Add(new KeyFrame <float>(FrameToTime(240), 0)); var mouthE = new SingleKeyFrameAnimation { TargetProperty = "MOUTH-e" }; mouthE.KeyFrames.Add(new KeyFrame <float>(FrameToTime(115), 0)); mouthE.KeyFrames.Add(new KeyFrame <float>(FrameToTime(125), 0.7f)); mouthE.KeyFrames.Add(new KeyFrame <float>(FrameToTime(130), 0.7f)); mouthE.KeyFrames.Add(new KeyFrame <float>(FrameToTime(140), 0.9f)); mouthE.KeyFrames.Add(new KeyFrame <float>(FrameToTime(145), 0.9f)); mouthE.KeyFrames.Add(new KeyFrame <float>(FrameToTime(155), 0.0f)); var mouthU = new SingleKeyFrameAnimation { TargetProperty = "MOUTH-u" }; mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(25), 0)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(35), 0.5f)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(55), 0)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(145), 0)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(155), 0.5f)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(160), 0.5f)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(170), 0.9f)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(175), 0.9f)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(170), 0.9f)); mouthU.KeyFrames.Add(new KeyFrame <float>(FrameToTime(190), 0.0f)); var mouthSmile = new SingleKeyFrameAnimation { TargetProperty = "MOUTH-smile" }; mouthSmile.KeyFrames.Add(new KeyFrame <float>(FrameToTime(210), 0)); mouthSmile.KeyFrames.Add(new KeyFrame <float>(FrameToTime(220), 1)); mouthSmile.KeyFrames.Add(new KeyFrame <float>(FrameToTime(230), 1)); mouthSmile.KeyFrames.Add(new KeyFrame <float>(FrameToTime(250), 0)); // Combine the key frame animations into a single animation. var timelineGroup = new TimelineGroup(); timelineGroup.Add(browMad); timelineGroup.Add(browSurp); timelineGroup.Add(cheekIn); timelineGroup.Add(cheekOut); timelineGroup.Add(eyeClosed); timelineGroup.Add(mouthE); timelineGroup.Add(mouthU); timelineGroup.Add(mouthSmile); // Make an endless loop. return(new TimelineClip(timelineGroup) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle }); }
public BlendedAnimationSample(Microsoft.Xna.Framework.Game game) : base(game) { Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; // Create the animatable object. _animatableSprite = new AnimatableSprite("SpriteA", SpriteBatch, Logo) { Position = new Vector2(bounds.Center.X, bounds.Center.Y / 2.0f), Color = Color.Red, }; Vector2FromToByAnimation slowLeftRightAnimation = new Vector2FromToByAnimation { TargetProperty = "Position", From = new Vector2(bounds.Left + 100, bounds.Top + 200), To = new Vector2(bounds.Right - 100, bounds.Top + 200), Duration = TimeSpan.FromSeconds(4), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; ColorKeyFrameAnimation redGreenAnimation = new ColorKeyFrameAnimation { TargetProperty = "Color", EnableInterpolation = true, }; redGreenAnimation.KeyFrames.Add(new KeyFrame <Color>(TimeSpan.FromSeconds(0), Color.Red)); redGreenAnimation.KeyFrames.Add(new KeyFrame <Color>(TimeSpan.FromSeconds(4), Color.Green)); TimelineGroup animationA = new TimelineGroup { slowLeftRightAnimation, redGreenAnimation, }; Vector2FromToByAnimation fastLeftRightAnimation = new Vector2FromToByAnimation { TargetProperty = "Position", From = new Vector2(bounds.Left + 100, bounds.Bottom - 200), To = new Vector2(bounds.Right - 100, bounds.Bottom - 200), Duration = TimeSpan.FromSeconds(1), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; ColorKeyFrameAnimation blackWhiteAnimation = new ColorKeyFrameAnimation { TargetProperty = "Color", EnableInterpolation = true, }; blackWhiteAnimation.KeyFrames.Add(new KeyFrame <Color>(TimeSpan.FromSeconds(0), Color.Black)); blackWhiteAnimation.KeyFrames.Add(new KeyFrame <Color>(TimeSpan.FromSeconds(1), Color.White)); TimelineGroup animationB = new TimelineGroup { fastLeftRightAnimation, blackWhiteAnimation, }; // Create a BlendGroup that blends animationA and animationB. // The BlendGroup uses the TargetProperty values of the contained animations to // to match the animations that should be blended: // slowLeftRightAnimation with fastLeftRightAnimation // redGreenAnimation with blackWhiteAnimation _blendedAnimation = new BlendGroup { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; _blendedAnimation.Add(animationA, 1); _blendedAnimation.Add(animationB, 0); _blendedAnimation.SynchronizeDurations(); // Start blended animation. AnimationService.StartAnimation(_blendedAnimation, _animatableSprite).UpdateAndApply(); }
private void CreateAndStartAnimations() { // Get the scene nodes that we want to animate using their names (as defined // in the .fbx file). _frontWheelLeft = _tank.GetSceneNode("l_steer_geo"); _frontWheelLeftRestPose = _frontWheelLeft.PoseLocal; _frontWheelRight = _tank.GetSceneNode("r_steer_geo"); _frontWheelRightRestPose = _frontWheelRight.PoseLocal; _hatch = _tank.GetSceneNode("hatch_geo"); _hatchRestPose = _hatch.PoseLocal; _turret = _tank.GetSceneNode("turret_geo"); _turretRestPose = _turret.PoseLocal; _cannon = _tank.GetSceneNode("canon_geo"); _cannonRestPose = _cannon.PoseLocal; // Create and start some animations. For general information about the DigitalRune Animation // system, please check out the user documentation and the DigitalRune Animation samples. // The front wheel should rotate left/right; oscillating endlessly. var frontWheelSteeringAnimation = new AnimationClip<float>( new SingleFromToByAnimation { From = -0.3f, To = 0.3f, Duration = TimeSpan.FromSeconds(3), EasingFunction = new SineEase { Mode = EasingMode.EaseInOut } }) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Oscillate, }; AnimationService.StartAnimation(frontWheelSteeringAnimation, _frontWheelSteeringAngle) .AutoRecycle(); // The hatch opens using a bounce ease. var bounceOpenAnimation = new SingleFromToByAnimation { By = -0.8f, Duration = TimeSpan.FromSeconds(1), EasingFunction = new BounceEase { Mode = EasingMode.EaseOut } }; // Then it should close again. var bounceCloseAnimation = new SingleFromToByAnimation { By = 0.8f, Duration = TimeSpan.FromSeconds(0.5f), }; // We combine the open and close animation. The close animation should start // 2 seconds after the open animation (Delay = 2) and it should stay some // time in the final position (Duration = 2). var bounceOpenCloseAnimation = new TimelineGroup { bounceOpenAnimation, new TimelineClip(bounceCloseAnimation) { Delay = TimeSpan.FromSeconds(2), Duration = TimeSpan.FromSeconds(2)}, }; // The bounceOpenCloseAnimation should loop forever. var hatchAnimation = new TimelineClip(bounceOpenCloseAnimation) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle, }; AnimationService.StartAnimation(hatchAnimation, _hatchAngle) .AutoRecycle(); // The turret rotates left/right endlessly. var turretAnimation = new AnimationClip<float>( new SingleFromToByAnimation { From = -0.5f, To = 0.5f, Duration = TimeSpan.FromSeconds(4), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut } }) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Oscillate, }; AnimationService.StartAnimation(turretAnimation, _turretAngle) .AutoRecycle(); // The cannon rotates up/down endlessly. var cannonAnimation = new AnimationClip<float>( new SingleFromToByAnimation { By = -0.7f, Duration = TimeSpan.FromSeconds(6), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut } }) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Oscillate, }; AnimationService.StartAnimation(cannonAnimation, _cannonAngle) .AutoRecycle(); }
protected internal ClockGroup(TimelineGroup group) : base(group) {}
// 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 ShouldThrowWhenOwnerHasChildren() { var timelineGroup = new TimelineGroup(); var animationInstance = timelineGroup.CreateInstance(); var collection = new AnimationInstanceCollection(animationInstance); }
public void AnimateObject() { var obj = new AnimatableObject("TestObject"); var property = new AnimatableProperty <float> { Value = 10.0f }; obj.Properties.Add("Value", property); var property2 = new AnimatableProperty <float> { Value = 20.0f }; obj.Properties.Add("Value2", property2); var animationA = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, TargetObject = "ObjectA", // Should be ignored. TargetProperty = "Value", }; var animationB = new SingleFromToByAnimation { From = 200.0f, To = 300.0f, TargetObject = "ObjectB", // Should be ignored. TargetProperty = "", }; var animationGroup = new TimelineGroup(); animationGroup.Add(animationA); animationGroup.Add(animationB); var manager = new AnimationManager(); // Should assign animationA to 'obj'. var controller = manager.CreateController(animationGroup, obj); Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[0]).Property); Assert.AreEqual(null, ((AnimationInstance <float>)controller.AnimationInstance.Children[1]).Property); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); Assert.IsFalse(manager.IsAnimated(obj)); // When started then animationA should be active. controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsTrue(manager.IsAnimated(obj)); Assert.IsTrue(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(10.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsFalse(manager.IsAnimated(obj)); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); // Same test for AnimationManager.StartAnimation() controller = manager.StartAnimation(animationGroup, obj); controller.UpdateAndApply(); Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[0]).Property); Assert.AreEqual(null, ((AnimationInstance <float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(100.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsTrue(manager.IsAnimated(obj)); Assert.IsTrue(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); manager.StopAnimation(obj); manager.UpdateAndApplyAnimation(obj); Assert.AreEqual(10.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsFalse(manager.IsAnimated(obj)); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); }