Search code examples
javascriptcsscanvasscaling

Why does 2d canvas not scale without blurring?


I am trying to build a super simple pixel grid (20x20) with a 2d canvas. And I would like to scale it up (*10) using different sizes for the attributes and the CSS.

I thought it should work that way, since the width and height attributes should represent the pixels of the grid as documented. But when I scale it using CSS, the pixels start antialiasing(?) somehow instead of staying simple pixels (rectangles). Setting antialias to false, did not have any effect.

Why is that and is there a way to solve it, without applying the scale to everything else but the CSS? (I could make one pixel 10 pixels wide, but that ruins the simplicity).

const element = document.createElement('canvas');
const canvas = element.getContext("2d", {antialias: false});

const size = 20;
const scale = 10;

element.width = size;
element.height = size;
element.style.width = size * scale + 'px';
element.style.height = size * scale + 'px';

[{x:10, y: 4}, 
 {x:10, y: 6}, 
 {x:10, y: 12}, 
 {x:10, y: 13}]
.forEach(({x, y}) => canvas.fillRect(x, y, 1, 1));

document.body.appendChild(element);


Solution

  • You can use the CSS / Style of image-rendering, and set it to pixelated.

    More details -> https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering

    eg.

    const element = document.createElement('canvas');
    const canvas = element.getContext("2d");
    element.style.imageRendering = 'pixelated';
    
    
    const size = 20;
    const scale = 10;
    
    element.width = size;
    element.height = size;
    element.style.width = size * scale + 'px';
    element.style.height = size * scale + 'px';
    
    [{x:10, y: 4}, 
     {x:10, y: 6}, 
     {x:10, y: 12}, 
     {x:10, y: 13}]
    .forEach(({x, y}) => canvas.fillRect(x, y, 1, 1));
    
    document.body.appendChild(element);