Use and understanding of entry-level canvas

1,canvas

  • canvas is h5 a new tag added, so it may not be compatible in the lower version of ie.
  • Canvas is a canvas, which can draw graphics freely.
  • canvas is a native js object and jq is not recommended

2. Basic use and introduction of canvas

1. Foundation use

Use the canvas tag to add width and height attributes

The canvas tag is an inline tag

<html>
<canvas height='400px' width='400px'></canvas>
</html>
<style>
    canvas{
      //You can set properties such as width, height and outer margin of the border  
    }
</style>

Low version incompatibility

Add prompt

<canvas height='400px' width='400px'>This version of browser does not support canvas Label, please update your browser or use tinder</canvas>

3. canvas draw line

1, Basic drawing method of straight line

The coordinate point is the origin from the point in the upper left corner__

1. Get canvas node

2. Create canvas path context

3. Open a path

4. Path starting point

5. Path end point

6. Add color to the path

7. End path

//Fixing steps
var canvas=document.getElementById('canvas') //Get canvas node
var c=canvas.getContext('2d')  //Establish canvas path context

c.beginPath()  //Enable a path beginpath() has the function of closing the previous line

c.moveTo(100,100)   //Path start point

c.lineTo(200,200)	//Path end point
//Set color before shading
c.strokeStyle='green'   //General color properties
//Set lineweight
c.lineWidth=5;

c.stroke()			//Add color to path

c.closePath()		//End path


//Translation center point
  can.translate(width / 2, height / 2)

2, Draw colorful lines and dashes

If you need to draw multiple lines with different colors, set the path, coordinate point and color for each line

//Fixing steps
var canvas=document.getElementById('canvas') //Get canvas node
var c=canvas.getContext('2d')  //Establish canvas path context


//First straight line
c.beginPath()  //Open a path
c.moveTo(100,200)   //Path start point
c.lineTo(200,200)	//Path end point
//Set color before shading
c.strokeStyle='green'   //General color properties
//Set lineweight
c.lineWidth=5;
c.stroke()			//Add color to path
c.closePath()		//End path

//Second straight line
c.beginPath()  //Open a path
c.moveTo(200,200)   //Path start point
c.lineTo(200,100)	//Path end point
//Set color before shading
c.strokeStyle='green'   //General color properties
//Set lineweight
c.lineWidth=5;
c.stroke()			//Add color to path
c.closePath()		//End path

//Third straight line
c.beginPath()  //Open a path
c.moveTo(200,100)   //Path start point
c.lineTo(100,100)	//Path end point
//Set color before shading
c.strokeStyle='green'   //General color properties
//Set lineweight
c.lineWidth=5;
c.stroke()			//Add color to path
c.closePath()		//End path

//Fourth straight line
c.beginPath()  //Open a path
c.moveTo(100,100)   //Path start point
c.lineTo(100,200)	//Path end point
//Set color before shading
c.strokeStyle='green'   //General color properties
//Set lineweight
c.lineWidth=5;
c.stroke()			//Add color to path
c.closePath()		//End path

The repeatability of this code is too high, so we can encapsulate the code in a straight line to get the following code

 //c is the canvas drawn
function drawLine(x1, y1, x2, y2, color, width) {  //x1: start abscissa, y1: start ordinate, x2: end abscissa, y2: end ordinate, color: line color, width: line width
        
        c.beginPath()  //Open a path
        c.moveTo(x1, y1)   //Path start point
        c.lineTo(x2, y2)	//Path end point
        //Set color before shading
        c.strokeStyle = color  //General color properties
        //Set lineweight
        c.lineWidth = width;
        c.stroke()			//Add color to path
        c.closePath()		//End path
    }

3, Straight line combination

When we need to use a uniform color line continuously, we can use the lineto() method to draw it together

//Fixing steps
var canvas=document.getElementById('canvas') //Get canvas node
var c=canvas.getContext('2d')  //Establish canvas path context

