Karan Singh
Karan Singh

Reputation: 1164

Drawing lines on canvas are dotted

I was trying to work on a rainbow-pen drawing canvas, but whenever I draw, the lines appear dotted. Only when I move really slowly, does it appear properly.

The 'mousemove' event listener, isn't really being able to detect fast changes or is there some other issue in my code? Also, here is the codepen link, if anyone wants a working program.

Here is the codepen!

const canvas = document.querySelector('#draw');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext("2d");
ctx.lineWidth = 50;
ctx.lineCap = "round";
ctx.lineJoin = "line";
ctx.strokeStyle = 0;
let hue = 0;
var [x, y] = [0, 0];
let paint = false;

canvas.addEventListener('mousedown', beginDraw);

function beginDraw(e) {
  paint = true;
  [x, y] = [e.x, e.y];
  // ctx.moveTo(x, y);
}

canvas.addEventListener('mousemove', draw);

function draw(e) {
  if (paint == false)
    return;
  ctx.strokeStyle = `hsla(${hue}, 100%, 50%, 0.5)`;
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(e.x, e.y);
  ctx.stroke();
  [x, y] = [e.x, e.y];
  hue++;
}

canvas.addEventListener('mouseup', endDraw);

function endDraw() {
  paint = false;
}
<canvas id="draw"></canvas>

Upvotes: 5

Views: 619

Answers (2)

Alexander van Oostenrijk
Alexander van Oostenrijk

Reputation: 4754

The mousemove event handler fires only so many times per second. On each execution, your code draws a line from the previous mouse location to the current mouse location. Each subsequent line partially overlaps the previous line.

For slow strokes, the overlap is almost 100% so you won't see the effect, but for faster strokes, the overlap is shown as a circle. Since you're using partial transparency, the spots where the lines overlap become darker and this causes the "dotted" effect you are seeing.

If you set your opacity to 1, the effect will go away.

Upvotes: 1

Łukasz Blaszyński
Łukasz Blaszyński

Reputation: 1565

I think the problem is opacity in your hsla function for color. Because it is set to 0.5 you have some transparency and because you are drawing a line for each mousemove you have for each mouse move event start and end point for your drawing. Sometimes these points overlaps each other.

You can remove transparency and keep it to 1. In such case you are no longer see places where 2 dots are drawn one above another making color more visible to others.

ctx.strokeStyle = `hsla(${hue}, 100%, 50%, 1)`;

In case you dont like to see dots when color changes you will need to make more color values also playing with other parameters not only hue parameter, because color step may be to large and you may see edges when color is changed.

Upvotes: 1

Related Questions