How to draw various figures with canvas

The standard of HTML5 has been out for a long time, but it seems that the canvas inside is not used in many places now. A very important reason is that the standard of canvas has not been completely determined, which is not suitable for large-scale use in production environment. But the advantages of canvas are also obvious. For example, when drawing a chart with a large number of elements, SVG is often overwhelmed by performance problems. For example, I have seen a lottery session of a technology sharing meeting. Although the effect is dazzling, because every avatar is DOM, the animation controlled by CSS3 leads to low performance. In addition, with the improvement of hardware performance, video shooting, image processing and other functions can be gradually realized on the web page. Most websites use Flash, but the performance of Flash on Mac computers is not high, and some extra knowledge is needed. Canvas is drawn directly by JavaScript, which is friendly to Mac and can be regarded as the successor of Flash.

Use canvas

Having said that, what is a canvas?

Canvas means "Canvas" in English, but the canvas mentioned here is a new element in HTML5, on which developers can draw a series of graphics. Canvas is simply written in HTML files:

& ltcanvas id = " canvas " width = " width " height = " height " > & lt; /canvas & gt;

Among them, the id attribute can be used by all HTML elements, and the canvas has only the last two attributes (controlling the width and height respectively), and nothing else. As for compatibility, CanIUse said that 90% of the browsers currently used by users support basic functions, so they can be used with confidence in most cases.

Be careful to use the width and height attributes of the canvas, and don't use CSS control, because CSS control will cause the canvas to deform. You can try to compare it with PhptpShop, the latter is to change the "picture size" and the former is to change the "canvas size" correctly. For example, the following picture shows the horizontal splicing of three pictures: the leftmost black box is the original picture with the size of 50px * 50px; When the size of the middle image is changed to 100px * 100px, the image becomes blurred, but the coordinate range of the image itself is not enlarged. On the far right is the correct canvas of 100px * 100px.

Most of the drawing methods of canvas are similar to those of canvas.

We get this element first:

var canvas = document . getelementbyid(' canvas ');

Then get an entry that can call all Canvas API through a method:

var CTX = canvas . get context(' 2d ');

Will you be excited to think of 3d when you see 2d? There is no 3d writing method, but if you want to open the door to the 3D world, you can write canvas.getContext('webgl'). However, WebGL is a set of standards based on OpenGL ES 2.0, which is completely different from this paper and will not be discussed here.

Basic concepts in canvas

coordinate

Different from the Cartesian coordinate system common in mathematics, the coordinate system of canvas is a common coordinate system in computers, which looks like this:

The upper left corner of the canvas is (0,0), which increases to the right with X and decreases with Y, and both X and Y are integers (even if they are not integers in the calculation process, they will be regarded as integers when drawing), and the unit is pixels.

draft

Take everyone to nostalgia. I don't know how many students played logo language when they were young. Inside, you can control a little turtle to walk, draw, write and put pen to paper on a board. The same is true of canvas. You need to control the movement and drawing of the brush. However, Canvas is more advanced. You can draw directly with some functions without controlling the position of the brush.

Basic graphics in canvas

Many interesting things can be done through the ctx variables defined above. Let's look at how to draw some basic graphics first.

line

We specify that the brush move to a certain point, and then tell the brush to draw from the current point to another point. We can make the brush move and draw many times and finally output it to the screen. Examples are as follows:

ctx.moveTo( 10, 10);

ctx.lineTo( 150,50);

ctx.lineTo( 10,50);

ctx.moveTo( 10,20);

ctx.lineTo(40,70);

CTX . stroke();

In the above code, lineTo is a function for generating lines. After execution, the brush moves to the end of the line. It should be noted that at this time, lines are not displayed on the screen, but only when you call stroke. This design makes sense because it takes a lot of resources to output content to the screen. We can save enough lines first, and finally draw a big one with strokes.

path

Drawing the path is very simple. First tell ctx "I'm going to start drawing the path", and then draw the path in various ways (such as lineTo). If you need to draw a closed path, finally tell ctx: "I'm done, you can close it." Of course, don't forget to use stroke to output to the screen.

A simple example:

CTX . begin path();