c.beginPath()  //Open a path
c.moveTo(100,200)   //Path start point
c.lineTo(200,200)	
c.lineTo(100,200)	
c.lineTo(100,100)
c.lineTo(100,200)	//Path end point
//Set color before shading
c.strokeStyle='green'   //General color properties
//Set lineweight
c.lineWidth=5;
c.stroke()			//Add color to path
c.closePath()		//End path

4, Dotted line

The dotted line is divided by multiple lines, so we can use multiple lines to form the dotted line. We can use the line function encapsulated above

//Construct a dashed line
drawLine(100,100,105,100,red,2)
drawLine(110,100,115,100,red,2)
drawLine(120,100,125,100,red,2)
drawLine(130,100,135,100,red,2)


//Or use the method directly
can.setLineDash(5,15) //Parameter 1: length of each segment of dotted line, parameter 2: interval
drawLine(130,100,135,100,red,2)

//You can use the for loop to build dashed lines
for (let i = 0; i < 20; i++) {
    drawLine(100 + i * 10, 100, 105 + i * 10, 100, 'red', 2)
}
//If you need to construct a slash, you can change the abscissa and ordinate at the same time
for (let i = 0; i < 20; i++) {
    drawLine(100 + i * 10, 100 + i * 10, 105 + i * 10, 105 + i * 10, 'red', 2)
}

4. Rectangle

We can draw a rectangle

can.rect(x,y,width,height)  //Draw a rectangle
/***
x : x coordinate of the upper left corner of the rectangle
y : y coordinate of the upper left corner of the rectangle
width: Width of rectangle
height: Height of rectangle
***/

can.rect(x,y,width,height)
//Fill rectangle
can.fillstyle='red'
can.fill()   
//Description border
can.strokeStyle='red'  //Set rectangle border color
can.lineWidth=5     //Sets the width of the rectangular border
can.stroke()       //Set a hollow rectangle

//There will be a problem that the rectangular border is covered, so we need to fill it first and stroke it. Don't reverse it


//More diversified methods

//Draw a filled rectangle
can.fillStyle = 'red'  //Rectangle fill color
can.fillRect(x,y,width,height)  
/***
x : x coordinate of the upper left corner of the rectangle
y : y coordinate of the upper left corner of the rectangle
width: Width of rectangle
height: Height of rectangle
***/

//Draw a hollow rectangle
can.strokeStyle = 'red'  //Border color
can.lineWidth=5     //Sets the width of the rectangular border
can.strokeRect(x,y,width,height) 
/***
x : x coordinate of the upper left corner of the rectangle
y : y coordinate of the upper left corner of the rectangle
width: Width of rectangle
height: Height of rectangle
***/

Thus, we can encapsulate the rectangular function

  function drawFill(x, y, width, height, color) {   //Parameter 1: ordinate of rectangle, parameter 2: abscissa of rectangle, parameter 3: width of rectangle, parameter 4: height of rectangle, parameter 5: color of rectangle
        can.fillStyle = color
        can.fillRect(x, y, width, height)
    }

5. Draw a rectangular statistical chart with straight lines and rectangles

    //Fixing steps
    var canvas = document.getElementById('canvas') //Get canvas node
    var can = canvas.getContext('2d')  //Establish canvas path context

    
   
    //Draw axis
    can.beginPath()  //Open a path
    can.moveTo(100, 100)   //Path start point
    can.lineTo(100, 400)
    can.lineTo(400, 400)	//Path end point
    //Set color before shading
    can.strokeStyle = 'green'   //General color properties
    //Set lineweight
    can.lineWidth = 1;

    can.stroke()			//Add color to path

    can.closePath()		//End path
	 function drawFill(x, y, width, height, color) {
        can.fillStyle = color
        can.fillRect(x, y, width, height)
    }
	//Add rectangle
    drawFill(110, 200, 30, 200, 'red')
    drawFill(160, 240, 30, 160, 'yellow')
    drawFill(210, 390, 30, 10, 'green')

