Canvas scale as in DOM element scale and the scale 2d context method

There is the canvas scale in the sense of how much the canvas element is scaled relative to its actual native size. There is also the scale context method as well when it comes to scaling object within the canvas. In this post I will be writing about all things canvas scale related.

1 - Canvas scale

Canvas scale can refer to a number of things. In this post I will be trying to address just about everything that has to do with scaling and the html 5 canvas element that can be used to draw graphics with javaScript code. In this post I assume that you have at least some background with canvas and javaScript, but are scratching you head when it comes to scaling with canvas.

2 - Scale a canvas with CSS

Lets start with the basics here. When it comes to creating a canvas to begin with there is the actual native pixel size of the canvas, and then there is a scaled size that can be set via CSS values.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html>
<head>
<title>canvas scale</title>
<!-- the values in css will set the scaled size of the canvas-->
<style>
#the-canvas{
width: 640px;
height:480px;
}
</style>
</head>
<body>
<!-- The values here will set the native size of the canvas-->
<canvas id="the-canvas" width="32" height="24"></canvas>
<script>
var canvas = document.getElementById('the-canvas'),
ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = 'green';
ctx.lineWidth = 5;
ctx.strokeRect(11, 7, 10, 10);
</script>
</body>
</html>

So then in this example I am creating a canvas with a native size of only 32 by 24, and then scaling it up to a size of 640 by 480 with css. Everything could be done inline by using the width and height attributes of the canvas element to set the native size, and the style attribute to set the scaled size of the canvas

3 - Set canvas scale with javaScript

It is possible to set the native size as well as the scaled size of the canvas with javaScript rather than with hard coded html and css. This can be done by getting a reference to the canvas element by one way or another and then using the width and height properties of that canvas element reference to set the native size. In addition the style api can be used to set the scale canvas size as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<html>
<head>
<title>canvas scale</title>
</head>
<body>
<canvas id="the-canvas"></canvas>
<script>
var canvas = document.getElementById('the-canvas'),
ctx = canvas.getContext('2d');
// sets the actual native size of the canvas
canvas.width = 320;
canvas.height = 240;
// Scales the canvas
canvas.style.width = '640px';
canvas.style.height = '480px';
var rect = [60,20,200,200];
ctx.strokeStyle = 'green';
ctx.lineWidth = 7;
ctx.strokeRect.apply(ctx, rect);
ctx.strokeStyle='black';
ctx.lineWidth = 1;
ctx.strokeRect.apply(ctx, rect);
</script>
</body>
</html>

So with a reference to a canvas element the width and height attributes will set the actual native size, but if you want to scale the canvas element then that should be done via the style api of the canvas element reference.

4 - The canvas scale 2d context method

There is also the scale method that can be used with via the 2d drawing context. This method is used to transform the until scale of the pixels of a canvas. So what is drawn to the canvas after the method is called will be smaller or bigger depending on the scale set with the canvas scale method, even if the values given to the method that is drawing is the same.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var canvas = document.getElementById('the-canvas'),
ctx = canvas.getContext('2d');
// sets the actual native size of the canvas
canvas.width = 40;
canvas.height = 40;
// Scales the canvas via in-line css
canvas.style.width = '100px';
canvas.style.height = '100px';
ctx.fillStyle='grey';
ctx.fillRect(0,0,canvas.width,canvas.height)
// red rect is 1/4 the size of the canvas
ctx.strokeStyle = 'red';
ctx.strokeRect(0, 0, 20, 20);
// adds a scaling transformation
ctx.scale(.5,.5);
ctx.fillStyle = 'black';
// black rect is 1/16 the size of the canvas
ctx.fillRect(0, 0, 20, 20);
console.log(canvas)

In this example the first rectangle drawn is one fourth the size of the canvas as expected, but the next black rectangle is one sixteenth the size of the canvas because of the unit scale that was set. This method can be used in conjunction with the canvas sav e and restore methods to change the unit scale, and then restore it back.

4.1 - Using ctx.scale to flip things

An interesting thing happens when passing negative values for the unit scale for the canvas scale method, doing so can be used to flip things.

1
2
3
4
5
6
7
8
9
10
var canvas = document.getElementById('the-canvas'),
ctx = canvas.getContext('2d');
canvas.width = 640;
canvas.height= 480;
ctx.scale(1, -1);
ctx.font = '20px serif';
ctx.textBaseline = 'top';
ctx.fillText('foobar', 0, -20);

5 - Canvas scale with another canvas and the drawImage 2d context method

Another thing to be aware of when it comes to scaling things with canvas is that you can use the drawImage 2d context method to draw one canvas to another canvas. The drawImage method can accept up to nine arguments that can be used to set the position and size of a source image in the canvas as well as additional arguments to set the destination position and the scaled size.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var scaledDraw = function(opt){
var fromCanvas = document.createElement('canvas'),
ctx = fromCanvas.getContext('2d');
fromCanvas.width = opt.w;
fromCanvas.height = opt.h;
opt.draw(ctx);
opt.toCanvas.getContext('2d').drawImage(fromCanvas,opt.sx,opt.sy,opt.sw,opt.sh,opt.dx,opt.dy,opt.dw,opt.dh);
};
var canvas = document.getElementById('the-canvas'),
ctx = canvas.getContext('2d');
canvas.width = 320;
canvas.height = 240;
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
scaledDraw({
toCanvas: canvas,
draw: function(ctx){
ctx.fillStyle = 'red';
ctx.fillRect(0,0,40,40);
ctx.fillStyle = 'green';
ctx.fillRect(40,0,40,40);
ctx.fillStyle = 'blue';
ctx.fillRect(0,40,40,40);
},
w: 80, h: 80,
sx:20,sy:20,sw:40,sh:40,
dx:20,dy:20,dw:280,dh:200
});

In this example I made a quick scaledDraw method that creates a new canvas and then draws to it with a given draw method. It then draws to a canvas that I give it via a toCanvas property.