I may be met a rendering problem when I used the Canvas of QML to draw a line
-
I encapsulate a control with canvas. When it get a coordinate array, it can draw the trajectory the array discribed.But during development process,I met a problem and I will simplify the problem in this question. First ,let us read the code following.
Canvas { anchors.centerIn: parent width: 500 height: 500 Rectangle { anchors.fill: parent border.width: 1 color: "transparent" } onPaint: { var ctx = getContext('2d') ctx.lineWidth = 2 ctx.strokeStyle = "yellow" ctx.beginPath() ctx.moveTo(100, 100) ctx.lineTo(300, 100) ctx.moveTo(100, 150) ctx.lineTo(300, 150) ctx.lineTo(100, 150) ctx.lineTo(300, 150) ctx.closePath() ctx.stroke() } }
The output is:
When I draw along with a line or an arc back and forth, the both ends of the line will automatically draw an extra section. But the data is large,I can avoid this phenomenon. So do you konw the solution?Could some one teach me?It is important for me,thanks a lot! -
@Tiny-Leaf - you haven't simplified anything, your question is difficult to understand, at least to me and possibly 26 other people.
I pasted your code and got the same result you show in your image. What were you expecting?, please give some indication of what you expect to see, even if you mock it up using Paint or GIMP, give us a clue.
-
@Markkyboy I don't think you're paying attention to the coordinates. These two lines should be drawn to the same length. Instead of the second one being longer than the first one. This is also the question I wish to raise. Both of these lines should be 200 pixels long. This is precisely the question I wish to raise. The second line appears to have rendered an extra section at both ends, causing it to be longer than the actual 200 pixels. And what causes this problem is that when I draw the second line, I draw again from the end to the beginning, and from the beginning back to the end.
I wonder if this is a bug of Canvas. -
With Qt 6.5.1, It's the closePath() call that results in extra length. Overdrawing the line doesn't make a difference. Adding a call to closePath() after the line from (100,100) to (300,100) results in both lines being the same length, somewhere over 200 pixels. Removing the call to closePath() fixes the issue, or at least hides it.
It looks like a bug to me, but I'm not that familiar with the canvas element.
-
@jeremy_k Actually, this proble has no relative with the 'closePath' called.
'clothPath()' will create a closed figure,for example:onPaint: { var ctx = getContext('2d') ctx.lineWidth = 2 ctx.strokeStyle = "yellow" ctx.moveTo(100, 150) ctx.lineTo(300, 150) ctx.lineTo(200, 200) ctx.stroke() }
For the above code, if I don't call the closePath(),we will get the following result:
But , if i call the closePath(),we will get a triangle because 'clothPath()' will automatically connect the end point and start point:
onPaint: { var ctx = getContext('2d') ctx.lineWidth = 2 ctx.strokeStyle = "yellow" ctx.beginPath() ctx.moveTo(100, 150) ctx.lineTo(300, 150) ctx.lineTo(200, 200) ctx.closePath() ctx.stroke() }
Then return to my problem, speak accurately,I met a rendering problem. The main cause of this problem is that when I draw multiple line segments, rendering problems occur if two line segments overlap more than one another.
So, if I want to draw a trejectory like this:
(Make an explanation:Since my canvas needs to draw different tracks when it is used, I use loops when I draw to ensure that I can draw various tracks when I pass parameters externally)
When I want to draw the above trajectory, I have to draw from A to B ,then draw from B to A ,then draw from A to C ,then draw from C to A and so on. So there will be a a lot of overlap during drawing.
Finally, I got the result just like following:
In short, when I draw with canvas, if I encounter overlapping parts, I will produce unexpected rendering results.I think this is bug of canvas.
I don't konw if I made a clear statement. If any questions, welcom to leave a comment.
-
@Tiny-Leaf said in I may be met a rendering problem when I used the Canvas of QML to draw a line:
@jeremy_k Actually, this proble has no relative with the 'closePath' called.
For the code initially proposed, removing closePath() changed the output to 2 parallel horizontal lines, 200 pixels long. If you redefine the problem, don't be surprised that answers don't apply.
-
@jeremy_k Did you read the question carefully? Please answer the question after the actual code, don't waste other people's time, I am correcting your answer. The problem I raised was the rendering problem, and you were talking about closePath
-
@Tiny-Leaf
Try the following code. The length of three segments should be same.drawLine(ctx, 50, 50, 150, 50); drawLine(ctx, 150, 50, 50, 50); drawLine(ctx, 150, 100, 50, 100); function drawLine(ctx, x1, y1, x2, y2) { ctx.beginPath() ctx.moveTo(x1, y1) ctx.lineTo(x2, y2) ctx.stroke() }
BTW: you may somehow avoid to draw a line twice if possible. It is not efficient.