边实践边学习Html5中的Canvas之平面图形绘制

举报
lwq1228 发表于 2021/08/06 10:08:52 2021/08/06
【摘要】 边实践边学习Html5中的Canvas之平面图形绘制

1、Canvas是什么

1.1、Canvas简介

在HTML5之前,为了使页面更加绚丽多彩,我们很多情况下都是借助“图片”来实现。不过,使用图片这种方式,都是以“低性能”为代价的。因为图片体积大、下载速度慢等。为了应对日渐复杂的Web应用开发,W3C在HTML5标准中引入了Canvas这一门技术。Canvas,又称“画布”,是HTML5的核心技术之一。HTML5新增了一个Canvas元素,我们常说的Canvas技术,指的就是使用Canvas元素结合JavaScript来绘制各种图形的技术。既然Canvas是HTML5核心技术,那它都有哪些厉害之处呢?

  1. 绘制图形:Canvas可以用来绘制各种基本图形,如矩形、曲线、圆等,也可以绘制各种复杂绚丽的图形;
  2. 绘制图表:Canvas可以绘制满足各种需求的图表;
  3. 动画效果:使用Canvas,我们也可以制作各种华丽的动画效果;
  4. 游戏开发:游戏开发在HTML5领域具有举足轻重的地位,现在我们也可以使用Canvas来开发各种游戏。

1.2、Canvas与SVG

HTML5有两个主要的2D图形技术:Canvas和SVG。事实上,Canvas和SVG是两门完全不同的技术,两者具有以下区别:

  • Canvas是使用JavaScript动态生成的,SVG是使用XML静态描述的。
  • Canvas是基于“位图”的,适用于像素处理和动态渲染,图形放大会影响质量;SVG是基于“矢量”的,图形放大不会影响质量。也就是说,使用Canvas绘制出来的是一个“位图”,而使用SVG绘制出来的是一个“矢量图”。
  • 每次发生修改,Canvas需要重绘,而SVG不需要重绘。
  • Canvas与SVG的关系,简单来说就像“美术与几何”的关系一样。

1.3、Canvas使用

简单来说,HTML5 Canvas就是一门使用JavaScript来操作Canvas元素的技术。使用Canvas元素来绘制图形,需要以下3步:

  1. 获取Canvas对象;
  2. 获取上下文环境对象Context;
  3. 开始绘制图形。

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.moveTo(100, 200);
            cxt.lineTo(300, 100);
            cxt.stroke();
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

说明:

在Canvas中,我们使用document.getElementById()方法来获取Canvas对象(这是一个DOM对象),然后使用Canvas对象的getContext(“2d”)方法获取上下文环境对象Context,最后使用Context对象的属性和方法来绘制各种图形。

1.4、Canvas元素

Canvas是一个行内块元素,我们一般需要指定其3个属性:id、width和height。width和height分别定义Canvas的宽度和高度。默认情况下,Canvas的宽度为300px,高度为150px。对于Canvas的宽度和高度,我们有两种方法来定义:在HTML属性中定义;在CSS样式中定义。但是在实际开发中,我们一定不要在CSS样式中定义,而是应该在HTML属性中定义。下面举例说明为什么不能在CSS样式定义Canvas的宽度和高度:

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            width: 400px;
            height: 300px;
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取canvas宽度和高度
            var str = "canvas的宽度为:" + cnv.width + ",高度为:" + cnv.height;
            alert(str);
        }
    </script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>

效果图:

说明:

从这个例子中我们可以看出:如果在CSS样式中定义,我们使用Canvas对象获取到的是宽度和高度的默认值,而不是实际的宽度和高度,这样我们就无法获取Canvas对象正确的宽度和高度。因此对于Canvas的宽度和高度,我们一定要在HTML属性中定义,而不是在CSS样式中定义。

1.5、Canvas对象

在Canvas中,我们使用document.getElementById()来获取Canvas对象。Canvas对象常用的属性和方法如下表:

属性 说明 方法 说明
width Canvas的宽度 getContext(“2d”) 获取Canvas2D上下文环境对象
height Canvas的高度 toDataURL() 获取Canvas对象产生的位图的字符串

也就是说,我们可以使用cnv.width和cnv.height分别获取Canvas的宽度和高度,可以使用cnv.getContext(“2d”)来获取Canvas 2D上下文环境对象,也可以使用toDataURL()来获取Canvas对象产生的位图的字符串。在这里,cnv指的是Canvas对象。

2、直线

2.1、Canvas坐标系