//This is inefficient, so we can further upgrade this function

    function drawFillARR(data, width = 30, mr = 20, color = 'red') {
        let x = 100
        data.forEach(item => {
            can.fillStyle = color
            x += width + mr
            can.fillRect(x, 400 - item, width, item)
        });
    }
    drawFillARR([100, 20, 310, 20,100])

//In this way, you only need to pass in the array in an array to draw a simple cylindrical statistical table


//Randomly generated chart
 function drawFillRandom(width = 30, mr = 20, color = 'red') {
        let x = 100
        let data = []
        for (let i = 0; i < 6; i++) {
            let height = Math.random() * 280 + 10
            data.push(height)
        }
        data.forEach((item, index) => {
            can.fillStyle = color
            if (index == 0) {
                x += mr
            } else {
                x += width + mr
            }

            can.fillRect(x, 400 - item, width, item)
        });
    }
drawFillRandom()

6. Expand knowledge

  • Generate hexadecimal random color function
  • Generate rgb random number
//Randomly generated hexadecimal color
let color16='#' + parseInt(Math.random() * 0Xffffff).toString(16)

//Randomly generate rgb color
let rgbaColor = `rgb(${parseInt(Math.random() * 256)},${parseInt(Math.random() * 256)},${parseInt(Math.random() * 256)})`
    console.log(rgbaColor);

7. Clear canvas (important)

Method: can clearRect(x,y,width,height)

can.clearRect(x,y,width,height)

/***
x : Clear the x coordinate of the upper left corner
y : Clear the y coordinate of the upper left corner
width: Clear width
height: Clear height
***/

8. Draw a circle

Method: can arc(x,y,radius,startAngle,endAngle,counterclockwise)

can.arc(x,y,radius,startAngle,endAngle,counterclockwise)
/***
x: x-axis coordinates of the center point of the circle
y: y-axis coordinates of the center point of the circle
radius: Radius of circle
startAngle: Starting angle   
endAngle: End angle math PI is 180 degrees. Changing this value can draw an arc
counterclockwise: true is counterclockwise and false is clockwise
***/

can.arc(250,250,200,0,Math.PI*2,false)  //Draw a circle
can.fillStyle = 'green'  //Fill set color
can.fill()  //fill color
can.lineWidth=5  //Line width of circle
can.strokeStyle='red'  //Line set color
can.stroke()     //Add color to lines

Calculate circumferential coordinates
x=x+r*cos(angle)  Abscissa
y=y+r*sin(angle)  Ordinate

Simple practice

Draw a teacup

<body>
    <canvas id="canvas" height="600" width="600"></canvas>
</body>
<script>
    //Fixing steps
    var canvas = document.getElementById('canvas') //Get canvas node
    var can = canvas.getContext('2d')  //Establish canvas path context
    //teacup
    can.rect(200, 300, 200, 200)
    can.lineWidth = 4
    can.stroke()
    can.beginPath()
    can.arc(400, 400, 50, Math.PI / 2, Math.PI * 2 * 3 / 4, true)
    can.lineWidth = 10
    can.stroke()

    //breath
    can.beginPath()
    can.arc(400, 400, 50, Math.PI / 2, Math.PI * 2 * 3 / 4, true)
    can.lineWidth = 10
    can.stroke()

    for (let i = 0; i < 4; i++) {
        can.beginPath()
        can.arc(230 + i * 40, 200, 20, Math.PI / 2, Math.PI * 2 * 3 / 4, false)
        can.lineWidth = 2
        can.stroke()

        can.beginPath()
        can.arc(230 + i * 40, 240, 20, Math.PI / 2, Math.PI * 2 * 3 / 4, true)
        can.lineWidth = 2
        can.stroke()
    }

</script>

9. Expand knowledge

Use the timer to draw the statistical timer

<body>
    <canvas id="canvas" height="500" width="500"></canvas>