ctx.moveTo( 10, 10);

ctx.lineTo( 150,50);

ctx.lineTo( 10,50);

CTX . close path();

CTX . stroke();

What if I don't just draw the path line, but want to fill the whole path? You can change the stroke in the last line to fill, so that the content in the closed path is filled with color, just like using a paint bucket in a drawing:

CTX . fill();

Arc/circle

There are many function parameters for drawing an arc:

Ctx.arc (center x coordinate, center y coordinate, radius, starting angle, ending angle, whether counterclockwise);

Note that in the coordinate system of Canvas, one side of the corner is a horizontal straight line with the center of the circle as the center to the right. The angle is in radians. For example, as shown in the following figure, the center of the circle, the starting angle (acute angle shown in the figure) and the ending angle (obtuse angle shown in the figure) are determined, and the direction is counterclockwise, so there is such an arc. If the direction is clockwise, it will be a very, very large arc to complement it. ...

So if you turn 2π, the arc becomes a circle, so you can also draw a circle by drawing an arc:

CTX . begin path();

Ctx.arc (center x coordinate, center y coordinate, radius, 0, mathematics. PI * 2, true);

CTX . close path();

The last parameter can be filled in at will (of course, it can also be left blank), because after 2π turns, it is a circle, whether clockwise or counterclockwise.

rectangle

If you just want to draw a horizontal and vertical rectangle, you can use the following two methods:

//Only strokes

Ctx.strokeRect (upper left corner X coordinate, upper left corner Y coordinate, width, height);

//Fill only

Ctx.fillRect (upper left corner X coordinate, upper left corner Y coordinate, width, height);

Line Style/Fill Style

Previously, all the drawings were black, but Canvas definitely has more than one color (otherwise, the standard setters will be badly sprayed). In fact, Canvas can set line style and fillStyle respectively, and use strokeStyle and fill style respectively. There are three possible values: solid color, gradient and image. Since the usage of line style is the same as that of filling style, let's take filling style as an example. If you want to set the line style, just change all the fillStyle to strokeStyle, and the parameters in it will remain unchanged.

/* Solid color fill */

//Ordinary color

CTX . fill style = ' # 0000 ff ';

//transparent color

ctx.fillStyle = 'rgba(64,0, 127,0.5)';

/* Gradient Fill */

//Set the size of the gradient (parameters are x and y at the starting point and x and y at the ending point respectively).

var gradient = CTX . createlineargradient(0,0, 170,0);

//Set the transition color. The first parameter is the position of the gradient, and the second parameter is the color.

gradient.addColorStop(0,' magenta ');

Gradient.addColorStop(0.5,' blue');

Gradient.addcolorstop (1.0,' red');

//Set the fill style

ctx.fillStyle = gradient

/* Picture Fill */

//Create a picture

Var image = new image;

image . src = '/path/to/image . png ';

//Create a picture brush stroke, and you can specify the tiling method of the picture, here is horizontal tiling.

var pattern = CTX . create pattern(image,' repeat-x ');

//Set the stroke fill

ctx.fillStyle = pattern

As for the gradient, in addition to the linear gradient mentioned in the code, there is also createRadialGradient, which is a radial gradient.

After setting the fill style, you can fill it with fill! If the line style is set, you can use stroke to stroke.

Of course, for line styles, there is an additional method called lineWidth, which can be used to control the width of lines.

trait

If you want to draw text on canvas, you need to know the font and font size first:

ctx.font = ' 30px Verdana

Then, you can stroke or fill the font by strokeText or fillText.

ctx.strokeText("Hello Coding!" , 23, 33);

ctx.fillText("Hello Coding!" , 23, 66);

draw

There are three ways to draw on canvas:

//Specify the drawing location

ctx.drawImage(image,x,y);

//Specify the drawing position and image width and height.

Ctx.drawImage (image, x, y, width, height);

//Specify the cropping area, drawing position and image width and height.

ctx.drawImage(image,sx,sy,swidth,she height,x,y,width,height);

The meanings of these parameters are as follows:

Image: The image, canvas or video to use.

Sx: optional, the x coordinate for starting cutting.

