好玩的Canvas:直线(线段)、图形的绘制

Canvas
在Canvas中有直线和曲线两种基本图形。本文将讲述Canvas直线图形的绘制,并详细讲述直线、矩形、多边形这三种常见直线图形的绘制。

Canvas坐标系介绍

W3C坐标系

数学坐标系(笛卡尔坐标系)常在数学中运用,而在前端开发中CSS3、Canvas、SVG等使用的都是W3C坐标系,这一点需要时刻谨记。

  • 数学坐标系:y轴正方向朝上;
  • W3C坐标系:y轴正方向朝下;

绘制直线(线段)

绘制一条线段

在Canvas中,moveTo()和lineTo()这两个方法配合使用来绘制线段。

canvas绘制直线

下面这个示例绘制了上面坐标系中的线段AB,代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Canvas绘制直线</title>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border: 0.0625rem;"></canvas>
    </body>
    <script>
        function get_dom(id){
            return document.getElementById(id);
        }
        window.onload = function(){
            var canvas = get_dom("canvas");
            var cxt = canvas.getContext("2d");
            cxt.moveTo(80,20);
            cxt.lineTo(20,60);
            cxt.stroke();
        }
    </script>
</html>

我们在纸上画一条线段一般都是先找个起始点,然后确定终点,最后连接两个端点,canvas也是这样。

首先使用getContext('2d')获取上下文环境对象context。然后使用moveTo()将画笔移到坐标A(80,20)moveTo()的含义是“将画笔移到该点(x1, y1)位置上,然后开始绘图”。再使用lineTo()将画笔从起点A画到终点坐标B(20,60)

如果是在纸上画,这样就已经结束了,但是在Canvas中,moveTo()lineTo()仅仅是确定线段的“起点坐标”和“终点坐标”这两个状态,但是实际上画笔还没开始“动”。因此我们还需要调用上下文对象的stroke()方法保存状态。

绘制多条线段

使用moveTo()lineTo()可以画一条线段,如果我们要同时画多条直线,也是使用这两个方法。lineTo()方法是可以重复使用的,第一次使用lineTo()后,画笔将自动移到终点坐标位置,第二次使用lineTo()后,Canvas会以“上一个终点坐标”作为第二次绘制的起点坐标,然后再开始画线段,以此类推。如果第二条直线需要用一个新的起点,使用moveTo()方法移动画笔即可。
Canvas绘制多条直线

下面是一个示例,绘制上面图片里的三个线段,代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Canvas绘制直线</title>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border: 0.0625rem;"></canvas>
    </body>
    <script>
        function get_dom(id){
            return document.getElementById(id);
        }
        window.onload = function(){
            var canvas = get_dom("canvas");
            var cxt = canvas.getContext("2d");
            cxt.moveTo(80,20);
            cxt.lineTo(20,60);
            cxt.lineTo(80,120);
            cxt.moveTo(20,80);
            cxt.lineTo(80,140)
            cxt.stroke();
        }
    </script>
</html>

所以如果使用Canvas绘制三角形、四边形等多边形就很简单了,绘制首尾相连的多边形即可,下面是一个绘制正方向的示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Canvas绘制直线</title>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border: 0.0625rem;"></canvas>
    </body>
    <script>
        function get_dom(id){
            return document.getElementById(id);
        }
        window.onload = function(){
            var canvas = get_dom("canvas");
            var cxt = canvas.getContext("2d");
            cxt.moveTo(20,20);
            cxt.lineTo(20,60);
            cxt.lineTo(60,60);
            cxt.lineTo(60,20);
            cxt.lineTo(20,20);
            cxt.stroke();
        }
    </script>
</html>

效果如下:

canvas绘制正方形

Canvas中的矩形绘制

前面使用moveTo()lineTo()这两个方法的配合使用绘制了一个正方形。通过画4条线段来绘制正方形代码过于繁琐,因此在实际开发中一般不采用前面的方法绘制矩形/正方形。

在Canvas中,矩形分为描边矩形和填充矩形这两种,而且提供了单独的方法,直接调用即可。

描边矩形

strokeStyle属性和strokeRect()方法配合使用来绘制描边矩形。strokeStyle是context对象的一个属性,strokeRect()是content对象的一个方法。

strokeStyle属性值

cxt.strokeStyle = "属性值";

strokeStyle属性取值有三种,即颜色值、渐变色、图案。
颜色值支持十六进制颜色值、颜色关键字、rgb颜色值、rgba颜色值。颜色值默认为#000000。渐变色和图案暂时不说。

strokeRect()方法

cxt.strokeRect(x,y,width,height);

这段代码对应下图所示:

image

注意
strokeStyle属性必须在strokeRect()方法之前定义,否则strokeStyle属性无效。

下面用strokeStylestrokeRect重新绘制前面的正方形,并设置边为绿色,代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Canvas绘制直线</title>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border: 0.0625rem;"></canvas>
    </body>
    <script>
        function get_dom(id){
            return document.getElementById(id);
        }
        window.onload = function(){
            var canvas = get_dom("canvas");
            var cxt = canvas.getContext("2d");
            cxt.strokeStyle="green";
            cxt.strokeRect(20,20,40,40);
        }
    </script>
</html>

效果如下:

image

填充矩形

在Canvas中,用fillStyle属性和fillRect()方法配合使用来画填充矩形。

fillStyle属性值

fillStyle属性跟strokeStyle属性一样,取值也有颜色值、渐变色、图案。

cxt.fillStyle="属性值"