</body>
<script>
    //Fixing steps
    var canvas = document.getElementById('canvas') //Get canvas node
    var can = canvas.getContext('2d')  //Establish canvas path context

    let deg = Math.PI / 180
    let count = 0
    let timer = setInterval(
        function () {
            if (count > 360) {
                clearInterval(timer)
            }
            count++
            can.beginPath()
            can.arc(250, 250, 200, 0, count * deg, false)  //Draw a circle
            // can.fillStyle = 'green' / / fill setting color
            // can.fill() / / fill color
            // can.lineWidth = 5 / / line width of the circle
            can.strokeStyle = 'red'  //Line set color
            can.stroke()     //Add color to lines
        }, 1
    )


</script>

10. Collision detection

The logic is: if it collides with the specified position, the acceleration is opposite

<body>
    <canvas id="canvas" height="500" width="500"></canvas>
</body>
<script>
    //Fixing steps
    var canvas = document.getElementById('canvas') //Get canvas node
    var can = canvas.getContext('2d')  //Establish canvas path context

    let arc1 = {
        x: 20,
        y: 20,
        r: 20,
        xv: 1,
        yv: 1
    }
    let width = 500
    let height = 500


    setInterval(function () {
        can.clearRect(0, 0, width, height)   //Empty the canvas after each movement
        can.beginPath()                     //Clear the brush when the motion is complete


        if ((arc1.x - arc1.r) < 0 || (arc1.x + arc1.r) >= width) {  //Making elastic collision of x-axis
            arc1.xv = -arc1.xv
        }
        arc1.x += arc1.xv


        if ((arc1.y - arc1.r) < 0 || (arc1.y + arc1.r) >= height) { //Making elastic collision of y-axis
            arc1.yv = -arc1.yv
        }
        arc1.y += arc1.yv


        can.arc(arc1.x, arc1.y, arc1.r, 0, Math.PI * 2, false)  //Draw a ball
        can.fillStyle = 'green'  //Fill set color
        can.fill()  //fill color
    }, 5)


</script>

Object oriented small ball, randomly generate multiple small balls

Randomly generate multiple small ball collisions
<body>
    <canvas id="canvas" height="500" width="500"></canvas>
</body>
<script>
    //Fixing steps
    var canvas = document.getElementById('canvas') //Get canvas node
    var can = canvas.getContext('2d')  //Establish canvas path context

    let width = 500
    let height = 500
    function r(num) {
        return parseInt(Math.random() * num)
    }
    function Ball() {   //Randomly generated ball
        this.r = r(40) + 10  //Small ball radius [10,50)
        //Randomly generated location
        this.x = r(400) + 50
        this.y = r(400) + 50

        this.color = '#' + parseInt(Math.random() * 0Xffffff).toString(16) / / randomly generate color
        this.xv = r(3) > 1 ? ~(r(2) + 2) : r(2) + 2//[2,5)
        this.yv = r(3) > 1 ? ~(r(2) + 2) : r(2) + 2//[2,5)
    }
    Ball.prototype.show = function () {
        this.run()
        can.beginPath()                     //Clear the brush when the motion is complete
        can.arc(this.x, this.y, this.r, 0, Math.PI * 2, false)  //Draw a ball
        can.fillStyle = this.color//Fill set color
        can.fill()  //fill color
    }
    Ball.prototype.run = function () {
        // can.clearRect(0, 0, width, height) / / empty the canvas after each movement

        if ((this.x - this.r) < 0 || (this.x + this.r) >= width) {  //Making elastic collision of x-axis
            this.xv = -this.xv
        }
        this.x += this.xv


        if ((this.y - this.r) < 0 || (this.y + this.r) >= height) { //Making elastic collision of y-axis
            this.yv = -this.yv
        }
        this.y += this.yv
    }
    let timer = null
    function addBall(num) {
        can.clearRect(0, 0, width, height)
        if (timer) {
            clearInterval(timer)
        }
        let ballArr = []
        for (let i = 0; i < num; i++) {  // Add ball
            let ball = new Ball()
            ballArr.push(ball)
            ball.show()
        }
        timer = setInterval(function () {   //Start moving
            can.clearRect(0, 0, width, height)   //Empty the canvas after each movement
            for (let i = 0; i < ballArr.length; i++) {
                ballArr[i].show()
            }
        }, 5)
    }
    addBall(10)

