Skip to content

Commit 0165541

Browse files
committed
feat: Optimize ink and add smoothing points
1 parent bbedd0a commit 0165541

1 file changed

Lines changed: 73 additions & 14 deletions

File tree

src/WPFDevelopers.Shared/Controls/ScreenCut/ScreenCut.cs

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ public class ScreenCut : Window, IDisposable
203203
private Path _currentStrokeContainer = null;
204204
private List<Rectangle> _currentStrokeRectangles = new List<Rectangle>();
205205
private Stack<UIElement> _strokeHistory = new Stack<UIElement>();
206-
207206
private static readonly HashSet<string> PermanentElementNames = new HashSet<string>
208207
{
209208
"PART_LeftRectangle",
@@ -216,6 +215,10 @@ public class ScreenCut : Window, IDisposable
216215
"PART_ColorPanelWrap",
217216
"PART_BorderPopup"
218217
};
218+
private Point? _lastInkPoint = null;
219+
private List<Point> _inkPoints = new List<Point>();
220+
private const double MIN_DISTANCE = 2.0;
221+
private const double SMOOTH_FACTOR = 0.3;
219222

220223
public ScreenCut(int index)
221224
{
@@ -996,20 +999,15 @@ private void CheckPoint(Point current)
996999
private void DrwaInkControl(Point current)
9971000
{
9981001
CheckPoint(current);
999-
if (current.X >= _rect.Left
1000-
&&
1001-
current.X <= _rect.Right
1002-
&&
1003-
current.Y >= _rect.Top
1004-
&&
1005-
current.Y <= _rect.Bottom)
1002+
if (current.X >= _rect.Left && current.X <= _rect.Right &&
1003+
current.Y >= _rect.Top && current.Y <= _rect.Bottom)
10061004
{
10071005
if (_polyLine == null)
10081006
{
10091007
_polyLine = new Polyline();
10101008
_polyLine.Stroke = _currentBrush == null ? Brushes.Red : _currentBrush;
10111009
_polyLine.Cursor = Cursors.Hand;
1012-
_polyLine.StrokeThickness = 3;
1010+
_polyLine.StrokeThickness = 5;
10131011
_polyLine.StrokeLineJoin = PenLineJoin.Round;
10141012
_polyLine.StrokeStartLineCap = PenLineCap.Round;
10151013
_polyLine.StrokeEndLineCap = PenLineCap.Round;
@@ -1023,10 +1021,63 @@ private void DrwaInkControl(Point current)
10231021
};
10241022
_canvas.Children.Add(_polyLine);
10251023
SetUndoEnabled();
1024+
_inkPoints.Clear();
1025+
_inkPoints.Add(current);
1026+
_polyLine.Points.Add(current);
1027+
_lastInkPoint = current;
1028+
return;
1029+
}
1030+
1031+
var distance = Point.Subtract(current, _lastInkPoint.Value).Length;
1032+
1033+
if (distance < MIN_DISTANCE)
1034+
return;
1035+
1036+
_inkPoints.Add(current);
1037+
if (_inkPoints.Count >= 3)
1038+
{
1039+
int iterations = (int)(SMOOTH_FACTOR * 3);
1040+
iterations = Math.Max(1, Math.Min(3, iterations));
1041+
var smoothedPoints = ChaikinSmooth(_inkPoints, 1);
1042+
_polyLine.Points.Clear();
1043+
foreach (var point in smoothedPoints)
1044+
{
1045+
_polyLine.Points.Add(point);
1046+
}
1047+
}
1048+
else
1049+
{
1050+
_polyLine.Points.Add(current);
10261051
}
1052+
_lastInkPoint = current;
1053+
}
1054+
}
1055+
1056+
private List<Point> ChaikinSmooth(List<Point> points, int iterations)
1057+
{
1058+
if (points.Count < 3)
1059+
return new List<Point>(points);
10271060

1028-
_polyLine.Points.Add(current);
1061+
var currentPoints = new List<Point>(points);
1062+
1063+
for (int iter = 0; iter < iterations; iter++)
1064+
{
1065+
var newPoints = new List<Point>();
1066+
1067+
newPoints.Add(currentPoints[0]);
1068+
for (int i = 0; i < currentPoints.Count - 1; i++)
1069+
{
1070+
var p0 = currentPoints[i];
1071+
var p1 = currentPoints[i + 1];
1072+
var q = new Point(0.75 * p0.X + 0.25 * p1.X, 0.75 * p0.Y + 0.25 * p1.Y);
1073+
var r = new Point(0.25 * p0.X + 0.75 * p1.X, 0.25 * p0.Y + 0.75 * p1.Y);
1074+
newPoints.Add(q);
1075+
newPoints.Add(r);
1076+
}
1077+
newPoints.Add(currentPoints[currentPoints.Count - 1]);
1078+
currentPoints = newPoints;
10291079
}
1080+
return currentPoints;
10301081
}
10311082

10321083
private void DrawArrowControl(Point current)
@@ -1329,11 +1380,19 @@ protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
13291380
_isMouseUp = true;
13301381
if (_screenCutMouseType != ScreenCutMouseType.Default)
13311382
{
1332-
if (_screenCutMouseType == ScreenCutMouseType.MoveMouse)
1333-
EditBarPosition();
1334-
else if(_screenCutMouseType == ScreenCutMouseType.DrawMosaic)
1383+
switch (_screenCutMouseType)
13351384
{
1336-
CompleteCurrentStroke();
1385+
case ScreenCutMouseType.MoveMouse:
1386+
EditBarPosition();
1387+
break;
1388+
case ScreenCutMouseType.DrawMosaic:
1389+
CompleteCurrentStroke();
1390+
break;
1391+
case ScreenCutMouseType.DrawInk:
1392+
_lastInkPoint = null;
1393+
_inkPoints.Clear();
1394+
_polyLine = null;
1395+
break;
13371396
}
13381397

13391398
if (_rectangleRadioButton.IsChecked != true

0 commit comments

Comments
 (0)