private void CreateSpinAnimation(SpinInstruction instruction, int tabToIndex, double fromAngle, double toAngle) { RotateTransform3D flipTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), 0)); DoubleAnimation flipAnimation = new DoubleAnimation(0, 360, new Duration(new TimeSpan(0, 0, 0, 0, animationDuration))); RotateTransform3D spinTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0)); DoubleAnimation spinAnimation = new DoubleAnimation(fromAngle, toAngle, new Duration(new TimeSpan(0, 0, 0, 0, animationDuration))); spinAnimation.Completed += (sender, e) => { instructions.Dequeue(); currentIndex = instruction.To; currentTabIndex = tabToIndex; isAnimating = false; Animate(); }; spinTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, spinAnimation); if (EnableFlip) { flipTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, flipAnimation); } Transform3DGroup carouselTransform = new Transform3DGroup(); carouselTransform.Children.Add(spinTransform); if (EnableFlip) { carouselTransform.Children.Add(flipTransform); } CarouselContainer.Transform = carouselTransform; double currentDistance = CalculateCameraDistance(instruction.From, currentTabIndex); double nextDistance = CalculateCameraDistance(instruction.To, tabToIndex); System.Diagnostics.Debug.WriteLine(nextDistance); DoubleAnimation cameraAnimation = new DoubleAnimation(currentDistance, nextDistance, new Duration(new TimeSpan(0, 0, 0, 0, animationDuration))); Transform3D cameraTransform = new TranslateTransform3D(0, 0, currentDistance); MainCamera.Transform = cameraTransform; cameraTransform.BeginAnimation(TranslateTransform3D.OffsetZProperty, cameraAnimation); }
private void Animate() { if (instructions.Count == 0 || isAnimating) { return; } SpinInstruction instruction = instructions.Peek(); bool wrapIt = false; if (instruction.To < 0 || instruction.To >= elements.Count) { if (WrapAtEnd && (instruction.To == -1 || instruction.To == elements.Count)) { wrapIt = true; instruction = new SpinInstruction(instruction.From, instruction.To < 0 ? elements.Count - 1 : 0); } else { instructions.Dequeue(); isAnimating = false; return; } } double angle = 360.0 / tabs.Count; int tabToIndex = AlwaysOnlyOneStep ? GetSafeIndex(currentTabIndex + Math.Sign(instruction.To - instruction.From)) : GetSafeIndex(instruction.To); if (wrapIt) { if (instruction.To == 0) { tabToIndex = 0; } if (instruction.To == elements.Count - 1) { tabToIndex = tabs.Count - 1; } } // Unhook if required foreach (Tab owner in (from tab in tabs where tab.Element == elements[instruction.To] || tab.Element == elements[instruction.From] select tab)) { owner.Element = null; } tabs[currentTabIndex].Element = elements[instruction.From]; tabs[currentTabIndex].UpdateTransform(currentTabIndex, angle, CalculateRadius()); tabs[tabToIndex].Element = elements[instruction.To]; tabs[tabToIndex].UpdateTransform(tabToIndex, angle, CalculateRadius()); isAnimating = true; double fromAngle = currentTabIndex * angle; double toAngle = tabToIndex * angle; if (wrapIt) { if (instruction.To == 0) { toAngle += 360; } if (instruction.To == elements.Count - 1) { toAngle -= 360; } } if (instruction.To - instruction.From > 0 && tabToIndex < currentTabIndex) { toAngle += 360; } if (instruction.To - instruction.From < 0 && tabToIndex > currentTabIndex) { toAngle -= 360; } CreateSpinAnimation(instruction, tabToIndex, fromAngle, toAngle); }