</script>

11. Draw text

Method: can fillText(text,x,y,maxWidth)

//Draw basic text
can.fillText(text,x,y,maxWidth)
/***
text: Text content
x: x coordinate of the lower left corner of the text
y: y coordinate of the lower left corner of the text
maxWidth:If the maximum width of the optional text is specified, it will overflow
***/

//Set text style
can.font='30px Microsoft YaHei ' //Size and style
can.fillstyle='red'  //Set text color
can.fillText('Hello',300,300)


//Properties of horizontal text
textAlign Value of:start end left right center  The default value is left
can.textAlign='left'

//Alignment of baseline (vertical position)
textBaseline: Top Botton Middle  The default value is top 
can.textBaseline='top'



//Draw empty text
can.strokeStyle='green'
can.strokeText('Hello',200,200)



//It doesn't matter. All students learn by themselves
//Draw Gradient Text
can.createLinearGradient(0,0,canvas,width,0)

12. Draw picture

Syntax 1:

can.drawImage(img,x,y)

can.drawImage(img,x,y)
/***
img:picture
x: x-axis coordinates of the starting position of the picture
y: y-axis coordinates of the starting position of the picture
***/

Syntax 2:

can.drawImage(img,x,y,width,height)

can.drawImage(img,x,y,width,height)
/***
img:picture
x: x-axis coordinates of the starting position of the picture
y: y-axis coordinates of the starting position of the picture
width:Picture width (zoom in or out)
height:The height of the cut picture (zoom in or out)
***/

Grammar 3

can.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)

can.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
/***
img:picture
sx:The x-axis coordinate of the start of cutting
sy:y-axis coordinates of the start of cutting
swidth:Width of the picture to start cutting
sheight:Height of the picture to start cutting
x: x-axis coordinates of the position after image cutting
y: y-axis coordinates of the position after image cutting
width:Width after image cutting
height:Height after image cutting
***/

Picture knowledge supplement

    let img = new Image()   //Create an instance of a picture
    img.src = 'fangzi.jpg'   //set up path
/***
The function will be triggered when the picture is loaded
 onload triggered successfully:
Failed to trigger onerror:
***/
 var canvas = document.getElementById('canvas') //Get canvas node
    var can = canvas.getContext('2d')  //Establish canvas path context
    let img = new Image()
    img.src = 'fangzi.jpg'
    img.onload = function () {
        console.log(img.width, img.height);
        can.drawImage(img, 450, 400, 460, 500, 0, 0, 250, 250) //Cut and move to a location
    }

getImageData(x,y,width,height)

//Gets the pixel data of the rectangle at the specified position
can.getImageData(x,y,width,height)
/***
x: Position x-axis coordinates
y: Position y-axis coordinates
width:image width
height:Picture height
***/
//After obtaining, it is stored in the form of an array

If you use local pictures, there will be cross domain problems, and there is no solution
 add to img.crossOrigin = '';
Use web pictures

putImageData(imaData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight)

//Place the picture in a position
putImageData(imaData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight)
/***
imgData  //Specifies the imageData object to put back on the canvas
x  ImageData The x-axis coordinate of the upper left corner of the object, calculated in pixels
y  ImageData The y-axis coordinate of the upper left corner of the object, calculated in pixels
dirtyX  Optional parameter, horizontal x, calculated in pixels, where the image is placed on the canvas
dirtyy  Optional parameter, horizontal value, calculated in pixels, where the image is placed on the canvas
dirtyWidth  Optional, the width of the drawn image
dirtyHeight   Optional, the height at which the image is drawn on the canvas
***/

