Wavy line above effects
Interface drawing operation
1 private Point? _startPoint = null; 2 private void ContainerCanvas_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 3 { 4 var position = e.GetPosition(ContainerCanvas); 5 if (_startPoint == null) 6 { 7 _startPoint = position; 8 } 9 else 10 { 11 //删除预览 12 if (_previewLineElement != null ) 13 is { 14 ContainerCanvas.Children.Remove (_previewLineElement); 15 _previewLineElement = null ; 16 _lastMovedPoint = null ; . 17 } 18 is // determine the end point, the wavy line drawn . 19 var myLineElement = new new MyLineElement (); 20 is myLineElement.DrawLine ( (Point) _startPoint, position); 21 is ContainerCanvas.Children.Add (myLineElement); 22 is _startPoint = null ; 23 is } 24 } 25 26 private MyLineElement _previewLineElement = null; 27 private Point? _lastMovedPoint = null; 28 29 /// <summary> 30 /// 波浪线绘制预览 31 /// </summary> 32 /// <param name="sender"></param> 33 /// <param name="e"></param> 34 private void ContainerCanvas_OnMouseMove(object sender, MouseEventArgs e) 35 { 36 var position = e.GetPosition(ContainerCanvas); 37 if (_startPoint != null && (_lastMovedPoint == null || _lastMovedPoint != null & (position - (Point)_lastMovedPoint).Length >= 2)) 38 { 39 _lastMovedPoint = position; 40 if (_previewLineElement != null) 41 { 42 ContainerCanvas.Children.Remove(_previewLineElement); 43 } 44 var myLineElement = new MyLineElement(); 45 myLineElement.DrawLine((Point)_startPoint, position); 46 ContainerCanvas.Children.Add(myLineElement); 47 _previewLineElement = myLineElement; 48 } 49 }
Controls and wavy lines drawn
1 class MyLineElement : FrameworkElement 2 { 3 public MyLineElement() 4 { 5 _visualShape = new VisualCollection(this); 6 } 7 internal void DrawLine(Point startPoint, Point endPoint) 8 { 9 List<Point> points = ForgePoints(startPoint, endPoint); 10 DrawLine(points); 11 } 12 private const int SeparatorPiexl = 4; 13 private const int AbundancePiexl = 3; 14 private List<Point> ForgePoints(Point startPoint, Point endPoint) 15 { 16 var points = new List<Point>(); 17 18 var lineVector = endPoint - startPoint; 19 var lineDistance = lineVector.Length; 20 var lineAngle = Math.Atan2(-(endPoint.Y - startPoint.Y), endPoint.X - startPoint.X); 21 22 points.Add(startPoint); 23 is int index = 0 ; 24 BOOL isAbundanceUpward = to true ; 25 the while (index * SeparatorPiexl < lineDistance) 26 is { 27 index ++ ; 28 // calculate the interval length (analog point to the starting point) 29 var separatorDistance = index * SeparatorPiexl; 30 var = abundancePiexl abundancePiexl; 31 is var distanceToStartPoint = Math.Sqrt (Math.Pow (separatorDistance, 2 ) + Math.Pow (abundancePiexl, 2 )); 32 // calculate the simulated points, start point, an angle with the straight line 33 is var separatorAngle = Math.atan2 (AbundancePiexl, separatorDistance); 34 is separatorAngle = isAbundanceUpward separatorAngle:? - separatorAngle; 35 isAbundanceUpward =! IsAbundanceUpward; 36 // obtain an analog point the horizontal angle of 37 [ var mockPointAngle + = lineAngle separatorAngle; 38 is // calculated coordinates analog 39 var verticalDistance * = distanceToStartPoint Math.Sin (mockPointAngle); 40 var horizontalDistance * = distanceToStartPoint Math.Cos(mockPointAngle); 41 var mockPoint = new Point(startPoint.X + horizontalDistance, startPoint.Y - verticalDistance); 42 points.Add(mockPoint); 43 } 44 points.Add(endPoint); 45 return points; 46 } 47 48 private void DrawLine(List<Point> points) 49 { 50 _visualShape.Clear(); 51 52 var geometryTest = new StreamGeometry(); 53 the using ( var CTX = geometryTest.Open ()) 54 is { 55 ctx.BeginFigure (Points [ 0 ], to true , to false ); 56 is IF (points.Count% 2 == 0 ) 57 is { 58 // Draw second order Bessel Seoul function, the need to ensure an even point 59 ctx.PolyQuadraticBezierTo (points, to true , to true ); 60 } 61 is the else 62 is { 63 is //Draw second order Bessel functions, the need to ensure an even point 64 points.Insert ( 0 , Points [ 0 ]); 65 ctx.PolyQuadraticBezierTo (Points, to true , to true ); 66 } 67 68 ctx.Close (); 69 } 70 71 is var Visual = new new the DrawingVisual (); 72 the using ( var context = visual.RenderOpen ()) 73 is { 74 context.DrawGeometry (FillBrush, StrokePen, geometryTest); 75 } 76 _visualShape.Add (Visual); 77 } 78 79 #region internal method 80 81 [The Obsolete] 82 protected the override void the OnRender (a DrawingContext DrawingContext) 83 { 84 // deprecated , to achieve filling _visualShape 85 // drawingContext.DrawGeometry (FillBrush, StrokePen, BaseGeometry); 86 } 87 88 protected the override int VisualChildrenCount => _visualShape.Count; 89 90 protected override Visual GetVisualChild(int index) 91 { 92 if (index < 0 || index >= _visualShape.Count) 93 { 94 throw new ArgumentOutOfRangeException(); 95 } 96 97 return _visualShape[index]; 98 } 99 100 #endregion 101 102 #region 曲线属性 103 104 private readonly VisualCollection _visualShape; 105 protected Brush FillBrush { get; set; } = Brushes.Transparent; 106 public Brush LineBrush { get; set; } = Brushes.DarkSeaGreen; 107 protected double BorderThickness { get; set; } = 1.0; 108 private Pen _defaultPen = null; 109 protected Pen StrokePen 110 { 111 get 112 { 113 if (_defaultPen == null) 114 { 115 _defaultPen = new Pen(LineBrush, BorderThickness); 116 } 117 return _defaultPen; 118 } 119 set => _defaultPen = value; 120 } 121 122 #endregion 123 }
Github Address: https://github.com/Kybs0/WaveLineTextDemo