fillRect()方法

cxt.fillRect(x,y,width,height);

fillRect()方法和strokeRect()的各参数意思一样。

注意:fillStyle必须在fillRect()之前设置。
下面将前面的正方形用填充矩形重新绘制,填充色为绿色,代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Canvas绘制直线</title>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border: 0.0625rem;"></canvas>
    </body>
    <script>
        function get_dom(id){
            return document.getElementById(id);
        }
        window.onload = function(){
            var canvas = get_dom("canvas");
            var cxt = canvas.getContext("2d");
            cxt.fillStyle="green";
            cxt.fillRect(20,20,40,40);
        }
    </script>
</html>

效果如下:

image

当然填充矩形和描边矩形也可以一起使用,下面是一个代码示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Canvas绘制直线</title>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border: 0.0625rem;"></canvas>
    </body>
    <script>
        function get_dom(id){
            return document.getElementById(id);
        }
        window.onload = function(){
            var canvas = get_dom("canvas");
            var cxt = canvas.getContext("2d");

            cxt.fillStyle="black";
            cxt.fillRect(20,20,40,40);

            cxt.fillStyle="green";
            cxt.fillRect(20,20,40,40);

            cxt.fillStyle="black";
            cxt.fillRect(50,50,40,40);
        }
    </script>
</html>

效果如下:

image

rect()方法直接绘制矩形

在Canvas,除了使用strokeRect()fillRect()可以绘制矩形外,使用rect()方法也可以绘制矩形。

cxt.rect(x,y,width,height);

rect()+stroke()

cxt.strokeStyle = "green";
cxt.rect(20,20,40,40);
cxt.stroke();

效果等同于:

cxt.strokeStyle="green";
cxt.strokeRect(20,20,40,40);

rect()+fill()

cxt.fillStyle = "green";
cxt.rect(20,20,40,40);
cxt.fill();

效果等同于:

cxt.fillStyle="green";
cxt.fillRect(20,20,40,40);

clearRect()方法清空矩形区域

在Canvas中,clearRect()方法用来清空矩形区域。

cxt.clearRect(x,y,width,height);

一个简单示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Canvas绘制直线</title>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border: 0.0625rem;"></canvas>
    </body>
    <script>
        function get_dom(id){
            return document.getElementById(id);
        }
        window.onload = function(){
            var canvas = get_dom("canvas");
            var cxt = canvas.getContext("2d");

            cxt.fillStyle="black";
            cxt.fillRect(20,20,40,40);

            cxt.fillStyle="green";
            cxt.fillRect(20,20,40,40);

            cxt.fillStyle="black";
            cxt.fillRect(50,50,40,40);

            cxt.clearRect(25,25,15,15);
        }
    </script>
</html>

效果如下:
image

cxt.clearRect(0, 0, canvas.width, canvas.height);

上面这段代码用于清空整个Canvas画布。canvas.width获取Canvas画布宽度,canvas.height表示获取Canvas画布的高度(canvas是指上述代码示例中用document.getElementById(id)获取的canvas对象)。

Canvas绘制正多变形

前面绘制了正方形,理论上任意正多边形都可以绘制出来,
正多边形绘制推导

依次类推,可以推导正n边形各坐标点,下面是代码示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Canvas绘制直线</title>
    </head>
    <body>
        <canvas id="canvas" width="800" height="800" style="border: 0.0625rem;"></canvas>
    </body>
    <script>
        function get_dom(id){
            return document.getElementById(id);
        }
        // 绘制多边形函数
        // cxt : context上下文对象,
        // x0,y0 : 正多边形中心坐标点,即(x0,y0)
        // n :正n边形
        // size: 边长
        function create_n(cxt,x0,y0,n,size){
            cxt.beginPath();
            var jd = 2*Math.PI/n;
            for (var i=0;i<n;i++) {
                var x = Math.cos(i*jd)*size+x0;
                var y = Math.sin(i*jd)*size+y0;
                console.log(x,y)
                cxt.lineTo(x,y);
            }
            cxt.closePath();
        }
        window.onload = function(){
            var canvas = get_dom("canvas");
            var cxt = canvas.getContext("2d");
            // 绘制中心点O(100,100),边长为50的正八边形
            create_n(cxt,100,100,8,50);
            cxt.stroke();
        }
    </script>
</html>

效果如下:
image

同理还可以用这些绘制五角星、六芒星等,绘制之前在纸上计算清楚。

总结

利用Canvas可以绘制各种常见的几何图形,可以深入学习。

© 版权声明
THE END
请我喝怡宝
点赞1
分享
评论 共7条
    • 人间不值得
    • 伍子蛇0

      我也写了一篇canvas的类似文章,欢迎过来吐槽,我写完正n边形,来看了看你写的,发现你写错了,边长size没有计算

      5月前回复
      • 人间不值得
        PM小凯哥0

        刚刚看了一下,边长size计算了,边长乘以余弦函数就是x方向偏移,再加上中心点x轴坐标x0就是正n边形x轴坐标点,y轴同理

        • 人间不值得
          伍子蛇0

          你不妨以正三角形简单的带入计算一下,你会发现数值是不对的

        • 人间不值得
          伍子蛇1

          我的意思是,确实画出了正n边形,但是边长不是入参size

          • 发现了,笔误,这个size应该是中心点到端点的距离,换算成边长也很简单。感谢指出错误。

    • 人间不值得
    • 伍子蛇0

      写得好!(只写三个字还不能发表

      5月前回复