//You can first use getImageData to get the data to be placed in putImageData

The previous summary strengthens the practice of linear ball

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        /* canvas {
            border: 1px solid;
            display: block;
            margin: 0 auto;
        } */
    </style>
</head>

<body style="overflow:-Scroll;overflow-y:hidden">
    <canvas id="canvas"></canvas>
</body>
<script>
    let canvas = document.querySelector('#canvas')
    let can = canvas.getContext('2d')
    let height = document.documentElement.clientHeight
    let width = document.documentElement.clientWidth
    canvas.height = height
    canvas.width = width
    // let width = 800
    // let height = 800
    //Draw a straight line
    function drawLine(x1, y1, x2, y2, color) {  //x1: start abscissa, y1: start ordinate, x2: end abscissa, y2: end ordinate, color: line color, width: line width
        can.beginPath()  //Open a path
        can.moveTo(x1, y1)   //Path start point
        can.lineTo(x2, y2)	//Path end point
        //Set color before shading
        can.strokeStyle = color || '#000 '/ / general color attribute
        //Set lineweight
        can.lineWidth = 2;
        can.stroke()			//Add color to path
        can.closePath()		//End path
    }

    //Write text
    function drawText(text, x, y) {
        can.font = '15px Microsoft YaHei ' //Size and style
        can.textAlign = 'center'
        can.textBaseline = 'top'
        can.fillText(text, x, y)

    }
    let strArr = 'python java javasprit HTML5 CSS3 Nodejs PHP VUE React'.split(' ')
    //Generate small ball
    function r(num) {
        return parseInt(Math.random() * num)
    }
    function Ball() {   //Randomly generated ball
        this.r = r(40) + 10  //Small ball radius [10,50)
        //Randomly generated location
        this.x = r(width - 100) + 50
        this.y = r(height - 100) + 50
        this.color = `rgb(${parseInt(Math.random() * 256)},${parseInt(Math.random() * 256)},${parseInt(Math.random() * 256)})`  //Randomly generated color
        this.xv = r(3) > 1 ? ~(r(2) + 2) : r(2) + 2//[2,5)
        this.yv = r(3) > 1 ? ~(r(2) + 2) : r(2) + 2//[2,5)
    }
    Ball.prototype.show = function () {
        this.run()
        can.beginPath()                     //Clear the brush when the motion is complete
        can.arc(this.x, this.y, this.r, 0, Math.PI * 2, false)  //Draw a ball
        can.fillStyle = this.color//Fill set color
        can.fill()  //fill color
    }
    Ball.prototype.run = function () {
        // can.clearRect(0, 0, width, height) / / empty the canvas after each movement

        if ((this.x - this.r) < 0 || (this.x + this.r) >= width) {  //Making elastic collision of x-axis
            this.xv = -this.xv
        }
        this.x += this.xv


        if ((this.y - this.r) < 0 || (this.y + this.r) >= height) { //Making elastic collision of y-axis
            this.yv = -this.yv
        }
        this.y += this.yv
    }
    let timer = null
    function addBall(num) {
        can.clearRect(0, 0, width, height)
        if (timer) {
            clearInterval(timer)
        }
        let ballArr = []
        for (let i = 0; i < num; i++) {  // Add ball
            let ball = new Ball()
            ballArr.push(ball)

            ball.show()
        }
        timer = setInterval(function () {   //Start moving
            can.clearRect(0, 0, width, height)   //Empty the canvas after each movement
            for (let i = 0; i < ballArr.length; i++) {
                ballArr[i].show()
                drawText(strArr[i], ballArr[i].x, ballArr[i].y + ballArr[i].r + 5)   //Add text tracking ball
                for (let j = 0; j < i; j++) {
                    drawLine(ballArr[i].x, ballArr[i].y, ballArr[j].x, ballArr[j].y, ballArr[i].color)  //Dash from large to small
                }
            }

        }, 10)
    }
    addBall(strArr.length)
</script>

</html>