在使用Canvas之前,我们先来介绍一下Canvas使用的坐标系。了解Canvas使用的坐标系,是使用Canvas的最基本的前提。我们经常见到的坐标系是数学坐标系,不过Canvas使用的坐标系是W3C坐标系,这两种坐标系唯一的区别在于y轴正方向的不同,如下图所示。

  • 数学坐标系:y轴正方向向上。

  • W3C坐标系:y轴正方向向下。

2.2、直线的绘制

2.2.1、一条直线

在Canvas中,我们可以配合使用moveTo()和lineTo()这两个方法来画直线。利用这两个方法,我们可以画一条直线,也可以同时画多条直线。

语法:

cxt.moveTo(x1, y1);
cxt.lineTo(x2, y2);
cxt.stroke();

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.moveTo(100, 200);
            cxt.lineTo(300, 100);
            cxt.stroke();
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

说明:

cxt表示上下文环境对象Context。(x1,y1)表示直线“起点”的坐标。moveTo的含义是“将画笔移到该点(x1,y1)位置上,然后开始绘图”。(x2,y2)表示直线“终点”的坐标。lineTo的含义是“从起点(x1,y1)开始画直线,一直画到终点坐标(x2,y2)”。cxt.moveTo(x1, y1);cxt.lineTo(x2, y2);两句代码仅仅是确定直线的“起点坐标”和“终点坐标”这两个状态,但是实际上画笔还没开始“动”。因此,我们还需要调用上下文对象的stroke()方法才有效。

2.2.2、多条直线

从上面我们知道,使用moveTo()和lineTo()这两个方法可以画一条直线。其实,如果我们想要同时画多条直线,也是使用这两个方法。

语法:

cxt.moveTo(x1, y1);
cxt.lineTo(x2, y2);
cxt.lineTo(x3, y3);
......
cxt.stroke();

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.moveTo(100, 100);
            cxt.lineTo(100, 200);
            cxt.lineTo(300, 200);
            cxt.lineTo(300, 100);
            cxt.lineTo(100, 100);
            cxt.stroke();
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

说明:

lineTo()方法是可以重复使用的。第1次使用lineTo()后,画笔将自动移到终点坐标位置,第2次使用lineTo()后,Canvas会以“上一个终点坐标”作为第2次调用的起点坐标,然后再开始画直线。

3、矩形

从2.2.2可以知道,我们可以配合使用moveTo()和lineTo()来画一个矩形。但是这种画矩形的方法代码量过多,因此在实际开发中并不推荐使用。对于绘制矩形,Canvas另外为我们提供了独立的方法来实现。在Canvas中,矩形分为两种:一种是“描边矩形”,另一种是“填充矩形”。

3.1、描边矩形

在Canvas中,我们可以配合使用strokeStyle属性和strokeRect()方法来画一个描边矩形。

语法:

cxt.strokeStyle = 属性值;
cxt.strokeRect(x, y, width, height);

strokeStyle是Context对象的一个属性,strokeRect()是Context对象的一个方法。

1、strokeStyle属性:

strokeStyle属性取值有3种:颜色值、渐变色和图案。strokeStyle取值为颜色值的几种情况如下:

//十六进制颜色值
cxt.strokeStyle = "#FFO000";
//颜色关键字
cxt.strokeStyle = "red";
//rgb颜色值
cxt.strokeStyle = "rgb(255,0,0)";
//rgba颜色值
cxt.strokeStyle = "rgba(255,0,0,0.8)";

2、strokeRect(x, y, width, height)方法:

strokeRect()方法用于确定矩形的坐标,其中x和y为矩形左上角的坐标,width表示矩形的宽度,height表示矩形的高度。我们还要特别注意一点,strokeStyle属性必须在strokeRect()方法之前定义,否则strokeStyle属性无效。

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.strokeStyle = "red";
            cxt.strokeRect(100, 100, 200, 100);
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

3.2、填充矩形

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

语法:

cxt.fillStyle = 属性值;
cxt.fillRect(x, y, width, height);

fillStyle是Context对象的一个属性,fillRect()是Context对象的一个方法。

1、fillStyle属性:

fillStyle属性取值有3种:颜色值、渐变色和图案。fillStyle取值为颜色值的几种情况如下:

//十六进制颜色值
cxt.fillStyle = "#FFO000";
//颜色关键字
cxt.fillStyle = "red";
//rgb颜色值
cxt.fillStyle = "rgb(255,0,0)";
//rgba颜色值
cxt.fillStyle = "rgba(255,0,0,0.8)";

