目录

  1. canvas介绍
  2. canvas绘制矩形
  3. canvas绘制圆形
  4. 使用moveTo()和lineTo()绘制路径
  5. 贝赛尔和二次方曲线
  6. 绘制变形图形

1. canvas介绍

canvas是HTML5中新增的一个元素,专门用来绘制图形。在页面放置一个canvas元素,就相当于放置了一个画布,可以在其中进行图形的绘制。但绘制图形,并不是指使用鼠标作画,而是需要javascript进行配合。创建canvas的时候,他默认的宽高为300px*150px

<canvas id="canvas">我是一个画布</canvas>

2. canvas绘制矩形

我们在HTML页面中直接插入canvas标签,也可以对它设置宽度和高度,切记设置canvas的时候不可以利用css样式进行设置

<canvas id="canvas" width="400" height="300">我是一个画布</canvas>

canvas 基础API

方法 描述
getContext() 获取绘图环境,可选参数”2d”
fillRect(x,y,width,height) 绘制一个填充的矩形(其实就是实心的)
strokeRect(x,y,width,height) 绘制一个矩形的边框(空心的)
clearRect(x,y,width,height) 清除指定矩形区域
练习1. 填充矩形:

效果图:

实现代码 :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>绘制一个实心矩形</title>
    </head>
    <body>
        <!--创建一个canvas-->
        <canvas id="myCanvas" width="800" height="800"></canvas>
        <script type="text/javascript">
            //获取canvas
            var myCanvas = document.getElementById("myCanvas");
            //设置canvas的绘图环境
            var oGx = myCanvas.getContext("2d")
            //绘制黑色的填充矩形 (就是黑色的矩形)
            /*
             x坐标为100、
             y坐标为100,
             宽高为100*100
             * */
            oGx.fillRect(100,100,100,100)  
        </script>
    </body>
</html>
练习2. 描边矩形

效果图:

实现代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>绘制一个空心矩形</title>
    </head>
    <body>
        <!--创建一个canvas-->
        <canvas id="myCanvas" width="800" height="800"></canvas>
        <script type="text/javascript">
            //获取canvas
            var myCanvas = document.getElementById("myCanvas");
            //设置canvas的绘图环境
            var oGx = myCanvas.getContext("2d")
            /*
             x坐标为100、
             y坐标为100,
             宽高为100*100
             * */
            oGx.strokeRect(100,100,100,100)
        </script>
    </body>
</html>
3. 清除矩形指定区域

效果图:

实现代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>清除矩形指定区域</title>
    </head>
    <body>
        <!--创建一个canvas-->
        <canvas id="myCanvas" width="800" height="800"></canvas>
        <script type="text/javascript">
            //获取canvas
            var myCanvas = document.getElementById("myCanvas");
            //设置canvas的绘图环境
            var oGx = myCanvas.getContext("2d")
            /*
             x坐标为100、
             y坐标为100,
             宽高为100*100
             * */
            oGx.fillRect(50,50,100,100)  
            //清除指定区域
            oGx.clearRect(50,50,50,50) //清除"x=50,y=50,宽度为50,高度为50的区域"
        </script>
    </body>
</html>

canvas 配色API

方法 描述
fillStyle 填充背景颜色
strokeStyle 设置边框颜色
lineWidth 设置边框的宽度
练习1. 红色填充矩形

效果图:

实现代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>fillStyle</title>
    </head>
    <body>
        <!--创建一个canvas-->
        <canvas id="myCanvas" width="800" height="800"></canvas>
        <script type="text/javascript">
            //获取canvas
            var myCanvas = document.getElementById("myCanvas");
            //设置canvas的绘图环境
            var oGx = myCanvas.getContext("2d")
            /*
             x坐标为100、
             y坐标为100,
             宽高为100*100
             * */
            //绘制填充的"红色"的矩形
            oGx.fillStyle = "red";
            oGx.fillRect(50,50,100,100);
        </script>
    </body>
</html>
练习2. 红色描边矩形

效果图:

实现代码:


<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>strokeStyle和lineWidth</title>
    </head>
    <body>
        <!--创建一个canvas-->
        <canvas id="myCanvas" width="800" height="800"></canvas>
        <script type="text/javascript">
            //获取canvas
            var myCanvas = document.getElementById("myCanvas");
            //设置canvas的绘图环境
            var oGx = myCanvas.getContext("2d")
            /*
             x坐标为100、
             y坐标为100,
             宽高为100*100
             * */
            //绘制边框为"红色"的线条加粗的矩形
            oGx.strokeStyle = "red";
            oGx.lineWidth = 5
            oGx.strokeRect(50,50,100,100);
        </script>
    </body>
</html>

3. canvas绘制圆形

绘制圆形分为4个步骤:

  1. 开始绘制路径(beginPath)
  2. 创建图像路径
  3. 路径创建完成后,关闭路径
  4. 设定绘制样式,调用绘制方法,绘制路径(closePtah)

绘制圆形,canvas也为我们提供了arc这个方法

ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise)

该方法的6个参数分别代表:

  • x为绘制圆形的起点横坐标
  • y表示绘制圆形的起点的纵坐标
  • radius表示圆的半径
  • startAngle为开始角度
  • endAngle为结束的角度
  • anticlockwise是否按照顺时针方向进行绘制(默认顺时针true代表),反之false逆时针
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>绘制一个描边圆</title>
    </head>
    <body>
        <!--创建一个canvas-->
        <canvas id="myCanvas" width="800" height="800"></canvas>
        <script type="text/javascript">
            //获取canvas
            var myCanvas = document.getElementById("myCanvas");
            //设置canvas的绘图环境
            var oGx = myCanvas.getContext("2d");
            //开始路径
            oGx.beginPath();
            //x,y坐标为100,半径为50,起始角度为0  结束角为360 顺时针旋转
            oGx.arc(100,100,50,0,360*Math.PI/180,false);
            //绘制线条
            oGx.stroke();
            //结束路径
            oGx.closePath();
        </script>
    </body>
</html>

弧度转换的公式:(degreens * Math.PI/180),绘制圆形默认按照以下的位置进行切换。

4. moveTo()和lineTo()绘制路径

我们可以使用moveTo()和lineTo()绘制直线,或者是自己想要的图形,不局限于矩形。

方法 描述
moveTo(x,y) 不绘制,只是将当前位置移动到新的目标点
lineTo(x,y) 不仅将当前位置移动到新的目标点(x,y),而且在两个坐标之间画一条直线
linejoin 设置两线段连接处所显示的样子。round,bevel,miter
lineCap 线段端点显示的样式
save 保存绘画路径
restore 销毁路径
练习1. 绘制一个三角形
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>三角形</title>
    <style type="text/css">
        body{
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="800" height="400"></canvas>
    <script type="text/javascript">
        var myCanvas = document.getElementById("myCanvas");
        var oGc = myCanvas.getContext("2d");
        oGc.beginPath();
        oGc.moveTo(100,100);
        oGc.lineTo(250,250);
        oGc.closePath();
        oGc.stroke();
        oGc.beginPath();
        oGc.moveTo(400,100);
        oGc.lineTo(250,250);
        oGc.closePath();
        oGc.stroke();
        oGc.beginPath();
        oGc.moveTo(400,100);
        oGc.lineTo(100,100);
        oGc.closePath();
        oGc.stroke();
    </script>
</body>
</html>
练习2. 画板

效果图:

实现代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>图画板</title>
        <style type="text/css">
            .context{
                width: 500px;
                margin: 20px auto;
                border: 5px solid #ddd;
                box-shadow: 2px 2px 4px 4px #ddd;
            }
        </style>
    </head>
    <body>
        <div class="context">
            <canvas id="myCanvas" width="500" height="500"></canvas>
        </div>
        <script type="text/javascript">
            var myCanvas = document.getElementById("myCanvas");
            var ctx = myCanvas.getContext("2d");
            myCanvas.onmousedown = function(e){
//                console.log(e)
                var disX = e.clientX - myCanvas.offsetLeft;
                var disY = e.clientY - myCanvas.offsetTop;
                ctx.moveTo(disX,disY);
                document.onmousemove = function(e){
                    var disX = e.clientX - myCanvas.offsetLeft;
                    var disY = e.clientY - myCanvas.offsetTop;
                    ctx.lineTo(disX,disY);
                    ctx.stroke();
                }
                document.onmouseup = function(){
                    document.onmousedown = null ;
                    document.onmousemove = null ;
                }
            }
        </script>
    </body>
</html>
练习3:运动的小方块

效果图:

代码实现:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>小方块运动</title>
    <style type="text/css">
        body{
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="800" height="400"></canvas>
    <script type="text/javascript">
        var myCanvas = document.getElementById("myCanvas");
        var oGc = myCanvas.getContext("2d");
        var num = 0
        setInterval(function(){
            num++;
            oGc.clearRect(0,0,100*num,100*num)
            oGc.fillRect(num,num,100,100)
        },30)
    </script>
</body>
</html>

练习4. 走动的时钟(基础版,高级版正在路上)

效果图:

代码实现:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>会动的时钟</title>
        <style type="text/css">
            *{
                margin: 0;
                padding: 0;
            }
            .box{
                width: 800px;
                margin: 20px auto;
            }
        </style>
    </head>
    <body>
        <div class="box">
            <canvas id="myCanvas" width="800" height="800"></canvas>
        </div>
        <script type="text/javascript">
            var myCanvas = document.getElementById("myCanvas");
            var oGc = myCanvas.getContext('2d');
            function draw(){
                //获取本地时间
                var oDate = new Date();
                var oHours = oDate.getHours();
                var oMin = oDate.getMinutes();
                var oSec = oDate.getSeconds();
                //计算时间的角度
                var oHoursValue = (-90+oHours*30+oMin/2)*Math.PI/180;
                var oMinValue = (-90+oMin*6)*Math.PI/180;
                var oSecValue = (-90+oSec*6)*Math.PI/180;
                //绘制时钟
                var x = 400;
                var y = 400;
                var r = 400;
                //绘制时钟的刻度
                oGc.save();
                oGc.beginPath();
                for (var i=0;i<60;i++) {
                    oGc.moveTo(x,y);
                    oGc.arc(x,y,r,6*i*Math.PI/180,6*(i+1)*Math.PI/180)
                }
                oGc.closePath();
                oGc.stroke();
                oGc.restore();
                //绘制第一个填充的大圆
                oGc.save();
                oGc.beginPath();
                oGc.fillStyle = "#fff";
                oGc.moveTo(x,y);
                oGc.arc(x,y,r*19/20,0,360*Math.PI/180)
                oGc.closePath();
                oGc.fill();
                oGc.restore();
                //绘制时刻度
                oGc.save();
                oGc.beginPath();
                oGc.lineWidth = 3 ;
                for (var i=0;i<12;i++) {
                    oGc.moveTo(x,y);
                    oGc.arc(x,y,r,30*i*Math.PI/180,30*(i+1)*Math.PI/180)
                }
                oGc.closePath();
                oGc.stroke();
                oGc.restore();
                //第二个填充圆
                oGc.save();
                oGc.beginPath();
                oGc.fillStyle = "#fff";
                oGc.moveTo(x,y);
                oGc.arc(x,y,r*18/20,0,360*Math.PI/180)
                oGc.closePath();
                oGc.fill();
                oGc.restore();
                //时钟
                oGc.save();
                oGc.beginPath();
                oGc.moveTo(x,y);
                oGc.lineWidth = 3 ;
                oGc.strokeStyle = "#1E9FFF";
                oGc.arc(x,y,r*10/20,oHoursValue,oHoursValue);
                oGc.closePath();
                oGc.stroke();
                oGc.restore();
                //分针
                oGc.save();
                oGc.beginPath();
                oGc.moveTo(x,y);
                oGc.lineWidth = 3 ;
                oGc.strokeStyle = "#7FFFD4";
                oGc.arc(x,y,r*12/20,oMinValue,oMinValue);
                oGc.closePath();
                oGc.stroke();
                oGc.restore();
                //秒针
                oGc.save();
                oGc.beginPath();
                oGc.moveTo(x,y);
                oGc.lineWidth = 3 ;
                oGc.strokeStyle = "#761C19";
                oGc.arc(x,y,r*16/20,oSecValue,oSecValue);
                oGc.closePath();
                oGc.stroke();
                oGc.restore();
            }
            setInterval(function(){
                draw()
            },1000)
            draw()
        </script>
    </body>
</html>

总结

以上canvas的基础用法,还有更高级的有待研究。欢迎大家一起交流学习。