C
C#2y ago
h0la

❔ WPF Canvas starts getting choppy and laggy after drawing a long line

Hello, I am making an application with a feature that lets you draw on the screen, however after drawing a long line the canvas gets very laggy and choppy, while creating the line and after its been completed. Any idea what is causing this and how I would improve the performance? Is it just limitations of the Canvas element? The line is a Path element, but I have also tried changing it to a Visual element instead but that didn't solve the issue. I attached a video where you can see how the issue presents itself.
12 Replies
JakenVeina
JakenVeina2y ago
to be honest, I don't see any choppiness or lagginess in that video, except for the one brief moment after the first line is broken. Is that you releasing the mouse, or is your mouse input getting interrupted somehow, by like a lag spike?
h0la
h0laOP2y ago
if you follow the behaviour of the line being drawn you can see it start off very responsive and smooth and then start slacking behind and becoming slower and yes that is me releasing the mouse
JakenVeina
JakenVeina2y ago
I really don't seen it so, how are you translating mouse movements into a Path?
h0la
h0laOP2y ago
private void Draw(MouseEventArgs e)
{

SolidColorBrush brush = new(Services.brushColor);
Line line = new()
{
Stroke = brush,
StrokeThickness = Services.brushSize,
StrokeEndLineCap = PenLineCap.Round,
StrokeStartLineCap = PenLineCap.Round,
X1 = currentPoint.X,
Y1 = currentPoint.Y,
X2 = e.GetPosition(this).X,
Y2 = e.GetPosition(this).Y
};

points.Add(new Point(e.GetPosition(this).X, e.GetPosition(this).Y));

currentPoint = e.GetPosition(this);

sketchCanvas.Children.Add(line);
}
private void Draw(MouseEventArgs e)
{

SolidColorBrush brush = new(Services.brushColor);
Line line = new()
{
Stroke = brush,
StrokeThickness = Services.brushSize,
StrokeEndLineCap = PenLineCap.Round,
StrokeStartLineCap = PenLineCap.Round,
X1 = currentPoint.X,
Y1 = currentPoint.Y,
X2 = e.GetPosition(this).X,
Y2 = e.GetPosition(this).Y
};

points.Add(new Point(e.GetPosition(this).X, e.GetPosition(this).Y));

currentPoint = e.GetPosition(this);

sketchCanvas.Children.Add(line);
}
this function gets called every MouseMove event and after you let go of the mouse those lines get deleted and this function is called to create a single smoothed path
h0la
h0laOP2y ago
BlazeBin - oldrpahuhugx
A tool for sharing your source code with the world!
JakenVeina
JakenVeina2y ago
so, you're creating individual line segments on each move perhaps that needs to be throttled a bit? does that have the potential to generate, like, duplicate segments? in the event that the mouse has moved only a small amount?
h0la
h0laOP2y ago
I battled this by removing points that were too close to eachother I just feel like it gets too laggy too fast and that I've missed something
JakenVeina
JakenVeina2y ago
off-hand, I dunno what that would be like I said, I very much don't see what you describe maybe you can only really feel it hands-on if having that many lines on the canvas at once, that quickly, is just too much for WPF, you'd just have to figure out how to use something more primitive or wrap up the drawing into one object sooner rebuilding a Path each time might be the better option or it might make things worse on account of the complexity of the Path
Klarth
Klarth2y ago
I would only use shapes if you plan on adding selection and other user interactions. Otherwise, just use WriteableBitmap. If you stick with Canvas, your main strategies will be: 1. Throttling. 2. Two canvases: one for shapes being drawn (on top) and one for shapes previously drawn. Transfer the shape to the "drawn" canvas once the shape is completed. If there are a lot of shapes / complex shapes, it might keep the previously drawn canvas from being invalidated as often. 3. Run the app in release mode and see if that helps enough.
JakenVeina
JakenVeina2y ago
all excellent points
Klarth
Klarth2y ago
The two canvas thing won't work if you need ZIndex layering while drawing though. Assumes you're always drawing on top.
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server