public static void HideWithAnimation(this Window window) { if (hideAnimationInProgress) return; try { hideAnimationInProgress = true; var hideAnimation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(0.2)), FillBehavior = FillBehavior.Stop, EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseIn } }; var taskbarPosition = TaskbarService.GetWinTaskbarState().TaskbarPosition; switch (taskbarPosition) { case TaskbarPosition.Left: case TaskbarPosition.Right: hideAnimation.From = window.Left; break; default: hideAnimation.From = window.Top; break; } hideAnimation.To = (taskbarPosition == TaskbarPosition.Top || taskbarPosition == TaskbarPosition.Left) ? hideAnimation.From - 10 : hideAnimation.From + 10; hideAnimation.Completed += (s, e) => { window.Visibility = Visibility.Hidden; hideAnimationInProgress = false; }; switch (taskbarPosition) { case TaskbarPosition.Left: case TaskbarPosition.Right: window.ApplyAnimationClock(Window.LeftProperty, hideAnimation.CreateClock()); break; default: window.ApplyAnimationClock(Window.TopProperty, hideAnimation.CreateClock()); break; } } catch { hideAnimationInProgress = false; } }
private void ApplyAnimationClockTest(DoubleAnimation animation) { FrameworkElement element = new FrameworkElement(); TestRootClock rootClock = new TestRootClock(); rootClock.Tick(TimeSpan.FromSeconds(0)); AnimationTimelineClock clock = (AnimationTimelineClock)animation.CreateClock(); clock.Begin(rootClock); element.Width = 10; Assert.AreEqual(10, element.Width); element.ApplyAnimationClock(FrameworkElement.WidthProperty, clock); Assert.AreEqual(10, element.Width); rootClock.Tick(TimeSpan.FromSeconds(0.5)); Assert.AreEqual(15, element.Width); rootClock.Tick(TimeSpan.FromSeconds(1)); Assert.AreEqual(20, element.Width); clock.Stop(); element.Width = 30; Assert.AreEqual(30, element.Width); }
public void Init(MyModel mm) { this.mm = mm; Transform3DGroup t3dg = (Transform3DGroup)this.mm.m3dg.Transform; RotateTransform3D rtx = (RotateTransform3D)t3dg.Children[2]; AxisAngleRotation3D aar3dx = (AxisAngleRotation3D)rtx.Rotation; RotateTransform3D rty = (RotateTransform3D)t3dg.Children[3]; AxisAngleRotation3D aar3dy = (AxisAngleRotation3D)rty.Rotation; RotateTransform3D rtz = (RotateTransform3D)t3dg.Children[4]; AxisAngleRotation3D aar3dz = (AxisAngleRotation3D)rtz.Rotation; DoubleAnimation dax = new DoubleAnimation(360, new Duration(new TimeSpan(0, 0, 10))); dax.RepeatBehavior = RepeatBehavior.Forever; //aar3dx.BeginAnimation(AxisAngleRotation3D.AngleProperty, dax); clockx = dax.CreateClock(); DoubleAnimation day = new DoubleAnimation(360, new Duration(new TimeSpan(0, 0, 5))); day.RepeatBehavior = RepeatBehavior.Forever; clocky = day.CreateClock(); DoubleAnimation daz = new DoubleAnimation(360, new Duration(new TimeSpan(0, 0, 5))); daz.RepeatBehavior = RepeatBehavior.Forever; clockz = daz.CreateClock(); aar3dx.ApplyAnimationClock(AxisAngleRotation3D.AngleProperty, clockx); aar3dy.ApplyAnimationClock(AxisAngleRotation3D.AngleProperty, clocky); aar3dz.ApplyAnimationClock(AxisAngleRotation3D.AngleProperty, clockx); clockx.Controller.Begin(); clocky.Controller.Begin(); clockz.Controller.Begin(); }
/// <summary> /// Flashes the control's wheel display. /// </summary> public void FlashWheel() { DoubleAnimation opacityAnimation = new DoubleAnimation( 0.5, 0, new Duration(TimeSpan.FromSeconds(1))); AnimationClock opacityClock = opacityAnimation.CreateClock(); this.mouseFill.ApplyAnimationClock(Path.OpacityProperty, opacityClock); }
void AnimateIn(object sender, EventArgs args) { var animation = new DoubleAnimation { From = -Height, To = 0, Duration = AnimationDuration, EasingFunction = AnimationEase, }; animation.Completed += BeginTimer; RenderTransform.ApplyAnimationClock(TranslateTransform.YProperty, animation.CreateClock()); }
void AnimateOut(object sender, EventArgs args) { var animation = new DoubleAnimation { From = 0, To = -Height, Duration = AnimationDuration, EasingFunction = AnimationEase, }; animation.Completed += delegate { RaiseEvent(new RoutedEventArgs(DoneEvent)); }; RenderTransform.ApplyAnimationClock( TranslateTransform.YProperty, animation.CreateClock()); }
public void ScaleEasingAnimation(FrameworkElement element, double from, double to) { ScaleTransform scale = new ScaleTransform(); element.RenderTransform = scale; element.RenderTransformOrigin = new Point(0.5, 0.5);//定义圆心位置 DoubleAnimation scaleAnimation = new DoubleAnimation() { From = from, //起始值 To = to, //结束值 //EasingFunction = easing, //缓动函数 Duration = new TimeSpan(0, 0, 0, 0, 200) //动画播放时间 }; AnimationClock clock = scaleAnimation.CreateClock(); scale.ApplyAnimationClock(ScaleTransform.ScaleXProperty, clock); scale.ApplyAnimationClock(ScaleTransform.ScaleYProperty, clock); }
public void AnimationExpressionFillBehaviorStopTest() { DoubleAnimation animation = new DoubleAnimation { From = 10, To = 20, FillBehavior = FillBehavior.Stop }; TestRootClock rootClock = new TestRootClock(); rootClock.Tick(TimeSpan.FromSeconds(1)); FrameworkElement element = new FrameworkElement(); Assert.AreEqual(Double.NaN, element.Width); AnimationTimelineClock animationClock = (AnimationTimelineClock)animation.CreateClock(); element.ApplyAnimationClock(FrameworkElement.WidthProperty, animationClock); animationClock.Begin(rootClock); rootClock.Tick(TimeSpan.FromSeconds(1)); Assert.AreEqual(10, element.Width); rootClock.Tick(TimeSpan.FromSeconds(2)); Assert.AreEqual(Double.NaN, element.Width); }
private void InitAnimation() { var animation = new DoubleAnimation { From = -100, To = _window.ActualWidth + 100, RepeatBehavior = RepeatBehavior.Forever }; double duration = _window.ActualWidth/90; if (duration < 1) duration = 1; animation.Duration = new Duration(TimeSpan.FromSeconds((int) duration)); var clock = animation.CreateClock(); RadioTitle.ApplyAnimationClock(Canvas.LeftProperty, clock); clock.Controller.Begin(); }
public static void ScaleEasingAnimation(FrameworkElement element) { ScaleTransform scale = new ScaleTransform(); element.RenderTransform = scale; element.RenderTransformOrigin = new Point(0.5, 0.5);//定义圆心位置 EasingFunctionBase easing = new ElasticEase() { EasingMode = EasingMode.EaseOut, //公式 Oscillations = 1, //滑过动画目标的次数 Springiness = 10 //弹簧刚度 }; DoubleAnimation scaleAnimation = new DoubleAnimation() { From = 0, //起始值 To = 1, //结束值 EasingFunction = easing, //缓动函数 Duration = new TimeSpan(0, 0, 0, 1, 200) //动画播放时间 }; AnimationClock clock = scaleAnimation.CreateClock(); scale.ApplyAnimationClock(ScaleTransform.ScaleXProperty, clock); scale.ApplyAnimationClock(ScaleTransform.ScaleYProperty, clock); }
public void Init(MyModel mm) { this.mm = mm; //Transform3DGroup t3dg = (Transform3DGroup)this.mm.m3dg.Transform; //ScaleTransform3D st3d = (ScaleTransform3D)t3dg.Children[0]; if (mm.scaleTransform != null) { ScaleTransform3D st3d = mm.scaleTransform; st3d.ScaleX = 0.01; st3d.ScaleY = 0.01; st3d.ScaleZ = 0.01; DoubleAnimation dax = new DoubleAnimation(0.01, 10, new Duration(new TimeSpan(0, 0, 2))); dax.AutoReverse = true; dax.RepeatBehavior = RepeatBehavior.Forever; clock = dax.CreateClock(); st3d.ApplyAnimationClock(ScaleTransform3D.ScaleXProperty, clock); st3d.ApplyAnimationClock(ScaleTransform3D.ScaleYProperty, clock); st3d.ApplyAnimationClock(ScaleTransform3D.ScaleZProperty, clock); clock.Controller.Begin(); } }
public void ClockPlay() { DoubleAnimation tmp = new DoubleAnimation(1, 1, TimeSpan.FromMinutes(3)); tmp.RepeatBehavior = RepeatBehavior.Forever; mainClock = tmp.CreateClock(); mainClock.CurrentTimeInvalidated += mainClock_CurrentTimeInvalidated; demoTxt.ApplyAnimationClock(OpacityProperty, clock); }
private void showMouse(object sender, MouseEventArgs e) { Mouse.OverrideCursor = Cursors.Arrow; if (ClockMouse != null && ClockMouse.CurrentState == ClockState.Active) { ClockMouse.Controller.Stop(); } DoubleAnimation daHideControl = new DoubleAnimation(1, 0, TimeSpan.FromSeconds(5)); ClockMouse = daHideControl.CreateClock(); ClockMouse.Completed += (o, s) => { Mouse.OverrideCursor = Cursors.None; }; demoTxt.ApplyAnimationClock(OpacityProperty, ClockMouse); }
/// <summary> /// 播放指示条动画 /// </summary> /// <param name="Angle"></param> void BeginIndicatorValueChangedAnimation(double Angle) { if (Angle < 5) // 如果EndAngle小于5度,则直接显示角度值,QuinticEase会造成过冲,EndAngle会变成负值,造成闪动 { /* 如果上一个动画还在执行中,则先停止动画 * 否则执行中的动画可能再次更改EndAngle */ if (animationclock != null && animationclock.CurrentState != ClockState.Stopped) animationclock.Controller.Stop(); IndicatorBar.EndAngle = Angle; } else { animation = new DoubleAnimation(); animation.Duration = new Duration(TimeSpan.FromMilliseconds(500)); animation.To = Angle; // QuinticEase ease = new QuinticEase(); ElasticEase ease = new ElasticEase() { Oscillations = 2, Springiness = 5 }; ease.EasingMode = EasingMode.EaseOut; animation.EasingFunction = ease; animationclock = animation.CreateClock(); animationclock.Completed += animationclock_Completed; IndicatorBar.ApplyAnimationClock(Arc.EndAngleProperty, animationclock, HandoffBehavior.SnapshotAndReplace); animationclock.Controller.Begin(); } }
/// <summary> /// <see cref="Shape.OnRender"/> /// </summary> protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); if (IsAnimated) { var pathGeometry = polylineGeometry as PathGeometry; if (pathGeometry != null) { var startPoint = Points.FirstOrDefault(); // Each dot starts moving from the first point of the polyline. var anumationDuration = new Duration(TimeSpan.FromSeconds(length / DotSpeed)); var relativeDelay = DotInterval / DotSpeed; // The time span between the start moments of the animation for two sequential dots. var dotCount = (int)(length / DotInterval); for (var i = 0; i < dotCount; i++) { var animationDelay = TimeSpan.FromSeconds(i * relativeDelay); var centerAnimation = new PointAnimationUsingPath // Animate the center of the dot to move along the polyline. { PathGeometry = pathGeometry, Duration = anumationDuration, RepeatBehavior = RepeatBehavior.Forever, BeginTime = animationDelay // Delaying animation prevents all dots from starting moving at the same time. }; // A hacky way to hide the dot while it's waiting on the start - just set its radius to zero and restore back when it starts moving. var radiusAnimation = new DoubleAnimation(0.0, DotRadius, TimeSpan.Zero) { BeginTime = animationDelay }; var centerAnimationClock = centerAnimation.CreateClock(); var radiusAnimationClock = radiusAnimation.CreateClock(); // Draw the dot at the beginning of the line. Will have the same fill as line stroke and no border. drawingContext.DrawEllipse(Stroke, EmptyPen, startPoint, centerAnimationClock, 0.0, radiusAnimationClock, 0.0, radiusAnimationClock); } } } }
private void ToggleActionsDisplay(bool delayed) { if (this.gridActions != null) { double from = this.ActualHeight; double to = 14; if (!this.IsExpanded) to += this.gridActions.ActualHeight; DoubleAnimation actionsAnimation = new DoubleAnimation(from, to, new Duration(TimeSpan.FromMilliseconds(100))); actionsAnimation.Completed += delegate { this.animating = false; this.IsExpanded = !this.IsExpanded; }; if (delayed) actionsAnimation.BeginTime = TimeSpan.FromMilliseconds(1500); this.animating = true; this.toggleActionsClock = actionsAnimation.CreateClock(); this.ApplyAnimationClock(ResourceDetailView.HeightProperty, this.toggleActionsClock); } }
public static void ShowwithAnimation(this Window window) { if (showAnimationInProgress) return; try { showAnimationInProgress = true; window.Visibility = Visibility.Visible; window.Topmost = false; window.Activate(); var showAnimation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(0.3)), FillBehavior = FillBehavior.Stop, EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut } }; var taskbarPosition = TaskbarService.GetWinTaskbarState().TaskbarPosition; switch (taskbarPosition) { case TaskbarPosition.Left: case TaskbarPosition.Right: showAnimation.To = window.Left; break; default: showAnimation.To = window.Top; break; } showAnimation.From = (taskbarPosition == TaskbarPosition.Top || taskbarPosition == TaskbarPosition.Left) ? showAnimation.To - 25 : showAnimation.To + 25; showAnimation.Completed += (s, e) => { window.Topmost = true; showAnimationInProgress = false; window.Focus(); }; switch (taskbarPosition) { case TaskbarPosition.Left: case TaskbarPosition.Right: window.ApplyAnimationClock(Window.LeftProperty, showAnimation.CreateClock()); break; default: window.ApplyAnimationClock(Window.TopProperty, showAnimation.CreateClock()); break; } } catch { showAnimationInProgress = false; } }
void RemoveBorrowLabel() { if (!infoPanel.Children.Contains(borrowLabel)) { return; } var outAnimation = new DoubleAnimation { From = 1, To = 0, Duration = new Duration(TimeSpan.FromSeconds(EASE_IN_TIME)), }; outAnimation.Completed += delegate { infoPanel.Children.Remove(borrowLabel); infoPanel.Children.Remove(description); AddInputPanel(); }; description.ApplyAnimationClock(TextBlock.OpacityProperty, outAnimation.CreateClock()); borrowLabel.ApplyAnimationClock(TextBlock.OpacityProperty, outAnimation.CreateClock()); }
/// <summary> /// 缓动缩放动画 (提升效率)Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline), new FrameworkPropertyMetadata { DefaultValue = 20 }); /// </summary> /// <param name="element">缩放控件</param> /// <param name="aTime">缩放时间</param> /// <param name="dFrom">缩放起始值(推荐1)</param> /// <param name="dTo">缩放结束值(推荐1.5)</param> /// <param name="aOscillations">滑过动画目标的次数(推荐5)</param> /// <param name="aSpringiness">弹簧刚度(推荐10)</param> /// <returns>返回动画对象</returns> public static AnimationClock ScaleEasingAnimation(FrameworkElement element, TimeSpan aTime, double dFrom, double dTo, int aOscillations, int aSpringiness) { ScaleTransform scale = new ScaleTransform(); element.RenderTransform = scale; element.RenderTransformOrigin = new Point(0.5, 0.5);//定义圆心位置 EasingFunctionBase easing = new ElasticEase() { EasingMode = EasingMode.EaseOut, //公式 Oscillations = aOscillations, //滑过动画目标的次数 Springiness = aSpringiness //弹簧刚度 }; DoubleAnimation scaleAnimation = new DoubleAnimation() { From = dFrom, //起始值 To = dTo, //结束值 EasingFunction = easing, //缓动函数 Duration = aTime //动画播放时间 }; AnimationClock clock = scaleAnimation.CreateClock(); scale.ApplyAnimationClock(ScaleTransform.ScaleXProperty, clock); scale.ApplyAnimationClock(ScaleTransform.ScaleYProperty, clock); return clock; }
private void DrawMapPosition(DrawingContext context) { var myDoubleAnimation = new DoubleAnimation(); myDoubleAnimation.From = 1.0; myDoubleAnimation.To = 0.0; myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(3)); context.PushOpacity(1.0, myDoubleAnimation.CreateClock()); context.DrawRectangle(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF2B2B2B")), null, new Rect(702, 10, 248, 64)); var relativePositions = RelativePositions(); var position = new FormattedText( relativePositions.Item1.ToString() + "% / " + relativePositions.Item2.ToString() + "%", CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Charlemagne STD"), 36, Brushes.PaleVioletRed); context.DrawText(position, new Point(712, 20)); }
void AddInputPanel() { if (infoPanel.Children.Contains(inputPanel)) { return; } infoPanel.Children.Add(inputPanel); var inAnimation = new DoubleAnimation { From = 0, To = 1, Duration = new Duration(TimeSpan.FromSeconds(0.1)), }; inAnimation.Completed += delegate { usernameBox.SelectAll(); usernameBox.Focus(); Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe"); }; inputPanel.ApplyAnimationClock(Grid.OpacityProperty, inAnimation.CreateClock()); }
void AnimateIn(object sender, RoutedEventArgs e) { var animation = new DoubleAnimation(1, new Duration(TimeSpan.FromSeconds(EASE_IN_TIME))); var clock = animation.CreateClock(); ApplyAnimationClock(Grid.OpacityProperty, clock); }
void AnimateOut() { var animation = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromSeconds(EASE_IN_TIME))); var clock = animation.CreateClock(); ApplyAnimationClock(Grid.OpacityProperty, clock); clock.Completed += (s, e2) => { var args = new RoutedEventArgs(DoneEvent); RaiseEvent(args); }; HideTouchKeyboard(); }
private void OpacityAnimation(DropShadowEffect gridEffect, int from, int to) { DoubleAnimation scaleAnimation = new DoubleAnimation { From = from, //起始值 To = to, //结束值 //EasingFunction = easing, //缓动函数 Duration = new TimeSpan(0, 0, 0, 0, 600) //动画播放时间 }; AnimationClock clock = scaleAnimation.CreateClock(); gridEffect.ApplyAnimationClock(DropShadowEffect.OpacityProperty, clock); }
/// <summary> /// ẩn thanh điều khiển /// </summary> private void HideControl(int time = 5) { Title_Layout.Visibility = Visibility.Visible; ControlPlayer_Layout.Visibility = Visibility.Visible; if (WindowState == WindowState.Maximized || true) { if (time > 5) { localThread = new Thread(localThreadRun); localThread.IsBackground = true; localThread.Start(); } else { DoubleAnimation daHideControl = new DoubleAnimation(1, 0, TimeSpan.FromSeconds(2)); clock = daHideControl.CreateClock(); daHideControl.EasingFunction = new PowerEase() { EasingMode = EasingMode.EaseOut }; clock.Completed += (o, s) => { Mouse.OverrideCursor = Cursors.None; Title_Layout.Visibility = Visibility.Hidden; ControlPlayer_Layout.Visibility = Visibility.Hidden; try { if (localThread != null && localThread.IsAlive) localThread.Abort(); } catch (Exception) { } }; Title_Layout.ApplyAnimationClock(OpacityProperty, clock); ControlPlayer_Layout.ApplyAnimationClock(OpacityProperty, clock); } } else { this.VisibleControl(); } }
private void SiegAnimation(String bild) { BitmapImage bit_img = new BitmapImage(); bit_img.BeginInit(); bit_img.UriSource = new Uri(siegerBild, UriKind.RelativeOrAbsolute); bit_img.EndInit(); img_sieger.Source = bit_img; //Siegerhuhn wird präsentiert DoubleAnimation da = new DoubleAnimation(); da.To = -30; da.RepeatBehavior = RepeatBehavior.Forever; da.AutoReverse = true; da.AccelerationRatio = 1; da.Duration = new Duration(TimeSpan.Parse("0:0:0.4")); uhr = da.CreateClock(); img_sieger.ApplyAnimationClock(Canvas.TopProperty, uhr); uhr.Controller.Begin(); }
private void DrawInvalidCommand(DrawingContext context) { var origin = CaseVisibleOffset(_displayInvalidCommandOn.X, _displayInvalidCommandOn.Y); var myDoubleAnimation = new DoubleAnimation(); myDoubleAnimation.From = 1.0; myDoubleAnimation.To = 0.0; myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(3)); context.PushOpacity(1.0, myDoubleAnimation.CreateClock()); context.DrawRectangle(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#55FF2B2B")), null, new Rect(origin.Item1, origin.Item2, CaseWidth, CaseHeight)); context.Pop(); }
/// <summary> /// 绘制进度条的圆弧 /// </summary> void DrawAngle() { double angle = 0.1; double percent = 0; if (this.Min == this.Max) { angle = 0.1; percent = 0; } else { angle = (this.Progress - this.Min) / (this.Max - this.Min) * 360; // 计算圆弧绘制的弧度 if (angle <= 0) angle = 0.1; percent = (this.Progress - this.Min) / (this.Max - this.Min) * 100; // 计算百分比 if (percent <= 0) percent = 0; } // 绘制圆弧用到的动画 QuarticEase ease = new QuarticEase() { EasingMode = EasingMode.EaseOut }; DoubleAnimation animation = new DoubleAnimation(); animation.Duration = new Duration(TimeSpan.FromMilliseconds(500)); animation.To = angle; animation.EasingFunction = ease; animationclock = animation.CreateClock(); animationclock.Completed += animationclock_Completed; // 绘制圆弧 this.ProgressIndicator.ApplyAnimationClock(Arc.EndAngleProperty, animationclock, HandoffBehavior.SnapshotAndReplace); this.txt_ProgressValue.Text = string.Format("{0}%", percent.ToString("F1")); }
private void RefreshLine(double y) { y = (y > 1.0) ? 1.0 : y; if (y == double.NaN) return; if (refreshind >= lines.Count) { refreshind = 0; cnv.Children.Clear(); } try { var li = lines [refreshind]; var befli = (refreshind - 1 < 0) ? lines.Last() : lines [refreshind - 1]; var lenx = cnv.ActualWidth / ((double)lines.Count); var animateDuration = new Duration(new TimeSpan(0, 0, 0, 0, 500)); li.X1 = lenx * refreshind; li.X2 = li.X1; var destX = lenx * (refreshind + 1); li.Y1 = befli.Y2; // valid if refrehed before line li.Y2 = li.Y1; var destY = cnv.ActualHeight * (1.0 - y); this.lineXanim = new DoubleAnimation(destX, animateDuration); li.ApplyAnimationClock(Line.X2Property, null); this.lineXclock = lineXanim.CreateClock(); li.ApplyAnimationClock(Line.X2Property, this.lineXclock); this.lineYanim = new DoubleAnimation(destY, animateDuration); li.ApplyAnimationClock(Line.Y2Property, null); this.lineYclock = lineYanim.CreateClock(); li.ApplyAnimationClock(Line.Y2Property, this.lineYclock); cnv.Children.Add(li); this.lineXclock.Controller.Begin(); this.lineYclock.Controller.Begin(); ++refreshind; } catch { throw; } }
private void DrawTextAndDot(DrawingContext drawingContext, string text, double distance, Brush brush, bool up) { DoubleAnimation doubleAnimation = new DoubleAnimation(2, 0, new Duration(TimeSpan.FromMilliseconds(800))); doubleAnimation.AutoReverse = true; //doubleAnimation.RepeatBehavior = RepeatBehavior.Forever; Pen ellipsePen = this.GetGuidePen(brush); ellipsePen.Freeze(); //drawingContext.DrawEllipse(brush, ellipsePen, new Point(distance - 0.5, this.RenderSize.Height / 2 - 0.5), 3, 3); drawingContext.DrawEllipse(brush, ellipsePen, new Point(distance, this.RenderSize.Height / 2 - 0.5), null, 2, doubleAnimation.CreateClock(), 2, doubleAnimation.CreateClock()); FormattedText formatted = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Verdana"), 9, brush); //formatted.SetFontWeight(FontWeights.Bold); formatted.TextAlignment = TextAlignment.Left; double position = up ? (this.RenderSize.Height / 2 - 3 - formatted.Height) : (this.RenderSize.Height / 2 + 2); var point = new Point(Math.Max(0, distance - formatted.Width / 2), position); var sub = RenderSize.Width - point.X - formatted.Width; if (sub < 0) point.Offset(sub, 0); drawingContext.DrawText(formatted, point); }