Common canvas optimization solutions — blur problem, rotation effect, off-screen, custom image size

Practice Demo — “Canvas off screen, Rotating effect Practice — Rotating Snowflake”

Canvas display blur problem – Canvas size is set to twice the display size

Question why

As you can see from the Canvas API, in order to obtain accurate lines, you must have an understanding of how lines are drawn.

First of all, it should be clear that the positioning of a canvas line is to determine the position of the middle line of the line, and then extend to both sides according to the width of the line. If the extended line does not fill up to 1px, the insufficient part will be filled with half of the actual stroke color. So what we actually see in the end is that the 1px line gets wider and blurry, as shown on the left:

The solution

According to the cause of the problem we know: as long as the part extending outward from the middle of the line is full 1px, the line will not be wide and blurred.

The easiest way to do this is to move the line position by 0.5px as required, but this is a palliative and can only be used to verify that the method is correct.

We can also set the canvas size to be twice the display size, which is equivalent to using two pixels in the drawing to fill one pixel in the actual display. In this way, the problem of canvas display blur can be solved well.



canvas.setAttribute('width', x * 2);
canvas.setAttribute('height', y * 2);
canvas.style.width = x + 'px';
canvas.style.height = y + 'px';Copy the code

In this way, remember to vary the layout sizes accordingly.

Off-screen canvas

Define off-screen canvas, set canvas size and draw canvas picture on off-screen canvas:



var offScreenCanvas = document.createElement('offScreenCanvas');
var offScreenCtx = offScreenCanvas.getContext('2d');Copy the code

Then draw the drawn off-screen canvas to the actual display canvas:



ctx.drawImage(offScreenCanvas, 0.0, offScreenCanvas.width, offScreenCanvas.height.0.0.canvas.width.canvas.height);Copy the code

benefits

First, it can draw a large picture of standard size without being limited by HTML tag and actual display size, and then adapt to the actual display canvas. Second, the caching effect of off-screen canvas can greatly improve the performance of canvas (of course, such rough code as above cannot reflect this effect).

insufficient

Off-screen canvas must be drawn to the actual display canvas after completion, which leads to some delayed elements (such as pictures, customized fonts, etc.) that are inconvenient to use in this way. I haven’t found a good solution to this problem so far.

Picture size problem

At the beginning of drawing, there was a very difficult problem: how many pictures and sets of pictures should be matched with different screen sizes when drawing PNG pictures on canvas. Later, after the above “off-screen canvas” problem is solved, this problem is solved: the drawImage function can set the size of the image, not the image itself.

Once this problem is solved, all you need is a set of images that can be scaled to fit on the screen and with the display.

Canvas rotation effect – Changes the canvas coordinate system

There are two very useful things in canvas: rotation and save state.

In order to draw the radius of different angles of the circle as an example, under normal circumstances we need to calculate the endpoint coordinates of the line P1{x1,y1}, P2{x2,y2} according to the radius of the circle, the Angle of the line and the position of the center of the circle, and then draw a line P1 to P2, the calculation in the code is not small. But in canvas we have a better solution:

1. Position stroke to center {x,y}



ctx.translate(x.y)Copy the code

2. Rotate the canvas Angle circle according to the Angle of the line (Angle =1 indicates a clockwise rotation)



ctx.rotate(Math.PI* 2 *angle);Copy the code

3. Draw a line from {0,0} to {r,0}



ctx.beginPath(a);ctx.lineTo(0, 0);
ctx.lineTo(r, 0);
ctx.stroke(a);Copy the code

Canvas rotation drawing step interpretation:

The stroke positioning is equivalent to fixing the origin position of the canvas, while the rotation of the canvas takes the origin as the center of the circle and rotates the X/Y coordinate system clockwise. The effect of rotation is to overlap the positive half axis of X with the line to be drawn, which is naturally equivalent to directly drawing a line from {0,0} to {r,0}.

Also note:

Before modifying the canvas coordinate system (fixing the origin, rotating the canvas), be sure to save the state, after drawing the line must reload the state! Otherwise you can easily get killed by your own modified frame.