2、fillRect(x, y, width, height)方法:

fillRect()方法用于确定矩形的坐标,其中x和y为矩形左上角的坐标,width表示矩形的宽度,height表示矩形的高度。我们还要特别注意一点,fillStyle属性必须在fillRect()方法之前定义,否则fillStyle属性无效。

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.fillStyle = "red";
            cxt.fillRect(100, 100, 200, 100);
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

3.3、rect()方法

在Canvas中,如果想要绘制一个矩形,除了使用strokeRect()和fillRect()这两个方法之外,我们还可以使用rect()方法。

语法:

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

x和y为矩形左上角的坐标,width表示矩形的宽度,height表示矩形的高度。

举例1-用rect绘制描边矩形:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.strokeStyle = "blue";
            cxt.rect(100, 100, 200, 100);
            cxt.stroke();
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

举例2-用rect绘制填充矩形:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.fillStyle = "blue";
            cxt.rect(100, 100, 200, 100);
            cxt.fill();
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

说明:

strokeRect()、fillRect()和rect()都可以画矩形。这3种方法的参数是相同的,不同之处在于实现效果方面。其中,strokeRect()和fillRect()方法在调用之后,会立即把矩形绘制出来。而rect()方法在调用之后,并不会把矩形绘制出来。只有在使用rect()方法之后再调用stroke()或者fill()方法,才会把矩形绘制出来。

3.4、清空矩形

在Canvas中,我们可以使用clearRect()方法来清空“指定矩形区域”。

语法:

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

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.fillStyle = "green";
            cxt.fillRect(100, 100, 200, 100);
            cxt.clearRect(120, 120, 160, 60);
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

说明:

x和y分别表示清空矩形区域左上角的坐标,width表示矩形的宽度,height表示矩形的高度。

4、多边形

在Canvas中中我们可以配合使用moveTo()和lineTo()来画三角形和矩形。其实多边形也是使用moveTo()和lineTo()这两个方法画出来的。如果想要在Canvas中画多边形,我们需要事先计算出多边形中各个顶点的坐标,然后再使用moveTo()和lineTo()在Canvas中画出来。跟矩形不一样,Canvas没有专门用来绘制三角形和多边形的方法。对于三角形和多边形,我们也是使用moveTo()和lineTo()这两个方法来实现的。

4.1、Canvas绘制箭头

对于箭头,我们都是事先确定箭头的7个顶点坐标,然后使用moveTo()和lineTo()来绘制。

坐标确定如图:

举例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3.开始绘制图形
            cxt.moveTo(80, 110);
            cxt.lineTo(80, 190);
            cxt.lineTo(200, 190);
            cxt.lineTo(200, 230);
            cxt.lineTo(320, 150);
            cxt.lineTo(200, 70);
            cxt.lineTo(200, 110);
            cxt.lineTo(80, 110);
            cxt.stroke();
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

4.2、Canvas绘制正多边形

正多边形在实际开发中也经常见到,要想绘制正多边形,我们首先来了解一下最简单的正多边形——正三角形。正三角形分析图如图所示。

根据正三角形的特点,我们可以封装一个绘制正多边形的函数:createPolygon()。

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #canvas {
            border: 1px dashed gray;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            // 1.获取Canvas对象
            var cnv = document.getElementById("canvas");
            // 2.获取上下文环境对象Context
            var cxt = cnv.getContext("2d");
            // 3、绘制正三角形
            createPolygon(cxt, 3, 200, 150, 100);
            cxt.fillStyle = "yellow";
            cxt.fill();
        }

        /**
         * 绘制正多边形的函数
         * @param cxt Canvas画笔对象
         * @param n 正多边形的边数
         * @param dx 正多边形中心坐标x
         * @param dy 正多边形中心坐标y
         * @param size 正多边形顶点到中心的距离
         */
        function createPolygon(cxt, n, dx, dy, size) {
            cxt.beginPath();
            var degree = (2 * Math.PI) / n;
            for (var i = 0; i < n; i++) {
                var x = Math.cos(i * degree);
                var y = Math.sin(i * degree);
                cxt.lineTo(x * size + dx, y * size + dy);
            }
            cxt.closePath();
        }
    </script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

效果图:

说明:

cxt.beginPath();用于开始一条新路径,cxt.closePath();用于关闭路径。绘制其他正多边形只需修改对应边数和其他参数即可:

// 绘制正n边形
createPolygon(cxt, n, 200, 150, 100);
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。