3

Reading related articles, I've tried forcing the canvas size in pixels, specifying half pixels for the paths and also context.translate(0.5) but my canvas lines are still blurry.

See Codepen.

const ctx = canvas.getContext("2d");
ctx.translate(0.5, 0.5);

/* Function to draw HTML5 canvas line */
const drawPath = (startX, startY, endX, endY) => {
  ctx.beginPath(); 
  ctx.lineWidth = "1";
  ctx.strokeStyle = "red"; 
  ctx.moveTo(startX, startY);
  ctx.lineTo(endX, endY);
  ctx.stroke();
};

Where am I going wrong and how can I make my lines crisp like the border around the boxes in the demo?

How it appears for me: enter image description here

Community
  • 1
  • 1
tctc91
  • 1,343
  • 2
  • 21
  • 41
  • Works fine for me in Chrome http://imgur.com/a/515dZ – tctc91 Oct 09 '16 at 12:48
  • yes sorry working in chrome may be not in fx – Madhawa Priyashantha Oct 09 '16 at 12:48
  • Looking at the image you supplied. The canvas is half the resolution of the display. Zoom in and look at the pixels on the X, The DOM line is 1px yet still twice a wide as the pixels on the letter. That means the canvas is being stretched and the blur is due to the bilinear filtering. Either you are zoomed on the tab or you have a retina display. Set the `canvas.width` & height to twice what it is, set the `canvas.style.width` & height to DOM pixels. Remove the `ctx.translate` and add `ctx.scale(2,2)` and all things will be clear. – Blindman67 Oct 09 '16 at 15:14
  • Thanks, that solved it. Make that an answer and I'll accept :) – tctc91 Oct 09 '16 at 15:56
  • @Blindman67. ... and from the image only(!) -- bravo! – markE Oct 09 '16 at 22:37

1 Answers1

7

Retina & HiDPI devices

Looking at the image you supplied. The canvas is half the resolution of the display. Zoom in and look at the pixels on the "X", The DOM line is 1px yet still twice a wide as the pixels on that letter. That means the canvas is being stretched and the blur is due to the bilinear filtering. Either you are zoomed out on the tab or you have a retina or HiDPI display. Set the canvas.width & canvas.height to twice what it is, set the canvas.style.width & canvas.style.height to DOM pixels. Remove the ctx.translate and add ctx.scale(2,2) and all things will be clear.

A zoom in on the image

enter image description here

Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • `ctx.scale(2,2)` has the downside that you cannot draw 1px hairlines and every line is at least 2px wide. You can really see the difference on your retina device. Solution is to make canvas twice the size and draw twice as big – use the pixels of the physical device. I wrote a post about this here: http://www.ntaso.com/how-to-draw-sharp-lines-on-a-html5-canvas-for-retina-displays/ – ntaso Oct 21 '16 at 18:05
  • 1
    @ntaso Yes you can render 1px lines just set `ctx.lineWidth=0.5` and you get the 1px line while the scale is 2. If the scale is 100 you can draw a 1 pixel line with "ctx.lineWidth=0.01;". My answer is about making the canvas 2 times as big, the scale is just so you can still use DOM pixels coordinates to render and don't have to multiply every coordinate by 2. Its just a matter of convenience. – Blindman67 Oct 21 '16 at 18:24