private static void AttachedProgressOffsetPropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e) { LayoutPathChildWrapper wrapper = null; while (true) { o = VisualTreeHelper.GetParent(o); if (o is LayoutPathChildWrapper) { wrapper = (LayoutPathChildWrapper)o; } if (o is LayoutPath) { if (DesignMode.DesignModeEnabled) { ((LayoutPath)o).TransformToProgress(((LayoutPath)o).PathProgress); return; } ((LayoutPath)o).MoveChild(wrapper, wrapper.Progress + ((double)e.NewValue / 100.0), !DesignMode.DesignModeEnabled); return; } if (o == null) { return; } } }
private void Translate(LayoutPathChildWrapper wrapper, Point childPoint, bool smooth) { double translateX = childPoint.X, translateY = childPoint.Y; var wrappedChild = wrapper.Content as FrameworkElement; var translationSmoothing = TranslationSmoothingDefault; var progressDistance = wrapper.ProgressDistance; var childWidth = wrappedChild.ActualWidth; var childHeight = wrappedChild.ActualHeight; translateX = childPoint.X - ExtendedGeometry.PathOffset.X; translateY = childPoint.Y - ExtendedGeometry.PathOffset.Y; //center align child translateX -= childWidth / 2.0; translateY -= childHeight / 2.0; wrapper.SetTransformCenter(childWidth / 2.0, childHeight / 2.0); if (smooth) { var childTranslationSmoothing = GetTranslationSmoothing((UIElement)wrapper.Content); if (!double.IsNaN(childTranslationSmoothing)) { translationSmoothing = childTranslationSmoothing; } } if (smooth && !double.IsNaN(progressDistance) && translationSmoothing > 0 && progressDistance > 0 && !wrapper.NoTranslateSmoothForced) { wrapper.TranslateX = (wrapper.TranslateX * translationSmoothing * 0.2 / progressDistance + translateX) / (translationSmoothing * 0.2 / progressDistance + 1); wrapper.TranslateY = (wrapper.TranslateY * translationSmoothing * 0.2 / progressDistance + translateY) / (translationSmoothing * 0.2 / progressDistance + 1); } else { wrapper.TranslateX = translateX; wrapper.TranslateY = translateY; wrapper.NoTranslateSmoothForced = false; } }
private void MoveChild(LayoutPathChildWrapper wrapper, double childPercent, bool smooth) { wrapper.RawProgress = childPercent; ApplyStackFilters(ref childPercent, wrapper); if (ChildrenEasingFunction != null) { childPercent = ChildrenEasingFunction.Ease(childPercent / 100.0) * 100; wrapper.RawProgress = ChildrenEasingFunction.Ease(wrapper.RawProgress / 100.0) * 100; } Point childPoint; double rotationTheta; ExtendedGeometry.GetPointAtFractionLength(childPercent, out childPoint, out rotationTheta); wrapper.Progress = childPercent; Rotate(wrapper, rotationTheta, smooth); Translate(wrapper, childPoint, smooth); }
private void Rotate(LayoutPathChildWrapper wrapper, double rotationTheta, bool smooth) { if (ChildrenOrientation == Orientations.None) { wrapper.Rotation = 0; return; } if (ChildrenOrientation == Orientations.Vertical) { rotationTheta += 90; } else if (ChildrenOrientation == Orientations.VerticalReversed) { rotationTheta += 270; } else if (ChildrenOrientation == Orientations.ToPathReversed) { rotationTheta += 180; } rotationTheta = rotationTheta % 360; var rotationSmoothing = RotationSmoothingDefault; var progressDistance = wrapper.ProgressDistance; if (smooth) { var childRotationSmoothing = GetRotationSmoothing((UIElement)wrapper.Content); if (!double.IsNaN(childRotationSmoothing)) { rotationSmoothing = childRotationSmoothing; } } //try smooth rotation if (smooth && !double.IsNaN(progressDistance) && rotationSmoothing > 0 && progressDistance > 0 && !wrapper.NoRotateSmoothForced) { var degreesDistance = Math.Max(rotationTheta, wrapper.Rotation) - Math.Min(rotationTheta, wrapper.Rotation); var rotation = wrapper.Rotation; while (degreesDistance > 180) { if (rotationTheta > rotation) { rotation = rotation + 360; } else { rotation = rotation - 360; } degreesDistance = Math.Max(rotationTheta, rotation) - Math.Min(rotationTheta, rotation); } wrapper.Rotation = (rotation * rotationSmoothing * 0.2 + rotationTheta * progressDistance) / (rotationSmoothing * 0.2 + progressDistance); } else { wrapper.Rotation = rotationTheta; wrapper.NoRotateSmoothForced = false; } }
private void ApplyStackFilters(ref double progress, LayoutPathChildWrapper wrapper) { if (progress < 0) { if (!ExtendedGeometry.PathGeometry.Figures.First().IsClosed) { //avoid traveling form start to end when smoothing in enabled wrapper.ForceNoSmoothOnProcessing(); } if (StartBehavior == Behaviors.Collapse) { wrapper.Visibility = Visibility.Collapsed; } else { wrapper.Visibility = Visibility.Visible; if (StartBehavior == Behaviors.Stack) { progress = 0; } else { //transfer to range 0-100. //Examples // -2 + 100 = 98 exit // -102 + 100 = -2 + 100 = 98 exit while (progress < 0) { progress = 100 + progress; } } } } else if (progress > 100) { if (!ExtendedGeometry.PathGeometry.Figures.First().IsClosed) { //avoid traveling form end to start when smoothing in enabled wrapper.ForceNoSmoothOnProcessing(); } if (EndBehavior == Behaviors.Collapse) { wrapper.Visibility = Visibility.Collapsed; } else { wrapper.Visibility = Visibility.Visible; if (EndBehavior == Behaviors.Stack) { progress = 99.9999; } else { //transfer to range 0-100 progress = progress % 100; if (progress == 0) { progress = 99.9999; } } } } else { if (progress == 100) { progress = 99.9999; } wrapper.Visibility = Visibility.Visible; } }