0

I've looked extensively for an answer to this problem and what I found was either outdated or didn't work.

I'm trying to create a 320 x 240 pixel canvas and render some lines that appear pixelated (aliased, with clear edges to each pixel). The system I'm running this on reports a window.devicePixelRatio of 1, and I'm using the same values for the element's width/height as CSS's width/height.

Here is a screenshot of what I'm seeing (a Firefox browser on a Windows system that has system resolution set to 1360 x 768 on the left, and the "ideal" image as I would like to see it on the right - its a mock-up done with a paint program): enter image description here

Here are the three files I'm using:

let canvas = document.querySelector(".playground-canvas");
let ctx = canvas.getContext("2d");

ctx.fillRect(5, 5, 50, 50);

ctx.beginPath();
ctx.moveTo(4.5, 15.5);
ctx.lineTo(15.5, 220.5);
ctx.lineWidth = 0.5;
ctx.strokeStyle = "red";
ctx.stroke();
* {
  box-sizing: border-box;
}

body {
  background: #333;
  padding: 0;
  margin: 0;
  overflow: hidden;
}

.playground-container {
  position: relative;
  width: 320px;
  height: 240px;
  margin: 0 auto;
  outline: 1px solid #fff;
  transform: scale(2) translateY(30%);
}

.playground-container canvas {
  image-rendering: pixelated;
}
<!DOCTYPE html>
<html>
  <head>
    <title>The Ideal Playground</title>
    <link href="playground.css" type="text/css" rel="stylesheet" />
  </head>
  <body>
    <div class="playground-container">
      <canvas class="playground-canvas" width="320" height="240"></canvas>
    </div>

    <script src="playground.js"></script>
  </body>
</html>

I'm guessing I'm trying to ask something of HTML/CSS/JS that it just can't reliably do in today's world of high-DPI displays, etc.

Any help appreciated, thanks.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
dvanaria
  • 6,593
  • 22
  • 62
  • 82
  • Nothing has changed in the last 10 years about that. We still can't draw non-antialiased paths on a canvas. The post-processing done by CSS doesn't matter, all it will do is make the antialiasing pixels bigger, it can't remove it. – Kaiido Jun 13 '22 at 06:28
  • The only valid solution I found when looking at the post that was linked when this question was closed: write up a bresenham algorithm and draw to the canvas a pixel at a time (using fillrect(x,y,1,1) along with the bresenham algorithm.) It works beautifully, at the expense of speed. The problem with the linked post is that it is by far outdated by now and stackoverflow users who are in search of a solution to this problem will have to weed through a lot of dead-end solutions that no longer work in current browsers. – dvanaria Jun 15 '22 at 13:14
  • The answers there are not outdated. Being myself relatively involved with what should / could be added to the API I'm sorry about that. I pushed a few times so that we finally have a shapeSmoothingEnabled and shapeSmoothingQuality properties, like SVG has, but it's currently not moving at all. So yes, there is no built in, you can do a bresenham, or even now (in Chrome and FF) you can use SVG filters to remove the transparent pixels but that's still the up to date state of the situation. – Kaiido Jun 15 '22 at 14:03
  • And for your bresenham perfs: https://stackoverflow.com/questions/50625903/faster-bresenham-line-for-html-canvas – Kaiido Jun 15 '22 at 15:04
  • don't edit your question to add an answer. A question need to remain a question – Temani Afif Jun 16 '22 at 08:48

0 Answers0