Strengthen linear practice

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        /* canvas {
            border: 1px solid;
            display: block;
            margin: 0 auto;
        } */
    </style>
</head>

<body style="overflow:-Scroll;overflow-y:hidden">
    <canvas id="canvas"></canvas>
</body>
<script>
    let canvas = document.querySelector('#canvas')
    let body = document.querySelector('body')
    let can = canvas.getContext('2d')
    let height = document.documentElement.clientHeight
    let width = document.documentElement.clientWidth
    canvas.height = height
    canvas.width = width
    //Generate small ball
    function r(num) {
        return parseInt(Math.random() * num)
    }
    function Ball(x, y) {   //Randomly generated ball
        this.r = 60 //Small ball radius [10,50)
        //Randomly generated location
        this.x = x
        this.y = y
        this.color = `rgb(${parseInt(Math.random() * 256)},${parseInt(Math.random() * 256)},${parseInt(Math.random() * 256)})`  //Randomly generated color
    }
    Ball.prototype.show = function () {
        can.beginPath()
        this.r -= 5                  //Clear the brush when the motion is complete
        can.arc(this.x, this.y, this.r, 0, Math.PI * 2, false)  //Draw a ball
        can.fillStyle = this.color//Fill set color
        can.fill()  //fill color
    }


    let ballArr = []
    setInterval(function () {   //Remove the ball from the array
        can.clearRect(0, 0, width, height)
        for (let i = 0; i < ballArr.length; i++) {
            let ball = ballArr[i]
            if (ball.r <= 0) {   //When the radius is 0, this element is removed from the array
                ballArr.splice(i, 1)
            } else {
                ballArr[i].show()   //Otherwise, continue rendering
            }
        }
    }, 30)
    window.addEventListener('mousemove', function (e) {  //Get x, y when moving
        let ball = new Ball(e.x, e.y)
        ballArr.push(ball)
        ball.show()
    })

</script>

</html>

Draw clock

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        div {
            background-color: #ccc;
            border-radius: 20px;
            width: 400px;
            height: 400px;
            margin: 0 auto;
            margin-top: 100px;
        }

        canvas {
            /* border: 1px solid; */
            /* background-color: #fff; */
            display: block;
            margin: 0 auto;
        }
    </style>
</head>

<body style="overflow:-Scroll;overflow-y:hidden">
    <div>
        <canvas id="canvas"></canvas>
    </div>
