The foundation of canvas

Time:2021-3-27

After watching SVG essentials for half a month, and then watching HTML5 + canvas basic course, I feel that most of the content is relatively easy. Many methods of canvas and element attributes of SVG have very similar functions.

I’ve been busy with the project a while ago, and it took less than a week to watch the basic course of canvas, so I didn’t have time to record. Recently, I was a little bit idle. I found another book “HTML5 canvas core technology graphics, animation and game development”. I feel that it is more detailed than the previous one. The two books are combined with further research, and by the way, they are sorted out and written.

Similarities and differences between canvas and SVG

These two kinds of drawing techniques are completely different in nature.
The essence of canvas is the processing of pixels. When drawing a straight line with canvas, canvas itself does not know that it is a straight line, only knows that the color of a group of pixels at a specific position has been changed. Canvas can know the color information of every pixel (RGBA). It is very good at processing pictures and even videos. In web games, there are many applications of canvas, and SVG is very disappointed about this.
The essence of SVG is the processing of vector. SVG knows the specific information of all elements in its canvas, such as the coordinates of the start and end of a line, thickness, color and so on. It can easily control the changes of all elements in its canvas. Because of the nature of the vector, SVG can be drawn to achieve lossless zoom in and out of the map, not against this canvas.

Even so, the function coincidence degree of the two kinds of drawing technology is still very high. As far as I know, the performance of the two technologies in data visualization is basically the same. One can be realized, and the other can also be realized. D3. JS based on SVG, hcharts and ecarts based on canvas are very beautiful in data visualization. Both of them have their own way to realize animation. Svg uses clip, mask, and filter to process images in a very rich way, which is not inferior to canvas at all.

So the choice of which technology to use should be better differentiated. SVG is used for drawing scaling and canvas is used for complex graphics processing. The rest depends on personal preference. No matter which one you choose, the JS foundation must be excellent (SVG needs to use js to realize the interaction with graphics, while all the drawing work of canvas is written in JS)

Viewbox in canvas

Svg has an important concept of viewbox (seeSvg’s viewbox)It’s also in canvas.
When drawing a canvas, you need to specify the width and height of the canvas element, both of which have no unit.

<canvas id="canvas" width="300" height="150"></canvas>

By default, a canvas area of 300px * 150px will be drawn.
Any drawing operation in the canvas area, when it comes to length and coordinate value, has no unit.

var context = document.getElementById("canvas").getContext("2d");
context.fillRect(40, 20, 200, 100);

At this time, a rectangle with the upper left corner coordinates of (40px, 20px) and the length and width of 200px * 100px is drawn.

But if you add a style to this < canvas > element: style=“ width:600px; height:300px “, you will find that the size of the canvas will be 600px * 300px, and the rectangle in the canvas will be enlarged year on year.
Therefore, the width and height attributes defined on the < canvas > element are the width and height of its viewbox.

In addition, when the width and height of canvas are not equal to the width and height of its style, if you need to obtain the coordinate position of the mouse in the canvas coordinate system when the mouse click event is triggered, you can do as follows:

function windowToCanvas(canvas, x, y) {
    var box = canvas.getBoundingClientRect();
    return { 
        x: (x - box.left) * (canvas.width  / box.width),
        y: (y - box.top)  * (canvas.height / box.height)
    };
}

canvas.addEventListener("click", function(e){
    var canvasPoint = windowToCanvas(canvas, e.clientX, e.clientY),
        x = canvasPoint.x,
        y = canvasPoint.y;
})

context

The < canvas > element itself has three methods:

Method name describe
getContext() Returns the drawing environment object associated with the canvas element. The most commonly used is “2D”, which represents the 2D drawing environment.
toDataUrl(type, quality) Returns a data address URL, which can be set to the SRC attribute value of img, and the type is the image type (image / JPG, image / PNG, etc.); the quality must be a double value between 0 and 1, indicating the image compression quality.
toBlob(callback, type, quality…) Create a blob to represent the canvas element image file. Callback is a callback function whose parameter is a reference to blob.

from canvas.getContext The object returned by (“2D”) is the instance context of the 2D drawing environment object canvasrenderingcontext2d of the canvas.
All drawing operations are realized by setting the properties of context and calling the methods provided by context.
The drawing process of canvas is simple, which is a bit similar to watercolor painting: choose the thickness of the pen and the pigment, and then draw a few strokes, then change the pen to dip some other pigment, and then draw a few strokes. Setting the properties of context is to select the thickness and pigment of the pen, and the method of calling context is to draw a few strokes.

Context property

Context contains the following attributes:

Property name describe
canvas Points to the canvas object to which it belongs. It is often used to obtain the width and height of canvas context.canvas.width , context.canvas.height
fillStyle Specifies the fill color, gradient, or pattern for subsequent graphics
strokeStyle Specifies the color, gradient, or pattern to stroke the path later
font Specifies the font of the text drawn by subsequent filltext() or stroketext() methods
textAlign Specifies the horizontal alignment of text drawn by subsequent filltext() or stroketext() methods
textBaseLine Specifies the vertical alignment of text drawn by subsequent filltext() or stroketext() methods
globalAlpha Specifies the transparency of subsequent graphics in the range of [0,1]
globalCompositeOperation Specifies how to overlay subsequent graphics with existing graphics on the canvas
lineCap Specifies the rendering method (but, round, square) of the end points of subsequent segments. The default is but
lineWidth Specifies the width of subsequent segments, which is 1 by default
lineJoin Specifies the rendering method (level, round, miter) of the connection points between subsequent segments. The default is miter
miterLimit Specifies the maximum distance of the miter connection point between subsequent segments
shadowBlur Specifies the shadow diffusion range of subsequent graphics. The larger the value, the larger the diffusion range. The default value is 0 (this value is not the shadow length, but represents the parameter value in the Gaussian blur equation)
shadowColor Specifies the color of the shadow for subsequent graphics. The translucent shadow color displays the elements below it
shadowOffsetX Specifies the horizontal offset of the shadow for subsequent graphics
shadowOffsetY Specifies the vertical offset of the shadow for subsequent graphics

(if you are familiar with SVG, you should be able to find a lot in common)

context.save () and context.restore ()

Now consider such a situation: draw a few strokes with color a that has been adjusted for a long time, and then draw a few strokes with color B. when you need to change back to color a, the best way is to keep the color adjusted each time in the palette, instead of having to re color every time.

The save () and restore () methods of context can achieve similar functions.
After setting some context properties, execute context.save () you can save the current context property state to a stack. In this way, no matter what the context property is changed to later, you only need to call it once context.restore (), the properties of context can be restored to the previous execution context.save (), which will be out of the stack.
Since the attribute state is saved to a stack, the save() and restore() methods can be executed many times. When calling save() and restore(), the attribute state of context will be saved and restored according to the principle of first in, last out.

Of course, this mode is not as convenient as using the palette, and it can’t switch to a certain attribute state at will, so the idea of using it is not the same as using the palette. For example, in state a, execute save (), and then change to state B. at this time, if you want to use restore () to switch back to state a, state B can only be discarded.