introduce
SVG builds XML trees to draw graphics, while Canvas draws graphics by calling related methods. Difference: SVG draws graphics by removing or changing the DOM method while using Canvas requires the image to be erased. The drawing API is defined in the drawing context. It’s not defined in the canvas. To get a context object, you need to call the canvas’s getContext method to get the context of the painting.
The canvas element and context belong to two different objects, where the canvas element is the Canvas canvas and the context object is the context required for drawing.
For 3D graphics, that is, webGL encapsulates the basic OPENGL. When webGL is called, its browser will call the OPengL-related API
Draw the circle
<! DOCTYPE html> <html lang="zh_CN" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8"> <title> title </title> </head> <body> <div> The first garden </br> <canvas ID ="square" width="10" height="100"> </canvas> </div> <div> The second garden <canvas id="circle" width="10" height="10">
</canvas>
</div>
<script src="./js/index.js" charset="UTF-8"></script>
</body>
</html>
Copy the code
// Get the canvas elementlet canvas = document.getElementById("square"); // Get the context for drawing a 2D elementlet context = canvas.getContext("2d"); // Set the fill color to red context.fillstyle ="#f00"; // fill a square context.fillrect (10,0,10,10);Copy the code
Draw line segments and fill polygons
// Get the canvas elementlet canvas = document.getElementById("square"); // Get the context for drawing a 2D elementlet context = canvas.getContext("2d"); // Start a path context.beginPath(); // Define a new subpath from 100,100 context.moveto (100,100); // Draw a line from 100 100 to 200 200 context.lineTo(200,200); // Draw a line segment context.lineTo(100,200); // Draw a path from 100 200 to 100 100 context.lineTo(100,100); // Draw edge context.stroke(); // Fill context.fill();Copy the code
Draw polygons
Taking the pentagon as an example,
var canvas = document.getElementById("square");
var context = canvas.getContext("2d"); // Draw a cabinet N deformation centered on 100,100 with radius 20. Each point is evenly distributed on the rounded corner. Start defining a sliver path context.moveto (100 + 20 * math.sin (0), 100-20 * math.cos (0)); Var delta = 2 * math.pi /5; var delta = 2 * math.pi /5; console.log(delta); Var Angle = 0;for(var i = 1; i < 5; I++){// Angle += delta; // Draw context.lineto (100 + 20* math.sin (Angle), 100-20 * math.cos (Angle)) by rotating the next vertex; } // Connect the last vertex to the starting point context.closepath (); // Start a new path from scratch context.stroke(); context.fill();Copy the code
Similarly, let’s draw a circle
var canvas = document.getElementById("square");
var context = canvas.getContext("2d"); // Draw a cabinet N deformation centered on 100,100 with radius 20. Each point is evenly distributed on the rounded corner. Start defining a sliver path context.moveto (100 + 20 * math.sin (0), 100-20 * math.cos (0)); Var delta = 2 * math.pi /500000; var delta = 2 * math.pi /500000; console.log(delta); Var Angle = 0;for(var i = 1; i < 500000; I++){// Angle += delta; // Draw context.lineto (100 + 20* math.sin (Angle), 100-20 * math.cos (Angle)) by rotating the next vertex; } // Connect the last vertex to the starting point context.closepath (); // Start a new path from scratch context.stroke(); context.fill();Copy the code
Nonzero winding principle
To test whether a point p inside the path, the use of zero around several principles, namely, an infinite extension from p along an arbitrary direction, or all the way to the ray path lie outside the area of a certain point, starting from 0 initialize a counter, now to enumerated through the ray path, when a path through the ray clockwise, counter plus 1, Counterclockwise minus 1. Finally, after enumerating all paths, if the timer is not 0, then P is considered to be in the path, and conversely, the counter is 0 and P is out of the path.
Js determines which is in the path and which is out of the path according to the non-zero winding principle for filling.
Graphic attributes
You can set the properties of graphics by setting fillStyle and other properties of the canvas context. For example, you can set the color, gradient, pattern and other styles when filling.
For canvas, the same context object will be returned every time it gets the context object, that is, the context object is singleton.
You can also use the save method to push the current state into the saved stack, and call the restore method to restore the state, i.e. the stack.
Canvas dimension coordinates
The default coordinate system of the canvas is the origin of the coordinates in the upper left corner (0,0), the value on the right side is large, and the value on the lower side is large. The coordinates are specified by floating point numbers, but they are not automatically converted to integers.
The canvas size cannot be changed arbitrarily, and any operation on any property will empty the entire canvas.
Coordinate transformation
The coordinates of each point are mapped to a CSS pixel, which is mapped to one or more device pixels. For a particular operation on the canvas, properties use the default coordinate system. The canvas and the current transformation matrix. The canvas also has the current transformation matrix, which is part of the state of the graph. The matrix defines the coordinate system for the current canvas. The canvas operation maps the point to the current coordinate system.
Coordinate transformation
When the c. ranslate(dx,dy) method is called, the following transformation is performed
Translate moves the coordinates up and down
x' = x + dy;
y' = y + dy;
Copy the code
Scale To scale, perform the following transformation
x' = sx * x;
y' = sy * y;
Copy the code
I rotate, and I do the following transformation
x' = x * cos(a) - y * sin(a);
y' = y * cos(a) - x * sin(a);
Copy the code
If you want to transform and then scale, you have to do the following transformation by mapping the existing frame to the points x prime and y prime in the frame and then converting to x prime and y prime.
x' ' = sx*x + dx;
y' ' = sy*y + dy;
Copy the code
If the transformation is reversed, perform the following transformation
x' ' = sx*(x + dx);
y' ' = sy*(y + dy);
Copy the code
This transformation is called an affine transformation, and it modifies the distance between points and the Angle between line segments. For parallel lines, affine transformations will also remain parallel. Affine transformations are described with six parameters as follows
x' = ax + cy + e;
y' = bx + dy + f;
Copy the code
Affine transformation is implemented by passing in parameters
For coordinate transformation, unless refresh, otherwise, has been drawn graph, will not disappear, all transformation, can not have been drawn graph change. Chestnut is as follows
var canvas = document.getElementById("square");
var context = canvas.getContext("2d"); BeginPath (); // Start a path context.beginPath(); // Start drawing subpath context.moveto (100,100); // Start drawing subpath context.moveto (100,100); // Continue drawing context.lineto (200,200); // Continue drawing context.lineto (200,200); // Draw edges context.stroke(); The context. Translate (200200); // Start a path context.beginPath(); // Start drawing subpath context.moveto (100,100); // Start drawing subpath context.moveto (100,100); // Continue drawing context.lineto (200,200); // Continue drawing context.lineto (200,200); // Draw edges context.stroke();Copy the code
A graph that has already been drawn does not change; the graph that has already been drawn changes
Koch snowflake
var canvas = document.getElementById("square");
var context = canvas.getContext("2d"); // Implement Koch snowflake through coordinate transformation // current state is pushedfunctionLeg (n) {// Save the state context.save(); / / the recursionif(n == 0){
context.lineTo(50, 0);
}else{// Define context.scale(1/2,1/2); Context. rotate(60 * (math.pi / 180)); leg(n - 1); context.rotate(-120 * (Math.PI / 180)); leg(n - 1); } // Coordinate restore transform context.restore(); // Restore the next coordinate to 0,0 context.translate(50, 0); } context.save(); context.moveTo(50, 50); // Draw the first leg(1); context.stroke();Copy the code
Draw filling curve
Draw some common graphics
var canvas = document.getElementById("square");
var context = canvas.getContext("2d"); // Tool function, Angle radiansfunction rads(x) {
returnMath.PI * x / 180; } // Draw the garden context.beginPath(); The context. The arc (100100, 40, 0, rads (360).false);
context.stroke();
context.fill();
Copy the code
The same is true for plotting bezier curves.
Colors, transparency, gradients, patterns
To draw a gradient, use the createLinearGradient to get a context for the gradient, and process that context. The color is then set to the context of the gradient, the fillStyle property.
Line drawing
caps
For line segments, there are three capping methods, namely butt, square and round. After drawing the graph, the parameters are sharp, rounded and flat. LineCap properties
The text
Similar to CSS, baseline issues.
tailoring
The current path will also be clipped in, and everything outside the path will not be displayed.
shadow
Set the shadow property
The picture
The Canvas API supports bitmap images as well as canvas exports as images.
// Create an img elementlet img = document.createElement("img"); // Set the SRC attribute img.src = canvas.todataURL (); / / appended to the document behind the document. The body. The appendChild (img);Copy the code
synthetic
Some apis are not described
Pixel operations
Call getImageDate to return the ImageDate object. CreateImageDate () can be used to create a pixel container for dynamic blurring. It retrieves the pixel’s ImageDate object and then retrieves its Data property, which is an array. Is a dimensional array. Each of the four elements represents the red component, the green component, the blue component, and the transparency component. (Alpha component) its pigmentation is 0-1, that is, the array stored in the array element is the pigmentation value. Every four elements are iterated over. It then assigns 1/ n of its pigment value plus m/n of the previous color block to the new color block, as follows
// row is the number of rowsfor(var row = 0; row < height; Row++){// get the offset of the second element in each row, where width is the pigment block in the row. var i = row * width * 4; // Every 4 pigment values are processedfor(var col = 1; col < width; Col++, I + = 4) {/ / to red component processing data [I] = (data [I] + data [4] I - * m)/n. Data [I + 1] = (data[I + 1] + data[I + 1-4] * m)/n; Data [I + 2] = (data[I + 2] + data[I + 2-4] * m)/n; Data [I + 3] = (data[I + 3] + data[I + 3-4] * m)/n; }}Copy the code
And then copy the pigment block back. Each pixel takes up one byte, one four bytes.
Hit testing
The isPointInPath method is used to determine whether a point is in the current path. Match detection.
Hit detection can be interconverted with mouse events
But the coordinates need to be transformed.