Reputation: 8726
I just want to draw a dashed line by canvas with lineDash is [1,1]. I found the function setLineDash
, in theory, that can do it. But I cannot make it work and cannot figure out how the function work.
AFAIK, setLineDash
function takes an argument that is an array. For example, setLineDash([1,1])
should set the dash length to 1
and the space length to 1
too. But, it does not. It just draws a solid line.
Please take a look at the snippet below.
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
canvas.width = 300
canvas.height = 300
ctx.lineWidth = 3
ctx.strokeStyle = 'red'
drawLine([1, 1], 25)
drawLine([2, 2], 50)
drawLine([3, 3], 75)
drawLine([4, 4], 100)
drawLine([5, 5], 125)
drawLine([6, 6], 150)
drawLine([7, 7], 175)
drawLine([8, 8], 200)
drawLine([9, 9], 225)
function drawLine(lineDash, y) {
ctx.beginPath()
ctx.setLineDash(lineDash)
ctx.moveTo(200, y)
ctx.lineTo(100, y)
ctx.closePath()
ctx.stroke()
}
<canvas id="myCanvas"></canvas>
Upvotes: 0
Views: 2154
Reputation: 620
closePath() method of the Canvas 2D API attempts to add a straight line from the current point to the start of the current sub-path.
So basically you are drawing in each drawLine()
function call two lines.
Your function each time draws 100px long line, but I will show on below examples shorten line (20px long) examples which will show what is happening:
Lets look at this code:
ctx.setLineDash([5, 5]);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(20, 0);
ctx.closePath();
ctx.stroke();
1 function first draws a 20px long line (from left to right), where it starts with 5px line, then 5px space, and repeat it until end is reached. Something like below:
| 1 1 2|
pixel: |1 5 0 5 0|
line start>|_____ _____ |line end
2 when closePath()
is called, a second line is being drawn, this time from 20th pixel back to 1st on canvas (from right to left), and this time it also starts with 5px line:
| 1 1 2|
pixel: |1 5 0 5 0|
line end| _____ _____| <line start
3 And when you combine those two lines together you will see like it is one continues line. And when you draw 100px long line the same situation will occure for dashes: [1,1], [2,2], [4,4], [5,5] what can you see on your snippset.
So basically you should NOT use closePath() at all.
Upvotes: 0
Reputation: 8726
Finally, I found the culprit is the order of ctx.closePath()
and ctx.stroke()
. I called ctx.stroke()
after closing the path so it makes the result go wrong.
Re-order the function call and it works as expected.
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
canvas.width = 300
canvas.height = 300
ctx.lineWidth = 3
ctx.strokeStyle = 'red'
drawLine([1, 1], 25)
drawLine([2, 2], 50)
drawLine([3, 3], 75)
drawLine([4, 4], 100)
drawLine([5, 5], 125)
drawLine([6, 6], 150)
drawLine([7, 7], 175)
drawLine([8, 8], 200)
drawLine([9, 9], 225)
function drawLine(lineDash, y) {
ctx.beginPath()
ctx.setLineDash(lineDash)
ctx.moveTo(200, y)
ctx.lineTo(100, y)
ctx.stroke()
ctx.closePath()
}
<canvas id="myCanvas"></canvas>
Upvotes: 2
Reputation: 642
Try This
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.setLineDash([1, 1]);
ctx.beginPath();
ctx.moveTo(0, 100);
ctx.lineTo(200, 100);
ctx.stroke();
<canvas id='canvas' width='350px' height='300px'></canvas>
Upvotes: 0