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!

The basic code is as follows, and all examples are implemented on this Canvas

<style>
    canvas{
        border: 1px solid #000;
    }
</style>

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

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

Basic graph transformation

Basic graphic transformations include displacement, rotation, and scaling. In canvas, these operations are performed based on the origin of the frame. In complex multi-graphics processing, different graphics applications have many kinds of transformations, which may cause confusion. Therefore, Canvas provides save and restore methods to realize the isolation and restoration of coordinate system, color setting and other contexts.

Displacement (translate)

  • translate(x, y): Moves the canvas origin to the specified position. namelyI’m moving the origin.
ctx.beginPath();
// Move the canvas frame origin to x, y
ctx.translate(origin.x,origin.y);
ctx.arc(0.0.20.0.2*Math.PI);
ctx.fillStyle="green";
ctx.fill();

ctx.beginPath();
ctx.rect(-canvas.width/2 +100,-canvas.height/2+50.200.100);
ctx.strokeStyle="red";
ctx.stroke();
Copy the code

Rotation (rotate)

  • Rotate (Angle): Rotates an axis in radians in a clockwise direction, with the center of the rotation being the origin.

    Rotation (origin of coordinates)

let rotateTest=function(){
    ctx.beginPath();
    ctx.rotate(Math.PI/180*30);
    ctx.rect(0.0.320.180);
    ctx.fillStyle="green";
    ctx.fill();
}
rotateTest();
Copy the code

  1. Move and rotate
let rotateTest2=function(){
    // Shift the origin and rotate at the origin
    ctx.translate(100.100);

    ctx.beginPath();           
    ctx.rect(0.0.320.180);
    ctx.fillStyle = "red";
    ctx.fill();

    ctx.beginPath();
    ctx.rotate(Math.PI/180*32);
    ctx.rect(0.0.320.180);
    ctx.fillStyle="green";
    ctx.fill();
}
rotateTest2();
Copy the code

Zoom (scale)

  • scale(x, y)Reduce or enlarge the shape (bitmap) by increasing or decreasing the number of pixels in the canvas.

Scale method. X and y indicate the scale of the horizontal and vertical axes respectively, and the value is positive. Less than 1 means shrinking, greater than 1 means zooming in, and 1 is the original scale.

By default, the unit of a Canvas is 1 pixel. For example, if we set the scale factor to 0.5, 1 unit will correspond to 0.5 pixels, and the shape will be half the same. Similarly, when set to 2.0, 1 unit corresponds to 2 pixels, and the result is that the graph is magnified twice.

You can view the scale as the scale of the entire canvas coordinate system

let scaleTest=function(){
    ctx.beginPath();
    ctx.strokeStyle="green";
    ctx.lineWidth=3;
    ctx.strokeRect(0.0.200.100);

    // Scale the x or y axis
    ctx.scale(2.1);
    ctx.scale(1.2);
    ctx.scale(2.2);
    ctx.beginPath();    
    ctx.strokeStyle = "red";
    ctx.lineWidth = 3;
    ctx.strokeRect(0.0.200.100);
}
scaleTest();
Copy the code

The distance between two points

So here we go. Use the Pythagorean theorem to find the distance

let getDistance=function(x1,y1,x2,y2){
    return Math.sqrt(Math.abs((x1 - x2) * (x1 - x2))*Math.abs((y1-y2)*(y1-y2)))
}
Copy the code

Sin, cos, tan, atan2 function

