title: How to calculate the offset to draw to the nearest pixel in a canvas with scale transformation applied?
body: <p>I am trying to draw a rectangle on an HTML canvas with pixel-perfect positioning, irregardless of the translation and scale applied to the canvas transform (assume rotation isn't used in this scenario).</p>
  <p>In this case, I always want the border of the rectangle to be 1px wide on the screen, irregardless of how zoomed in the rectangle is with the scale applied (which I have working in the demo below), however I also want it drawn at exact pixel coordinates so no antialiasing is applied.</p>
  <p>In the code below, I'm pretty sure I have to manipulate the arguments of ctx.rect to add offsets to each position in order to round it to display exactly on the nearest pixel on screen. But I'm not sure what math to use to get there?</p>
  <p>As you can see in this demo, with 1.5 scaling applied the rectangle is no longer drawn on pixel perfect coordinates.</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const canvases = [
    {
      ctx: document.getElementById('canvasOriginal').getContext('2d'),
      scale: 1,
      translateX: 0,
      translateY: 0
    },
    {
      ctx: document.getElementById('canvasZoomed').getContext('2d'),
      scale: 1.5,
      translateX: -0.5,
      translateY: -0.5
    }
  ];
  
  for (const { ctx, scale, translateX, translateY } of canvases) {
    ctx.translate(translateX, translateY);
    ctx.scale(scale, scale);
    ctx.beginPath();
    ctx.rect(1.5, 1.5, 4, 4);
    ctx.lineWidth = 1 / scale;
    ctx.strokeStyle = 'red';
    ctx.stroke();
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>canvas {
    border: 1px solid #ccc;
    image-rendering: pixelated;
    image-rendering: crisp-edges;
    width: 100px;
    height: 100px;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;canvas id="canvasOriginal" width="10" height="10"&gt;&lt;/canvas&gt;
  &lt;canvas id="canvasZoomed" width="10" height="10"&gt;&lt;/canvas&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>This is my desired result of the scaled image in the snippet above:</p>
  <p><a href="https://i.stack.imgur.com/YZ6w3.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YZ6w3.png" alt="enter image description here" /></a></p>
  <p>EDIT: Please do not ignore translation.</p>