Sy: optional, the y coordinate of starting cutting.

Swidth: Optional, crop the width of the image.

The height: optional, crop the height of the image.

X: the x coordinate of the image placed on the canvas.

Y: Y coordinates of the image placed on the canvas.

Width: optional, the width of the image to be used.

Height: Optional, the height of the image to be used.

Canvas settings

Careful students may find that some attributes are directly set to ctx variables, such as ctx.lineWidth. As long as they are set, the lines drawn later are all of this width.

In fact, there are many settings for canvas, for example, we can move canvas directly, rotate canvas, set global drawing transparency and so on. These settings can also be saved and restored at any time.

One thing to note is that everything that has been painted on the canvas is dead, and no matter what settings are made later, it will not change. This is very similar to the drawing program under Windows.

Before it's too late, just code:

//Moving the canvas is actually moving the coordinate system.

Ctx.translate (the amount moved to the right, the amount moved down);

//Rotate the canvas with the rotation center as the origin of the coordinate system.

Ctx.rotate (clockwise rotation angle);

//Scale the canvas around the origin of the coordinate system.

Ctx.scale (horizontal amplification, vertical amplification);

//Set the transparency of the drawing. If the transparency is set by attributes such as fillStyle, it will be superimposed.

Ctx.globalAlpha (decimal from zero to one);

//Set global combination operation

CTX . globalcompositeoperation = ' lighter ';

//Save the current settings.

CTX . save();

//Restore the last saved settings.

CTX . restore();

Moving, rotating and scaling are actually controlling the coordinate system of the drawing. If you always have a calibrated coordinate system in your mind when calling these three methods, the effect will be very good.

In fact, the coordinate transformation of canvas follows the knowledge of computer graphics: transformation matrix. Simply put, a coordinate can be regarded as a matrix, and the transformation of coordinates can be realized by multiplying the matrix corresponding to the coordinate by the transformation matrix. In order to improve the calculation efficiency, we can first calculate the transformation matrix after several transformations are merged, and then directly transform the current coordinate system through the transform function, or reset the coordinate system to the initial state through the setTransform function before the transformation. As for the content of the transformation matrix, it is a bit super-class for this paper.

The global combination operation is a bit like the "blending option" in PhotoShop, and the specific implementation mode has not been completely determined. At present, common browsers have unified implementation methods: source-over, source-top, destination-over, destination-out, lighter and xor. Specific behaviors can be found in Mozilla's official documents, but other browsers do not guarantee that all behaviors conform to Mozilla's standards because the standards have not been fully determined. Generally speaking, source-over and lighter are two common standards, which are indisputable in the browser world.

As for saving and restoring settings, it's a bit fun. First of all, you should know something called "stack".

Stack is a one-dimensional array and can only be operated in one direction. The stack is empty at the beginning, so we can push elements into the array from this direction, and only the last element (the top element of the stack) pops up from this direction, with no additional operation. Of course, the number of POPs can't be more than the number of push, because when the pop reaches the bottom of the stack, there are no elements in the stack, so it is meaningless to pop again at this time. Stack has many uses, such as bracket matching, expression evaluation, depth-first search, and even function calls in most languages use Stack.

Every time we call the save function, we actually push the current global settings onto a special stack. Every time we call the restore function, we pop up the last saved content and use it to overwrite the current global settings, so that the top of the stack is the last saved content. Saving and restoring are very useful in some cases, for example, I need to draw a crooked diagram and then continue to draw a straight diagram, so that I can call save first, then call rotate, and then resume after drawing the diagram and continue to draw other diagrams.

In fact, there are many methods for Canvas, such as toDataURL directly converting the current canvas content into hexadecimal data -url, getImageData directly converting images into RGBA arrays for image processing algorithms, putImageData converting RGBA arrays into images and displaying them on canvas, and so on. If JavaScript is updated regularly (it is better to use requestAnimationFrame instead of setInterval), it can produce animation effect. There are also many libraries of Canvas on the Internet, which can facilitate programmers to write their own special effects or functions based on Canvas. I want to say a word here: the ability of canvas is as strong as the size of everyone's brain hole ~