In mathematics, the relation between sine-sine, cos-cosine and tan-tangent is as follows:

  • Math.sin(x)Returns a value between -1 and 1, representing the sine of a given Angle in radians.
  • Math.cos(x)Returns a value between -1 and 1 that represents the cosine of an Angle in radians.
  • Math.atan2(y,x)Return the plane Angle (radian value) between the line segment from the origin (0,0) to (x,y) and the positive direction of the X-axis. Return the offset Angle of the points x,y between the value -pi and PI.Math.atan(y/x)The radians returned in the 1, 3, or 2, 4 quadrants are the same, indistinguishable.
  • Math.tan(x)Returns the tangent of an Angle (radian). `

// sin cos atan2
let sincosatan2Test=function(){
    let p={
        x:100.y:100,}let alpha=Math.atan2(p.x,p.y);
    console.log(` coordinates${p.x}.${p.y}Radian value of:${alpha}`);
    console.log(` coordinates${p.x}.${p.y}The point of view of:${alpha*180/Math.PI}Degree of `);
    let anglePI_sin=Math.sin(Math.PI);
    let anglehalfPI_sin=Math.sin(Math.PI/2);
    let angle2PI_sin = Math.sin(Math.PI*2);
    let angle1000_sin = Math.sin(1000);
    console.log("The sine of PI:"+anglePI_sin);
    console.log("The sine of 1/2PI:"+anglehalfPI_sin);
    console.log("2*PI sine:"+angle2PI_sin);
    console.log("The sine of 1000:"+angle1000_sin);

    let anglePI_cos = Math.cos(Math.PI);
    let anglehalfPI_cos = Math.cos(Math.PI / 2);
    let angle2PI_cos = Math.cos(Math.PI * 2);
    let angle1000_cos = Math.cos(1000);
    console.log("The sine of PI:" + anglePI_sin);
    console.log("The sine of 1/2PI:" + anglehalfPI_sin);
    console.log("2*PI sine:" + angle2PI_sin);
    console.log("The sine of 1000:" + angle1000_sin);
}
sincosatan2Test();
Copy the code

Save and restore Canvas state

In Canvas, Saving and Restoring State are essential operations when drawing complex graphics.

The function of save is to isolate a new canvas context, save the previous state, reset the new style and draw graphics; The purpose of restore is to restore the last saved state, drawn with the old style.

Especially in cases where effects such as displacement, rotation, and scaling are used, restore restores the state of the coordinate system and prevents confusion in complex operations.

save()andrestore()Method to save and restore the Canvas state

The state of a Canvas is a snapshot of all the styles and distortions applied to the current Canvas.

save()

Canvas state is stored on the stack, and every time the save() method is called, the current state is pushed to the stack for saving.

A painting state includes:

  • Deformation of the current application (i.e. move, rotate and scale)

  • strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, Value of shadowBlur, shadowColor, globalCompositeOperation

  • Current clipping path

The save method can be called any number of times. (Like array push())

restore()

Each time the restore method is called, the last saved state is popped off the stack and all Settings are restored. (Like pop() for arrays).

Save and Resotre are very convenient to isolate and manage the canvas context state. Usually, the canvas effect can be as follows:

// Save the previous state
ctx.save();
// Style Settings
/ /...
ctx.restore();// Restore the status
Copy the code

Examples for save and Restore

As follows, use this process: Draw a square, save the previous state and modify the color draw, Save the previous state and modify the color draw, Restore the state and draw, restore the state and draw, a small example of draw.

// The state is saved and restored
let statusSaveRestore=function(){
    ctx.fillRect(0.0.150.150);   // Draw a rectangle using the default Settings
    ctx.save();                  // Save the default state

    ctx.fillStyle = 'red'       // Change the color based on the original configuration
    ctx.fillRect(15.15.120.120); // Draw a rectangle with the new Settings

    ctx.save();                  // Save the current state
    ctx.fillStyle = '#FFF'       // Change the color configuration again
    ctx.fillRect(30.30.90.90);   // Draw a rectangle with the new configuration

    ctx.restore();               // Reload the previous color state
    ctx.fillRect(45.45.60.60);   // Draw a rectangle using the last configuration

    ctx.restore();               // Load the default color configuration
    ctx.fillRect(60.60.30.30);   // Draw a rectangle using the loaded configuration
}
statusSaveRestore();
Copy the code

The effects of saving and restoring without using state are as follows:

Various examples of pentacle stars

As follows, the five sharp angles and five obtuse angles of a five-pointed star can be regarded as 10 points evenly separated from the center of the circle. The inner and outer circles can each contain 5 points. Given different radii of the inner and outer circles, the coordinates of each point can be obtained by sines and cosines.

As follows, the implementation of the pentagram function code, but also can be modified to prevent the generation of anti-pentagram:

// Draw a five-pointed star
let drawPentagram=function(options){

    let ctx=options.ctx;
    let origin = {
        x: options.x,
        y: options.y
    }
    let lengthScale=options.lengthScale||0.4; // More than 1 is also a pentagram

    // The long and short sides of the pentacle
    let lengthR = options.lengthR||100;
    let shortR = lengthScale* lengthR;
    // The angular radian of the pentagram
    let starRotate=options.starRotate||0;
    let strokeColor=options.strokeColor||"red";

    let deg = Math.PI * 2 / 10;

    
    ctx.save();
    // Move the canvas origin to the center of the pentacle
    ctx.translate(origin.x, origin.y);
    // Assume that the long side Angle is on the X-axis
    // Rotate the coordinate system so that the x axis is up, that is, the sharp Angle is up, to ensure that the pentacle is aligned
    ctx.rotate(- Math.PI / 2);

    ctx.rotate(starRotate);

    ctx.beginPath();
    //ctx.moveTo(lengthR*Math.cos(0),lengthR*Math.sin(0));
    ctx.moveTo(lengthR, 0);
    for (let i = 1; i < 10; i++) {
        let currDeg = i * deg;
        if (i % 2= = =0) { //lengthR
            ctx.lineTo(lengthR * Math.cos(currDeg), lengthR * Math.sin(currDeg));
        }
        else {
            ctx.lineTo(shortR * Math.cos(currDeg), shortR * Math.sin(currDeg));
        }
    }
    ctx.closePath();
    ctx.strokeStyle = strokeColor;
    ctx.stroke();
    // Put the frame rotation in the positive direction. The frame is rotated, and the previously drawn figure remains the same
    // Because restore is used, the rotation restore can be omitted here
    // ctx.rotate(Math.PI / 2);
    ctx.restore();

}
Copy the code

Draw a standard five-pointed star:

drawPentagram({
    ctx, 
    x:canvas.width / 2.y:canvas.height / 2});Copy the code

The code looks like this:

Randomly generate countless stars:

let colorArr=["red"."greed"."yellow"."pink"."olive"."blue"."orange"."brown"."purple"]

for (let i = 0; i < 10; i++) {
    drawPentagram({
        ctx,
        x: canvas.width*Math.random(),
        y: canvas.height*Math.random(),
        lengthR:100*Math.random(),
        lengthScale: Math.random(),
        strokeColor:colorArr[Math.floor(colorArr.length*Math.random())],
        starRotate: Math.PI*2* Math.random()
    });
}
Copy the code

The code looks like this: