Bootstrap

前端Canvas组件学习

目录

前言

1 绘制线条

2 绘制折线

3 绘制矩形

4  绘制三角形

5 绘制圆

6 绘制弧线

7 绘制扇形

8 绘制椭圆

9 绘制文本

10 绘制网格图

11 绘制折线图

12 绘制贝塞尔曲线

13 绘制线性渐变

14 绘制放射性渐变

总结


前言

本文介绍如何利用canvas组件在网页中绘制图表

1 绘制线条

<!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>
        canvas{
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <!-- 
        canvas
        画布:
            矩形区域,可以控制该区域的每一像素
            画布默认尺寸300px*150px,可通过width和height设置
            (不要通过css设置 因为css设置并不会增加像素点个数,只是将每一个像素点放大)

            
     -->
     <!-- 通过属性方式设置画布尺寸 -->
     <canvas width="600" height="400" id="canvas"></canvas>
     <script>
        //获取画布元素的对象
        const canvas=document.querySelector("#canvas");
        //获取画布的上下文对象
        context=canvas.getContext("2d");
        //console.log(context);
        // 设置线条的起点
        context.moveTo(10,10);
        //设置线条的终点
        context.lineTo(510,10);
        //设置线条的颜色
        context.strokeStyle="red";
        //设置线条的粗细
        context.lineWidth=10;
        //设置线条两端的样式(线帽) 可选值:"butt|round|square"
        context.lineCap="round"
        //设置两条线相交时,拐角的类型
        //绘制线条(通过描边的方式)
        context.stroke();
     </script>
</body>
</html>

2 绘制折线

<!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>
        canvas{
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <!-- 
        canvas
        画布:
            矩形区域,可以控制该区域的每一像素
            画布默认尺寸300px*150px,可通过width和height设置
            (不要通过css设置 因为css设置并不会增加像素点个数,只是将每一个像素点放大)

            
     -->
     <!-- 通过属性方式设置画布尺寸 -->
     <canvas width="600" height="600" id="canvas"></canvas>
     <script>
        //获取画布元素的对象
        const canvas=document.querySelector("#canvas");
        //获取画布的上下文对象
        context=canvas.getContext("2d");
        //console.log(context);
        // 设置线条的起点
        context.moveTo(10,10);
        //设置线条的拐点
        context.lineTo(510,10);
        //设置线条的终点
        context.lineTo(510,260);
        //设置线条的颜色
        context.strokeStyle="red";
        //设置线条的粗细
        context.lineWidth=10;
        //设置线条两端的样式(线帽) 可选值:"butt|round|square",默认butt
        context.lineCap="round"
        //设置两条线相交时,拐角的类型 可选值:"miter|bevel|round",默认miter
        context.lineJoin="miter";
        //绘制线条(通过描边的方式)
        //设置均要在绘制之前完成
        context.stroke();
     </script>
</body>
</html>

3 绘制矩形

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600">
        <!-- 检测浏览器是否支持canvas,支持则不显示下列文字,不支持则显示下列文字 -->
        您的浏览器版本过低,请升级浏览器
    </canvas>
    <script>
        //获取画布上下文对象
        const context=document.querySelector('#canvas').getContext("2d");
        //绘制一个线条
        //设置线条的起点
        context.moveTo(10, 10);
        //设置线条的终点
        context.lineTo(10, 320);
        //设置线条的颜色
        context.strokeStyle='blue';
        //设置线条的粗细
        context.lineWidth="4";
        //绘制线条
        context.stroke();
        
        //开启一个独立的作用域(独立的绘制路径)
        context.beginPath();
        //绘制第二个线条
        context.moveTo(40,20);
        context.lineTo(40,320);
        context.strokeStyle="red";
        context.stroke();
        context.closePath();
        
        
        //绘制矩形
        //方法一
        context.beginPath();
        //设置起点
        context.moveTo(50,50);
        //设置第一个拐点
        context.lineTo(250,50);
        //设置第二个拐点
        context.lineTo(250,150);
        //设置第三个拐点
        context.lineTo(50,150);
        //返回原来的点
        //context.lineTo(50,50);
        //连接起点和终点,形成一个封闭区域
        context.closePath();
        //开始绘制
        context.stroke();

        //方法二
        context.beginPath();
        //设置关键信息 rect(x矩形左上角的横坐标, y矩形左上角的纵坐标, width矩形的宽度, height矩形的高度)
        context.rect(400, 80, 150,100);
        //设置填充色
        context.fillStyle="orange";
        //设置轮廓色
        context.strokeStyle='green';
        //绘制空心矩形
        context.stroke();
        //绘制实心矩形
        context.fill();
        

        //方法三
        context.beginPath();
        //通过描边的方式绘制空心矩形
        context.strokeRect(50, 400, 180, 130);
        //设置填充颜色
        context.fillStyle="yellow";
        //通过填充的方式绘制实心矩形
        context.fillRect(400,400,100,70);
    </script>
</body>
</html>

4  绘制三角形

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="400">
        <!-- 检测浏览器是否支持canvas,支持则不显示下列文字,不支持则显示下列文字 -->
        您的浏览器版本过低,请升级浏览器
    </canvas>
    <script>
        //获取画布上下文对象
        const context=document.querySelector('#canvas').getContext("2d");
             
        //绘制三角形
        context.moveTo(20, 20);
        context.lineTo(20, 220);
        context.lineTo(220,220);
        context.closePath();
        context.stroke();
        
    </script>
</body>
</html>

5 绘制圆

​
<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        const context=document.querySelector("#canvas").getContext('2d');
        //绘制圆形
        //x,y表示圆心的坐标,radius 圆的半径,Math.PI/180*startAngle起始弧度 ,Math.PI/180*endAngle 终止弧度 anticlockwise:是否逆时针绘制(true表示逆时针绘制,false表示顺时针绘制)
        //context.arc(x,y,radius,Math.PI/180*startAngle,Math.PI/180*endAngle,anticlockwise);
        context.arc(200,200,100,Math.PI/180*0,Math.PI/180*360);//绘制圆顺时针逆时针无所谓
        context.strokeStyle="red";
        //绘制空心圆形
        context.stroke();
        context.fillStyle='orange';
        //绘制实心圆形
        context.fill();
    </script>
</body>
</html>

​

6 绘制弧线

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        const context=document.querySelector("#canvas").getContext('2d');
        //绘制弧线
        //x,y表示圆心的坐标,radius 圆的半径,Math.PI/180*startAngle起始弧度 ,Math.PI/180*endAngle 
        //终止弧度 anticlockwise:是否逆时针绘制(true表示逆时针绘制,false表示顺时针绘制  默认值为false)
        //context.arc(x,y,radius,Math.PI/180*startAngle,Math.PI/180*endAngle,anticlockwise);
        context.arc(300,200,150,Math.PI/180*0,Math.PI/180*90,true);
        context.strokeStyle="red";
        //绘制弧线
        context.stroke();

    </script>
</body>
</html>

7 绘制扇形

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        const context=document.querySelector("#canvas").getContext('2d');
        //绘制扇形
        //x,y表示圆心的坐标,radius 圆的半径,Math.PI/180*startAngle起始弧度 ,Math.PI/180*endAngle 
        //终止弧度 anticlockwise:是否逆时针绘制(true表示逆时针绘制,false表示顺时针绘制  默认值为false)
        //context.arc(x,y,radius,Math.PI/180*startAngle,Math.PI/180*endAngle,anticlockwise);
        //设置画笔的起点 与顺序有关
        context.moveTo(300, 200);
        //绘制扇形的关键参数
        context.arc(300,200,150,Math.PI/180*0,Math.PI/180*90);
        context.strokeStyle="red";
        //自动形成一个闭合的区域
        context.closePath();
        //绘制扇形
        context.stroke();

        context.fillStyle="green";
        context.fill();

    </script>
</body>
</html>

8 绘制椭圆

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        const context=document.querySelector("#canvas").getContext('2d');
        //绘制椭圆
        //x,y表示圆心的坐标,radiusX 水平方向的半径, radiusY竖直方向的半径,rotation 旋转弧度 Math.PI/180*startAngle起始弧度 ,Math.PI/180*endAngle 
        //终止弧度 anticlockwise:是否逆时针绘制(true表示逆时针绘制,false表示顺时针绘制  默认值为false)
        //context.ellipse(x,y,radiusX,radiusY,rotation,Math.PI/180*startAngle,Math.PI/180*endAngle,anticlockwise);
        //绘制椭圆的关键参数
        context.ellipse(300,200,200, 100,Math.PI/2,Math.PI/180*0,Math.PI/180*360);
        context.strokeStyle="red";
        //绘制空心椭圆
        context.stroke();

        context.fillStyle="orange";
        //绘制实心椭圆
        context.fill();
    </script>
</body>
</html>

9 绘制文本

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
        //获取画布的dom对象
        const canvas=document.querySelector("#canvas");
        canvas.width=600;
        canvas.height=600;
        //获取画布的上下文对象
        const context=canvas.getContext('2d');
        //绘制文字
        //context.strokeText(文字内容,x,y,maxWidth);会自动绘制
        //x,y指的是文字绘制的矩形区域左下角的坐标
        //设置字体大小
        context.font="30px Microsoft Yahei";
        //设置文字在水平方向的对齐方式 'start|left|center|right|end' 
        //left center right参考的是绘制坐标x 
        //center将文字劈成两半,以绘制坐标x为轴对称分布 
        //left将文字矩形的左边界与绘制坐标x对齐
        //right将文字矩形的右边界与绘制坐标x对齐
        //start和left效果相同 right和end效果相同
        context.textAlign='center';
        //绘制描边文字
        //context.strokeText("你好,中国",100,100,300);
        context.strokeText("你好,中国",0,100,300);

        //绘制实心文字
        context.font="25px 宋体";
        context.fillText("hello world", 300, 300, 200);
        
    </script>
</body>
</html>

10 绘制网格图

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        const context=document.querySelector("#canvas").getContext('2d');
        //绘制网格
        
        //坐标系的尺寸
        const width=600;
        const height=600;
        //网格的尺寸
        const gridWidth=20;
        const gridHeight=20;
        //绘制一组水平线
        for(let i=0;i<=height/gridHeight;i++)
        {
            //开启独立的绘制路径
            context.beginPath();
            //设置水平线起点坐标
            //0,0 0,20 0,40
            context.moveTo(0, i*gridHeight);
            //设置水平线终点坐标
            //600,0 600,20 600,40
            context.lineTo(600,i*gridHeight);
            context.strokeStyle="blue";
            //开始绘制
            context.stroke();
        }
        //绘制一组垂直线
        for(let i=0;i<=width/gridWidth;i++)
        {
            //开启独立的绘制路径
            context.beginPath();
            //设置垂直线起点坐标
            //0,0 20,0 40,0
            context.moveTo(i*gridWidth,0);
            //设置垂直线终点坐标
            //0,600 20,600 40,600
            context.lineTo(i*gridWidth,600);
            context.strokeStyle="orange";
            //开始绘制
            context.stroke();
        }
    </script>
</body>
</html>

11 绘制折线图

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        const context=document.querySelector("#canvas").getContext('2d');
        //绘制网格
        
        //坐标系的尺寸
        const width=600;
        const height=600;
        //网格的尺寸
        const gridWidth=20;
        const gridHeight=20;
        //绘制一组水平线
        for(let i=0;i<=height/gridHeight;i++)
        {
            //开启独立的绘制路径
            context.beginPath();
            //设置水平线起点坐标
            //0,0 0,20 0,40
            context.moveTo(0, i*gridHeight);
            //设置水平线终点坐标
            //600,0 600,20 600,40
            context.lineTo(600,i*gridHeight);
            context.strokeStyle="gray";
            //开始绘制
            context.stroke();
        }
        //绘制一组垂直线
        for(let i=0;i<=width/gridWidth;i++)
        {
            //开启独立的绘制路径
            context.beginPath();
            //设置垂直线起点坐标
            //0,0 20,0 40,0
            context.moveTo(i*gridWidth,0);
            //设置垂直线终点坐标
            //0,600 20,600 40,600
            context.lineTo(i*gridWidth,600);
            context.strokeStyle="gray";
            //开始绘制
            context.stroke();
        }
        //绘制直角坐标系
        //开启独立的绘制路径
        context.beginPath();
        //设置起点
        context.moveTo(20,20);
        //设置拐点
        context.lineTo(20,580);
        //设置终点
        context.lineTo(580,580);
        //context.strokeStyle="black";
        //开始绘制
        context.stroke();

        //绘制x轴的箭头
        //开启独立绘制路径
        context.beginPath();
        context.moveTo(570,575);
        context.lineTo(580,580);
        context.lineTo(570,585);
        context.fill();

         //绘制y轴的箭头
        //开启独立绘制路径
        context.beginPath();
        context.moveTo(15,30);
        context.lineTo(20,20);
        context.lineTo(25,30);
        context.fill();

        //绘制折线
        /*
        context.beginPath();
        context.moveTo(20,580);
        context.lineTo(120,100);
        context.lineTo(320,80);
        context.lineTo(420,180);
        context.lineTo(480,280);
        context.lineWidth=2;
        context.strokeStyle="red";
        context.stroke();

        context.beginPath();
        context.moveTo(20,80);
        context.lineTo(120,120);
        context.lineTo(220,150);
        context.lineTo(320,220);
        context.lineTo(520,380);
        context.lineWidth=2;
        context.strokeStyle="orange";
        context.stroke();

        context.beginPath();
        context.moveTo(20,80);
        context.lineTo(120,150);
        context.lineTo(220,180);
        context.lineTo(320,210);
        context.lineTo(360,380);
        context.lineWidth=2;
        context.strokeStyle="purple";
        context.stroke();
        */

        //数组方式绘制
        const pionts=[
            [
                {x:20,y:580},{x:120,y:100},{x:320,y:80},{x:420,y:180},{x:480,y:280},
            ],
            [
                {x:20,y:80},{x:120,y:120},{x:220,y:150},{x:320,y:220},{x:520,y:380},
            ],
            [
                {x:20,y:80},{x:120,y:150},{x:220,y:180},{x:320,y:210},{x:360,y:380},
            ]
        ]

        pionts.forEach(item=>{
            context.beginPath();
            //将起点取出来
            const startPoint=item.shift();
            console.log(item);
            //设置起点
            context.moveTo(startPoint.x,startPoint.y);
            item.forEach(val=>{
                //设置拐点
                context.lineTo(val.x,val.y);
            })
            context.strokeStyle="orange";
            //绘制折线
            context.stroke();
        })
    </script>
</body>
</html>

12 绘制贝塞尔曲线

<!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>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>

<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        //绘制二次贝塞尔曲线
        const context = document.querySelector("#canvas").getContext('2d');
        context.strokeStyle = "#1572b5";
        context.lineWidth = 2;
        context.beginPath();
        //设置起点
        context.moveTo(137, 400);
        //设置控制点和终点
        //context.quadraticCurveTo(cpx, cpy, x, y);绘制二次贝塞尔曲线 cpx,cpy为控制点,x,y为结束点
        context.quadraticCurveTo(299, -4, 428, 399);
        context.stroke();

        //绘制三次贝赛尔曲线
        canvas = document.getElementById("canvas");
        ctx = canvas.getContext("2d")
        ctx.strokeStyle = "#1572b5";
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(180, 50);
        //ctx.bezierCurveTo(cpx1, cpy1, cpx2,cpy2,x,y);绘制二次贝塞尔曲线 cpx,cpy为控制点,x,y为结束点
        ctx.bezierCurveTo(150,130,201, 83, 450, 250);
        ctx.stroke();
        ctx.closePath();

    </script>
</body>

</html>

13 绘制线性渐变

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        const context=document.querySelector("#canvas").getContext('2d');
        //创建线性渐变对象
        //context.createLinearGradient(x1, y1, x2, y2);x1,y1:起始位置,x2,y2:结束位置
        //水平
        //const lg=context.createLinearGradient(0, 0, 200, 0);
        //垂直
        //const lg=context.createLinearGradient(0, 0, 0, 100);
        //对角线
        const lg=context.createLinearGradient(0, 0, 100, 100);
        //往渐变读写中添加渐变色
        //addColorStop(0, 'red');线性范围:0-1 color:颜色
        lg.addColorStop(0, 'red');
        lg.addColorStop(0.3, 'orange');
        lg.addColorStop(0.6, 'yellow');
        lg.addColorStop(1, 'green');

        //调用渐变色
        context.fillStyle=lg;
        //绘制实心矩形
        context.fillRect(10,20,200,100);
        
    </script>
</body>
</html>

14 绘制放射性渐变

<!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>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        const context=document.querySelector("#canvas").getContext('2d');
        //创建放射性渐变对象
        //createRadialGradient(x1, y1,r1, x2, y2,r2);x1,y1:内圆圆心,r1:内圆半径,x2,y2:外圆圆心,r2:外圆半径
        //水平
        //const rg=context.createRadialGradient(0, 0, 200, 0);
        //垂直
        //const rg=context.createRadialGradient(0, 0, 0, 100);
        //对角线
        const rg=context.createRadialGradient(200,200,20,200,200,120);
        //往渐变对象中添加渐变色
        //addColorStop(0, 'red');线性范围:0-1 color:颜色
        rg.addColorStop(0, 'red');
        rg.addColorStop(0.3, 'orange');
        rg.addColorStop(0.6, 'yellow');
        rg.addColorStop(1, 'green');
        //调用渐变色
        context.fillStyle=rg;
        //绘制圆形
        context.arc(200,200,150,0,Math.PI/180*360);
        context.fill();
        
    </script>
</body>
</html>

总结

学习了如何利用canvas组件在网页中绘制图形图表。

;