Canvas 2d, как рисовать чтоб все было четким?

Рисуем сетку на канвасе

<canvas id="canvas" style="display: block;">Your browser is not support.</canvas>
<script>

function drw(ctx) {
        ctx.lineWidth = 0.5; 
        ctx.strokeStyle = "grey";
        ctx.imageSmoothingEnabled = false;

        for(var x=0;x<500;x+=6) {
          ctx.beginPath();
          ctx.moveTo(x,0);
          ctx.lineTo(x,500);
          ctx.closePath();
          ctx.stroke();

          ctx.beginPath();
          ctx.moveTo(0,x);
          ctx.lineTo(500,x);
          ctx.closePath();
          ctx.stroke();
        }      
}

const dpr = window.devicePixelRatio || 1;
var 
    can = document.getElementById('canvas'),
    ctx = can.getContext('2d');

    can.width = 500;
    can.height = 500;
    can.width = can.offsetWidth * dpr;
    can.height = can.offsetHeight * dpr;
    ctx.scale(dpr, dpr);

    can.style.imageRendering = "pixelated";
    drw(ctx);

</script>

получаем разные линии, как сделать так чтоб все лиии были одинаковые и четкие?

Приветствия. Давай сразу на “ты”.

Во-первых у меня на устройстве с кратной плотностью пикселей подобных проблем с поведением нет. Вижу 1000 на 1000 канвас с сеткой. Ниже опишу какие нюансы надо учесть чтобы на других устройствах вглядело подобным образом

В коде есть пара нюансов которые мешают получить четкую сетку

  1. Ширина линии должна быть целым (сейчас ширина 0,5 ctx.lineWidth = 0.5;). Используй целое. Все равно ты увеличиваешь размер канваса так чтобы пиксели канваса соответствовали физическим пикселям.
  2. Я предполжу что ты хочешь достичь линий толщеной с физический пиксель (программный пиксель будет пропорционально толще). Такое выглядит круто. Для этого нужна комбинация из установления размеров канваса пропорционально DPR (device pixel ratio, отношение плотности пикселей (не знаю точный термин на русском)).
    1. сделать ширину линии пропорциональной dpr
    2. нарисовать на увеличенном канвасе
    3. трансформировать-уменьшить размер канваса.
  3. Математика вычисления размера канваса “перемешана”. Тут ты задаешь 500 пикселей can.width = 500;, и ниже задаешь новое значение can.width = can.offsetWidth * dpr;.

Думаю что мы за одну итерацию не дойдем до того что именно тебе надо. Доспрашивай, доуточняй

Конечный результат (канвас на 500 программных пикселей с сеткой линий толщиной в физический пиксель):

<canvas id="canvas" style="display: block;">Your browser is not support.</canvas>
<script>
const dpr = window.devicePixelRatio || 1;

function drw(ctx) {
    ctx.lineWidth = 1 / dpr;  // ширина линии пропорциональна DPR
    ctx.strokeStyle = "grey";
    ctx.imageSmoothingEnabled = false;

    for(var x=0;x<500;x+=6) {
      ctx.beginPath();
      ctx.moveTo(x,0);
      ctx.lineTo(x,500);
      ctx.closePath();
      ctx.stroke();

      ctx.beginPath();
      ctx.moveTo(0,x);
      ctx.lineTo(500,x);
      ctx.closePath();
      ctx.stroke();
    }      
}


var can = document.getElementById('canvas'),
var ctx = can.getContext('2d');
	
const width = 500;
const height = 500;
can.width = width * dpr;   // увеличиваем канвас пропорционально отношению размеров программно-физических пикселей
can.height = height * dpr; // увеличиваем канвас пропорционально отношению размеров программно-физических пикселей
can.style.width = width + 'px';
can.style.height = height + 'px';

ctx.setTransform(dpr, 0, 0, dpr, 0.5, 0.5); // 0.5 - магическое число которое убирает разброс расстояний между линиями. Это общий трюк суть которого сложно объяснить сжато

can.style.imageRendering = "pixelated";
drw(ctx);

</script>