This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!

SVG tag is the application of vector graphics in HTML5;

The Canvas tag is an HTML5 bitmap application.

Cnavas label

The following is the basic structure of a Canvas tag, and all of the following examples are based on this.

<canvas id="c1" width="600" height="500"></canvas>
<script>
    let canvas=document.getElementById("c1");    
    let ctx=canvas.getContext("2d");   

    // Example code...
</script> 
Copy the code

Canvas coordinate system

Canvas completes the positioning and length measurement of graphics based on grid and coordinate space.

As shown, the Canvas element is covered by the grid by default. Typically, a cell in the grid is equivalent to a pixel in the Canvas element. The grid starts at the top left corner (coordinate (0,0)). All the elements are positioned relative to the origin.

Translation, mesh rotation, and scaling based on the origin of coordinates.

The upper-left coordinates of the blue square are X pixels from the left (X-axis) and Y pixels from the top (Y-axis). (the coordinate is (x,y)).

How to draw graphics on Canvas?

Drawing canvas graphic is divided into two parts:

  1. Bones, frames of shapes, also called paths. Use moveTo, lineTo, and so on to specify the point and line coordinates to draw.

  2. Draw, given a color to draw. There are two ways to draw:

    1. stroke
      • 1.1 Stroke style: Stroke colorctx.strokeStyle="red"; Stroke thicknessctx.lineWidth=2;
      • 1.2 Perform drawing, that is, draw linesctx.stroke();
    2. fill
      • 2.1 Fill Colorctx.fillStyle="blue";
      • 2.2 Execution of drawing, that is, to achieve the fillingctx.fill().

As a result, stroke and fill are executed in a different order, resulting in some different display results, as shown in the figure below

Drawing in the Canvas is a state-based drawing, that is, first set the state of a drawing, and then call the specific function to draw.

A picturesque line:

// draw a line from 20,20 to 120,120
ctx.moveTo(20.20);
ctx.lineTo(120.120);

// Call stroke() for the specific drawing
ctx.stroke();
Copy the code

The path to draw

A path, even a subpath, is closed.

Steps to draw a graph using a path:

  1. Create the start point of the path.

BeginPath () Creates a new path, and moveTo(x, y) sets the starting point of the path.

The beginPath() method is explicitly called before the path is drawn

  1. Call the draw method to draw the path

For example, lineTo(x,y) draws a line from the current path to the specified coordinates.

  1. Close the path

After closePath() closes the path, the draw command is redirected to the context of the canvas.

