static Duration CalculateDuration(BubbleTaskGroup taskGroup, BubbleViewModel bubble, int millisecondsPerUnit) { var bubbleTask = taskGroup.SingleOrDefault(t => t.Bubble == bubble); int totalMilliseconds; switch (taskGroup.TaskType) { case BubbleTaskType.Burst: case BubbleTaskType.Add: totalMilliseconds = millisecondsPerUnit; break; case BubbleTaskType.MoveDown: totalMilliseconds = millisecondsPerUnit * Math.Abs(bubbleTask.MoveDistance); break; case BubbleTaskType.MoveRight: totalMilliseconds = millisecondsPerUnit * Math.Abs(bubbleTask.MoveDistance); break; default: throw new ArgumentException("Unrecognized BubblesTaskType value: " + taskGroup.TaskType, "taskType"); } return(new Duration(TimeSpan.FromMilliseconds(totalMilliseconds))); }
void GetStoryboardCreationData( BubbleTaskGroup taskGroup, out int millisecondsPerUnit, out Func <ContentPresenter, double> getTo, out DependencyProperty animatedProperty, out IEnumerable <BubbleViewModel> bubbles) { switch (taskGroup.TaskType) { case BubbleTaskType.Burst: millisecondsPerUnit = 100; getTo = cp => 0.0; animatedProperty = UIElement.OpacityProperty; bubbles = taskGroup.Select(t => t.Bubble); break; case BubbleTaskType.Add: millisecondsPerUnit = 100; getTo = cp => 1.0; animatedProperty = UIElement.OpacityProperty; bubbles = taskGroup.Select(t => t.Bubble); break; case BubbleTaskType.MoveDown: millisecondsPerUnit = 50; getTo = _bubbleCanvas.CalculateTop; animatedProperty = Canvas.TopProperty; // Sort the bubbles to ensure that the columns move // in sync with each other in an appealing way. bubbles = taskGroup.Select(t => t.Bubble) .OrderByDescending(b => b.Row) .ThenByDescending(b => b.Column); break; case BubbleTaskType.MoveRight: millisecondsPerUnit = 50; getTo = _bubbleCanvas.CalculateLeft; animatedProperty = Canvas.LeftProperty; // Sort the bubbles to ensure that the rows move // in sync with each other in an appealing way. bubbles = taskGroup.Select(t => t.Bubble) .OrderByDescending(b => b.Row) .ThenByDescending(b => b.Column); break; default: throw new ArgumentException("Unrecognized BubblesTaskType: " + taskGroup.TaskType); } }
internal Storyboard CreateStoryboard(BubbleTaskGroup taskGroup) { if (taskGroup.Count() == 0) { return(null); } int millisecondsPerUnit; Func <ContentPresenter, double> getTo; DependencyProperty animatedProperty; IEnumerable <BubbleViewModel> bubbles; this.GetStoryboardCreationData( taskGroup, out millisecondsPerUnit, out getTo, out animatedProperty, out bubbles); var storyboard = new Storyboard(); var targetProperty = new PropertyPath(animatedProperty); var beginTime = TimeSpan.FromMilliseconds(0); var beginTimeIncrement = TimeSpan.FromMilliseconds(millisecondsPerUnit / bubbles.Count()); foreach (ContentPresenter presenter in this.GetBubblePresenters(bubbles)) { var bubble = presenter.DataContext as BubbleViewModel; var anim = new EasingDoubleAnimation { BeginTime = beginTime, Duration = CalculateDuration(taskGroup, bubble, millisecondsPerUnit), Equation = EasingEquation.CubicEaseIn, To = getTo(presenter), }; Storyboard.SetTarget(anim, presenter); Storyboard.SetTargetProperty(anim, targetProperty); if (IsTaskStaggered(taskGroup.TaskType)) { beginTime = beginTime.Add(beginTimeIncrement); } storyboard.Children.Add(anim); } return(storyboard); }
void PerformTask(BubbleTaskGroup taskGroup, Storyboard storyboard) { if (storyboard != null) { // There are some bubbles that need to be animated, so we must // wait until the Storyboard finishs before completing the task. storyboard.Completed += delegate { taskGroup.RaiseComplete(); }; // Freeze the Storyboard to improve perf. storyboard.Freeze(); // Start animating the bubbles associated with the task. storyboard.Begin(this); } else { // There are no bubbles associated with this task, // so immediately move to the task completion phase. taskGroup.RaiseComplete(); } }
void ProcessTaskGroup(BubbleTaskGroup taskGroup) { var storyboard = _storyboardFactory.CreateStoryboard(taskGroup); this.PerformTask(taskGroup, storyboard); }