Nikhil Kinkar
Nikhil Kinkar

Reputation: 781

What is the difference between html5 canvas scale vs increasing the canvas dimensions for zooming?

As mentioned in MDN web docs for canvas scale:

By default, one unit on the canvas is exactly one pixel. If we apply, for instance, a scaling factor of 0.5, the resulting unit would become 0.5 pixels and so shapes would be drawn at half size. In a similar way setting the scaling factor to 2.0 would increase the unit size and one unit now becomes two pixels. This results in shapes being drawn twice as large.

So does it work the same when we increase the width/height of the canvas for zooming purposes, or does it just stretch the image, does it affect the image quality?

Upvotes: 1

Views: 953

Answers (3)

traktor
traktor

Reputation: 19366

If you directly change the width or height attrribute of a canvas HTML element, you change the size of the canvas pixel buffer and wipe out any previous content of the canvas. This is not an effective means of scaling content :-)

CSS scaling is invoked by changing the intrinsic width or height of a canvas in CSS. Increasing the dimensions of the canvas significantly in CSS may produce blurring in similar fashion to zooming an image in an image viewer beyond the information content of the image.

If you change canvas scaling (by means of its context object) prior to drawing shapes and lines onto a canvas, the drawing routine will limit blurring to single pixels on the edges of content drawn. Typically this is similar to using anti-aliasing to render font characters and may not be undesirable.

The 2018-09 editors' draft of CSS Images Module Level 3 proposes an image-rendering property to control how CSS interpolates images when zooming. It lacks support in some major browsers as the time of the draft.

See also this related question on using nearest neighbor interpolation to zoom canvas objects.

Upvotes: 0

Kaiido
Kaiido

Reputation: 137084

The canvas context drawing methods asks for us to provide some coordinates and lengths in their methods. For instance, the x, y, width, height of the fillRect(x y, width, height) method.

All these values are unit-less, so let's name it magical-unit.

Since the canvas is a raster image, it has been decided that at first, each magical-unit represents one pixel of this raster image. When we set the canvas width or height, we are just changing the number of pixels that the canvas can hold.

So from this, we can build a nice magical-unit-grid of canvas.width * canvas.height * 1.
In this scenario, when passing (10, 10) as arguments to a method expecting coordinates in magical-units, the pointer will get moved to the pixels at coordinates 10, 10.

Now, there are some methods, like scale(), but also translate(), transform() etc. that will modify our magical-unit-grid.

translate(5, 10) for instance will move our magical-unit-grid by 5 magical-units horizontally and 10 vertically. So now coordinates (10,10) will actually point to the pixels at coordinates 15, 20 (10 + 5, 10 + 10).

And after a call to scale(2, 2), one magical-unit will now be equal to two pixels on the canvas. So, if we pass (10, 10) to the same method as above, our pointer will actually move to the pixels at coordinates 20, 20.

Our previous drawings won't have changed, the quality of our canvas is no-different, the only thing that did change is the value of our magical-unit.

Upvotes: 1

Bas van Dijk
Bas van Dijk

Reputation: 10713

As far as I know, it is exactly as you stated. When changing the dimensions of the canvas the image is stretched and the pixels are interpolated the same way as when you stretch an image.

When scaling inside the canvas, the drawing engine knows for example to draw 2x2 pixels when the scaling is set to 2. Therefore the image remains "sharp".

Upvotes: 1

Related Questions