(Often omitted in practice, just make sure to start a new path if necessary. Fill () automatically closes the path.

  1. Once the path is generated, the figure can be rendered by stroke or by filling the path area.
  • stroke()To draw the outline of a figure with lines.
  • fill()Fill the content area of the path to generate a solid graph.

Line Lines and properties

Line line

Draw the line combination into a triangle and set the border and fill

  • triangle
// Straight triangle border style
ctx.beginPath()
ctx.moveTo(10.180);
ctx.lineTo(300.20);
ctx.lineTo(400.220);
ctx.closePath(); // closePath closes the path, forming a triangle. The closure is cancelled to two line segments
ctx.strokeStyle="green";// Line color. Default is black
ctx.stroke(); 
Copy the code

  • Solid triangle
// Fill the triangle
ctx.beginPath();
ctx.moveTo(50.50);
ctx.lineTo(200.50);
ctx.lineTo(200.200);

ctx.fillStyle="red"; // Fill the color
ctx.fill(); // Fill the closed area. If path is not closed, fill() closes the path automatically.
Copy the code

Draw a polygon

Arbitrarily draw a closed polygon

// Multiple lines draw polygons
ctx.beginPath();
ctx.moveTo(20.30);
ctx.lineTo(300.20);
ctx.lineTo(350.200);
ctx.lineTo(280.330);
ctx.lineTo(70.290);
// ctx.closePath(); 
ctx.strokeStyle="red";
ctx.stroke();
Copy the code

Line Attribute

LineCap — Line end style

  • round: A circle is added to the end of the line segment
  • butt(default) The end of the line ends with a square
  • squareAdd a square to the end of the segment (width is the same as the segment and height is half the thickness (width) of the segment)
//    
    ctx.beginPath();
    ctx.moveTo(50.50);
    ctx.lineTo(50.300);
    ctx.lineWidth=20;
    ctx.strokeStyle="red";
    ctx.lineCap="butt";/ / the default
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(100.50);
    ctx.lineTo(100.300);
    ctx.lineWidth = 20;
    ctx.strokeStyle = "red";
    ctx.lineCap="round";
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(150.50);
    ctx.lineTo(150.300);
    ctx.lineWidth = 20;
    ctx.strokeStyle = "red";
    ctx.lineCap = "square";
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(0.49);
    ctx.lineTo(300.49);
    ctx.moveTo(0.301);
    ctx.lineTo(300.301);
    ctx.lineWidth = 0.5;
    ctx.strokeStyle = "blue";
    ctx.stroke();
Copy the code

The pattern at the end of the line

LineJoin – the style where lines meet

Within the same path, set the style of the indirect line and line.

  1. Round draws the shape of the corner by filling in an extra fan with the center of the circle at the end of the connected section. The radius of the fillet is the width of the line segment.

  2. Bevel fills an additional triangular base area at the end of the connected sections, each with its own independent rectangular corners.

  3. The miter(default) forms an additional rhomb region by extending the outer edges of the connecting sections so that they intersect at one point.

// linejoin()
    var lineJoin = ['round'.'bevel'.'miter'];
    ctx.lineWidth = 20;
    ctx.strokeStyle = "red";
 
    for (var i = 0; i < lineJoin.length; i++){
        ctx.lineJoin = lineJoin[i];
        ctx.beginPath();
        ctx.moveTo(50.50 + i * 50);
        ctx.lineTo(100.100 + i * 50);
        ctx.lineTo(150.50 + i * 50);
        ctx.lineTo(200.100 + i * 50);
        ctx.lineTo(250.50 + i * 50);
        ctx.stroke();
    }
Copy the code

Dotted lines — setLineDash() and lineDashOffset

The setLineDash() method and the lineDashOffset property implement the dotted line style.

  • setLineDashThe getline () method takes an array to specify alternations between line segments and gaps;
  • lineDashOffsetC property sets the start offset.
/ / dotted line
ctx.setLineDash([20.5]);  // [Solid line length, gap length]
ctx.lineDashOffset = -0;
ctx.strokeRect(50.50.210.210);
Copy the code

The result is different because of the order of fill and stroke

// Fill followed by stroke and stroke followed by fill
    ctx.beginPath();
    ctx.moveTo(30.40);
    ctx.lineTo(200.30);
    ctx.lineTo(200.200);
    ctx.closePath();
    ctx.fillStyle = "blue";
    ctx.fill();
    ctx.strokeStyle="red";
    ctx.lineWidth=20;
    ctx.stroke();
    
    
    ctx.beginPath();
    ctx.moveTo(230.40);
    ctx.lineTo(400.30);
    ctx.lineTo(400.200);    
    ctx.closePath();
    ctx.strokeStyle="red";
    ctx.lineWidth=20;
    ctx.stroke();
    ctx.fillStyle="blue";
    ctx.fill();
Copy the code

Rectangle – Draws the graph directly

< Canvas > supports only one type of native drawing: rectangles. All other graphs need to generate at least one path.

The fillRect, strokeRect, and clearRect methods related to rectangles have the following effects:

// Draw a rectangle
//ctx.fillStyle="red"; //#f00
ctx.fillStyle = "Rgba (0, 0, 200, 0.3)";
ctx.fillRect(10.10.50.50);// Draw a solid x,y,width,height rectangle
ctx.strokeRect(10.60.50.50);// Draw a rectangle with x,y,width,height
ctx.clearRect(20.20.30.30);// Clear the specified rectangular area completely transparent.
Copy the code

The circular arc

There are two ways to draw an arc: arc() and arcTo()

  • arc(x, y, r, startAngle, endAngle, anticlockwise): The center of the circle is (x, y), and the radius is r, starting from startAngle radians and ending from endAngle radians. Anticlosewise: true — counterclockwise, false — clockwise (default).
  • arcTo(x1, y1, x2, y2, radius): Draw an arc according to the given control points and radius, and finally connect the two control points with a straight line.

Angle and radians

Math. PI = 180 degrees

Angle =(math.pi /180)*degrees

Degrees =(180/ math.pi)* Angle

Arc To draw an arc

  • Arc or fill arc
    let degreeToAngle = function (degree) {
        return Math.PI / 180 * degree;
    }

    / / arc arc
    let width=canvas.width,height=canvas.height;
    / / dot
    let origin={
        x:width/2.y:height/2
    }

    // Arc and arc filling
    ctx.beginPath();
    ctx.arc(origin.x,origin.y,100, degreeToAngle(0),degreeToAngle(70));
    ctx.strokeStyle="blue";
    ctx.lineWidth=4;
    ctx.stroke();
    ctx.fillStyle="red";
    ctx.fill();
Copy the code

  • Fill the fan or circle
    // Fill the fan
    ctx.beginPath();
    ctx.moveTo(origin.x, origin.y); // Start at the center of the circle
    // ctx.arc(origin.x,origin.y,100,degreeToAngle(0),degreeToAngle(110));    
    ctx.arc(origin.x, origin.y, 100, degreeToAngle(0), degreeToAngle(360));    
    ctx.closePath();  // Close the path sector
    ctx.lineWidth=6;
    ctx.strokeStyle="blue";
    ctx.stroke();
    ctx.fillStyle="red";
    ctx.fill();
Copy the code

ArcTo draws an arc

// The current position of the path is the starting point
// x1, y1 is control point 1
// x2, y2 is control point 2
arcTo(x1, y1, x2, y2, r)
Copy the code

The control points in arcTo are illustrated as follows:

ArcTo () can be understood as: the arc drawn is determined by two tangent lines (tangent to two lines, but not true circle due to the radius parameter).

Tangent line 1: The line determined by the starting point and control point 1.

Tangent line 2: the line determined by control points 1 and 2.

ctx.beginPath();
/ / starting point
ctx.moveTo(50.50);
Parameter 1 and 2: control point 1 coordinate parameter 3 and 4: control point 2 coordinate parameter 4: arc radius
ctx.arcTo(200.50.200.200.100);
ctx.lineTo(200.200); // If you do not draw the lineTo, the arc may not end at control point 2
ctx.stroke();

ctx.beginPath();
ctx.rect(50.50.10.10);
ctx.rect(200.50.10.10);
ctx.rect(200.200.10.10);
ctx.fill();
Copy the code

Transparency Settings

Rgba color setting transparency

Sets the opacity of the specified line or fill

ctx.beginPath();
ctx.rect(20.20.100.80);
ctx.strokeStyle = "Rgba (0255, 0, 3)";
ctx.lineWidth = 20;
ctx.stroke();
ctx.fill();
Copy the code

GlobalAlpha global transparency

GlobalAlpha = transparencyValue: Sets the transparency of all images on canvas from 0.0 (fully transparent) to 1.0 (completely opaque). Default is 1.0.

ctx.beginPath();
ctx.rect(20.20.100.80);
ctx.strokeStyle="Rgba (0255, 1)"
ctx.globalAlpha = 0.3;
ctx.lineWidth=20;
ctx.stroke();
ctx.fill();
Copy the code

Composite sample

Smiling face

    let width=canvas.width,height=canvas.height;
    / / dot
    let origin={
        x:width/2.y:height/2
    }

    / / smiling face
    let face_radius=100;
    ctx.beginPath();
    ctx.arc(origin.x,origin.y, face_radius,0.2*Math.PI);
    ctx.lineWidth = 2;
    ctx.stroke();

    // Eyebrows and eyes
    let per_dist= face_radius* 2 / 3;
    let leftEyeOrigin={
        x: origin.x - per_dist / 2.y: origin.y - per_dist / 3
    }

    / / the eyebrows
    ctx.beginPath();
    ctx.arc(leftEyeOrigin.x, leftEyeOrigin.y, face_radius/3,degreeToAngle(225),degreeToAngle(315));    
    ctx.lineWidth = 2;
    ctx.stroke();

    let rightEyeOrigin = {
        x: origin.x + per_dist / 2.y: origin.y - per_dist / 3
    }
    ctx.beginPath();
    ctx.arc(rightEyeOrigin.x, rightEyeOrigin.y, face_radius / 3, degreeToAngle(225), degreeToAngle(315));
    ctx.lineWidth = 2;
    ctx.stroke();

    / / eyes
    ctx.beginPath();
    ctx.arc(leftEyeOrigin.x,leftEyeOrigin.y,face_radius/5.0.2*Math.PI);
    ctx.stroke();
    ctx.beginPath();
    ctx.arc(leftEyeOrigin.x, leftEyeOrigin.y, face_radius / 10.0.2 * Math.PI);
    ctx.fillStyle = "#7b5028";
    ctx.fill();

    ctx.beginPath();
    ctx.arc(rightEyeOrigin.x, rightEyeOrigin.y, face_radius / 5.0.2 * Math.PI);
    ctx.stroke();
    ctx.beginPath();
    ctx.arc(rightEyeOrigin.x, rightEyeOrigin.y, face_radius / 10.0.2 * Math.PI);
    ctx.fillStyle="#7b5028";
    ctx.fill();

    // mouth
    mouth={
        x:origin.x,
        y:origin.y+ face_radius/10
    } 
    ctx.beginPath();
    ctx.arc(mouth.x,mouth.y,face_radius/2,degreeToAngle(30),degreeToAngle(150));
    ctx.stroke();
Copy the code

The moon

    let width=canvas.width,height=canvas.height;
    / / dot
    let origin={
        x:width/2.y:height/2
    }

    // Fill the entire canvas
    ctx.fillStyle="# 000";
    ctx.fillRect(0.0,canvas.width,canvas.height);
    / / the moon
    let earth_radius=100;
    let moon_radius=80;
    let moon_origin={
        x:origin.x-60.y:origin.y
    }
    
    ctx.beginPath();
    ctx.arc(moon_origin.x,moon_origin.y,moon_radius,0.2*Math.PI);
    ctx.fillStyle="yellow";
    ctx.fill();
    ctx.stroke();
    ctx.beginPath();
    ctx.arc(origin.x, origin.y, earth_radius, 0.2 * Math.PI);
    ctx.fillStyle="# 000";
    ctx.fill();
    ctx.stroke();
Copy the code