HTML5 Canvas and Anti-aliasing

You may translate canvas by half-pixel distance.

ctx.translate(0.5, 0.5);

Initially the canvas positioning point between the physical pixels.


Anti-aliasing cannot be turned on or off, and is controlled by the browser.

Can I turn off antialiasing on an HTML <canvas> element?


It's now 2018, and we finally have cheap ways to do something around it...

Indeed, since the 2d context API now has a filter property, and that this filter property can accept SVGFilters, we can build an SVGFilter that will keep only fully opaque pixels from our drawings, and thus eliminate the default anti-aliasing.

So it won't deactivate antialiasing per se, but provides a cheap way both in term of implementation and of performances to remove all semi-transparent pixels while drawing.

I am not really a specialist of SVGFilters, so there might be a better way of doing it, but for the example, I'll use a <feComponentTransfer> node to grab only fully opaque pixels.

var ctx = canvas.getContext('2d');
ctx.fillStyle = '#ABEDBE';
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = 'black';
ctx.font = '14px sans-serif';
ctx.textAlign = 'center';

// first without filter
ctx.fillText('no filter', 60, 20);
drawArc();
drawTriangle();
// then with filter
ctx.setTransform(1, 0, 0, 1, 120, 0);
ctx.filter = 'url(#remove-alpha)';
// and do the same ops
ctx.fillText('no alpha', 60, 20);
drawArc();
drawTriangle();

// to remove the filter
ctx.filter = 'none';


function drawArc() {
  ctx.beginPath();
  ctx.arc(60, 80, 50, 0, Math.PI * 2);
  ctx.stroke();
}

function drawTriangle() {
  ctx.beginPath();
  ctx.moveTo(60, 150);
  ctx.lineTo(110, 230);
  ctx.lineTo(10, 230);
  ctx.closePath();
  ctx.stroke();
}
// unrelated
// simply to show a zoomed-in version
var zCtx = zoomed.getContext('2d');
zCtx.imageSmoothingEnabled = false;
canvas.onmousemove = function drawToZoommed(e) {
  var x = e.pageX - this.offsetLeft,
    y = e.pageY - this.offsetTop,
    w = this.width,
    h = this.height;
    
  zCtx.clearRect(0,0,w,h);
  zCtx.drawImage(this, x-w/6,y-h/6,w, h, 0,0,w*3, h*3);
}
<svg width="0" height="0" style="position:absolute;z-index:-1;">
  <defs>
    <filter id="remove-alpha" x="0" y="0" width="100%" height="100%">
      <feComponentTransfer>
        <feFuncA type="discrete" tableValues="0 1"></feFuncA>
      </feComponentTransfer>
      </filter>
  </defs>
</svg>

<canvas id="canvas" width="250" height="250" ></canvas>
<canvas id="zoomed" width="250" height="250" ></canvas>

And for the ones that don't like to append an <svg> element in their DOM, you can also save it as an external svg file and set the filter property to path/to/svg_file.svg#remove-alpha.