</body>
<script>
    let canvas = document.querySelector('#canvas')
    let can = canvas.getContext('2d')
    // let height = document.documentElement.clientHeight
    // let width = document.documentElement.clientWidth
    // canvas.height = height
    // canvas.width = width
    // let width = 800
    // let height = 800
    canvas.height = 400
    canvas.width = 400
    let height = width = 400   //Clock width and height
    let x = y = 200     //Clock center point
    let r = 180       //Clock radius
    let r_houe = 60   //Hour hand length
    let r_min = 120   //Minute hand length
    let r_s = 140    //Second hand length
    let r_text = 140   //Text radius
    let r_square = 165   //Scale radius
    let r_circle = 10   //Dial dot
    let deg = 2 * Math.PI   //Define basic circle size
    //Draw a straight line
    function drawLine(x1, y1, x2, y2, color, width) {  //x1: start abscissa, y1: start ordinate, x2: end abscissa, y2: end ordinate, color: line color, width: line width
        can.beginPath()  //Open a path
        can.moveTo(x1, y1)   //Path start point
        can.lineTo(x2, y2)	//Path end point
        //Set color before shading
        can.strokeStyle = color || '#000 '/ / general color attribute
        //Set lineweight
        can.lineWidth = width || 2;
        can.stroke()			//Add color to path
        can.closePath()		//End path
    }

    //Draw text
    function drawText(text, x, y) {
        can.font = '700 20px Microsoft YaHei ' //Size and style
        can.textAlign = 'center'
        can.textBaseline = 'middle'
        can.fillText(text, x, y)
    }

    //Draw a circle
    function drawArc(x, y, r, color) {
        can.beginPath()
        can.arc(x, y, r, 0, Math.PI * 2, false)
        // can.lineWidth = 1
        // can.stroke()
        can.fillStyle = color || '#fff'
        can.fill()
    }
    // 1. Reset center point
    can.translate(width / 2, height / 2)

    function startM() {  //Constant value
        //2. Draw dial
        drawArc(0, 0, r)   //Clock dial
        drawArc(0, 0, r_circle, '#000 ') / / center point
        //3. Draw numbers
        for (let i = 1; i <= 12; i++) {
            let flagDeg = (2 * Math.PI) / 12 * i + (2 * Math.PI) / 12 * (~2)
            x = r_text * Math.cos(flagDeg)
            y = r_text * Math.sin(flagDeg)
            drawText(i, x, y)
        }

        //4. Draw scale
        for (let i = 1; i <= 60; i++) {
            let flagDeg = (2 * Math.PI) / 60 * i
            if (i % 5 == 0) {
                drawLine(r * Math.cos(flagDeg), r * Math.sin(flagDeg), (r - 10) * Math.cos(flagDeg), (r - 10) * Math.sin(flagDeg), '#aaa', 2)
            } else {
                drawLine(r * Math.cos(flagDeg), r * Math.sin(flagDeg), (r - 6) * Math.cos(flagDeg), (r - 6) * Math.sin(flagDeg), '#ccc', 1)
            }
        }

    }
    startM()
    drawLine(0, 0, 0, ~r_houe, 'red', 5)  //Clock
    drawLine(0, 0, 0, ~r_min, 'yellow', 3)   //minute hand
    drawLine(0, 0, 0, ~r_s, 'blue', 2)     //second hand
    function houe() {
        this.x = 0
        this.y = r_houe
        this.r = r_houe
        this.color = 'red'
        this.width = 5
        this.total = 0
    }
    function min() {
        this.x = 0
        this.y = r_min
        this.r = r_min
        this.color = 'blue'
        this.width = 3
        this.total = 0
    }
    function mis() {
        this.x = 0
        this.y = r_s
        this.r = r_s
        this.color = 'yellow'
        this.width = 2
        this.total = 0
    }
    houe.prototype.run = function (m) {
        let flagDeg = (2 * Math.PI) / 12 * this.total - Math.PI / 2 + m
        drawLine(0, 0, this.r * Math.cos(flagDeg), this.r * Math.sin(flagDeg), this.color, this.width)  //Clock
    }
    min.prototype.run = function (s) {
        let flagDeg = (2 * Math.PI) / 60 * this.total - Math.PI / 2 + s
        drawLine(0, 0, this.r * Math.cos(flagDeg), this.r * Math.sin(flagDeg), this.color, this.width)  //minute hand

    }
    mis.prototype.run = function () {
        let flagDeg = (2 * Math.PI) / 60 * this.total - Math.PI / 2
        drawLine(0, 0, this.r * Math.cos(flagDeg), this.r * Math.sin(flagDeg), this.color, this.width)  //second hand

    }
    let h = new houe()
    let m = new min()
    let s = new mis()
    setInterval(function () {
        can.clearRect(-200, -200, 400, 400)
        startM()
        if (s.total == 60) {
            s.total = 0
            s.total += 1
            if (m.total == 60) {
                m.total = 0
                m.total += 1
                if (h.total == 12) {
                    h.total = 0
                    m.total += 1
                } else {
                    h.total += 1
                }
            } else {
                m.total += 1
            }
        } else {
            s.total += 1
        }

        h.run((2 * Math.PI / 60 * m.total) / 360 * 30)
        m.run((2 * Math.PI / 60 * s.total) / 360 * 6)
        s.run()
    }, 1000)
</script>

</html>

Tags: Javascript Front-end css

Posted by logging on Tue, 17 May 2022 04:53:11 +0300