首页 > 代码库 > 【转】五分钟学会 Canvas 基础(一)

【转】五分钟学会 Canvas 基础(一)

原文:http://www.jianshu.com/p/d9ec1ef9c1e8

0.前言

最近忙里偷闲,来写的这篇文章,但是中午出去吃个饭,回来因为自己的误操作,把上午的文章全删除了,还没法找回。

小编真的是瞬间觉得整个人生都灰暗了。

心塞,这次真的不想多说什么了。

-------------我是华丽的分割线--------------

终于把这篇文章写完了,关于本文,针对读者主要是之前从未接触过 Canvas的同学。当然,你要学 canvas 一定要有 JS 基础啦。

其次就是,因为前前后后耽误了两天时间,可能在书写和描述中出现一些小的纰漏,请各位读者老爷见谅。

最后,也希望这篇文章能够对迷茫的你产生一些帮助,感谢。

1. canvas 简介


1.1 canvas 是什么?

是HTML5中重要的元素,和audio、video元素类似完全不需要任何外部插件就能够运行.

Canvas中文翻译就是”画布”.它提供了强大的图形的处理功能(绘制,变换,像素处理…)。

但是需要注意,canvas 元素本身并不绘制图形,它只是相当于一张空画布。

如果开发者需要向 canvas 上绘制图形,则必须使用 JavaScript 脚本进行绘制。

1.2 canvas 能够做什么?

  • 基础图形的绘制
  • 文字的绘制
  • 图形的变形和图片的合成
  • 图片和视频的处理
  • 动画的实现
  • 小游戏的制作

1.3 支持的浏览器

大多数现代浏览器都是支持Canvas的,比如 Firefox, safari, chrome, opera的最近版本以及IE9都支持.

IE8及以下不支持HTML5,但是我们可以进行提示用户更新到最新的版本

1.4 关于canvas 标签的基本概念

在 HTML 页面上定义 canvas 元素与定义其他普通元素并无任何不同,它吃了可以指定 id, style ,class ,hidden 等通用属性之外,还可以设置 width 和 height 两个属性。

为什么要特意去说这个呢?

咱们在 章节 2.2 中详细去说明。

除此之外,我们在网页中定义 canvas 元素之后,它只是一张空白的画布,想要在画布上绘画,一定要经过下面几步。

  1. 获取 canvas 元素对应的 DOM 对象,这必须是一个 canvas 对象
  2. 调用 canvas 对象的 getContext( ) 方法,该方法返回一个 canvasRenderingContext2D 对象,该对象可以绘制图形。
  3. 调用 canvasRenderingContext2D 对象的方法进行绘图。

那么我们就来开始我们的canvas 实战,来看看 canvas 该如何会绘制图形。

2.canvas 实战


2.1 查看当前浏览器对 canvas 的支持情况

我们在上面也说明了,我们的一些浏览器是不支持 canvas 的,这个时候我们应该怎么去做呢?

这时候我们可以直接在 canvas 标签之间去书写内容,这么做的好处是当你的浏览器不支持 canvas 的时候,我们可以去展示标签之间的内容,具体如下。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title>    <style type="text/css">        html,body{            margin: 0px;        }        canvas{            background: #ccc;        }    </style></head><body>    <canvas>        我们在设置 canvas 之前需要首先监测用户电脑是否支持 canvas    </canvas></body></html>
技术分享

既然已经创建完成了具体的内容,那我们现在可以看见了么?

我们虽然没有给定 canvas 的宽度和高度,但是实际上我们的canvas 在页面中是可见的

需要注意,canvas 默认样式的宽度和高度 是 300px * 150px.

即使我们不去设置具体的宽度和高度,它也是可以显示的。

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css">  html,body{   margin: 0px;  }  canvas{   background: #ccc;  } </style></head><body> <canvas>  我们在设置 canvas 之前需要首先监测用户电脑是否支持 canvas </canvas></body></html>
技术分享
2.png

那我们该如何去修改画布的默认大小呢?

2.2 修改 Canvas 的画布

按照我们正常的思路来说,我们会直接去使用 canvas_1.style.width = "500px"; 来去修改我们的 canvas 的宽度,但是这样真的对么?

答案当然是否定的,canvas 相当于是一张图片,如果我们设置 <canvas width="500" height="500">.

这样写相当于图片的实际大小是 500 * 500.

但是,假如我们这样去书写。

<canvas style="width:500px;height:500px;">

这样实际是把 canvas 默认的 300 150 的图片强行拉伸为 500px 500px 了,所以这样会导致我们的内容被强行缩放,从而导致问题。

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css">  html,body{   margin: 0px;  }  canvas{   background: #ccc;  } </style></head><body> <canvas id="canvas_1">  我们在设置 canvas 之前需要首先监测用户电脑是否支持 canvas </canvas></body><script type="text/javascript"> var canvas_1 = document.getElementById("canvas_1"); // 设置宽度和高度,但是这种写法会造成额外的问题 // 画布会拉伸 // canvas_1.style.width = "500px"; // canvas_1.style.height = "500px"; // 所以推荐写法 // 1.使用内联样式表 // 2.去使用点(.) canvas_1.width = "500"; //注意,不要加 px canvas_1.height = "500";</script></html>

2.3 获取绘制环境

我们在上面已经设置了我们的画布的大小,但是存在一个问题。

我们还没有找到我们的画布呀!~

要是我们连具体的画布都没有,我们又该向哪里去绘画呢?

实际上我们可以通过 var ctx = canvas_1.getContext("2d"); 来去获取到我们的绘制环境。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body>    <canvas id="canvas_1" width="500" height="400" style="box-shadow: 0 0 20px black;">        当前浏览器不支持 canvas    </canvas></body><script type="text/javascript">    // 获取 canvas 元素对应的 DOM 对象    var canvas_1 = document.getElementById("canvas_1");    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象    var ctx = canvas_1.getContext("2d");    // 打印一下,查看是否能够显示具体环境    console.log(ctx);</script></html>

假如打印成功,我们应该可以在浏览器中的 console 中查看到我们的画布具体信息。

技术分享
3.png

但是请注意,getContext("2d"); 中一定是2d而不是2D,否则不会生效。

2.4 绘制的坐标轴

既然我们已经能够获取到我们具体的画布了,那我们是不是开始绘制了呀。

先等等,我们首先先来分析一个问题,就是我们绘制图形的时候,以这个一个区域,我们应该从哪里开始,设置的数值又应该从哪里开始呢?这时候你就应该去想一想,是不是存在这么一个坐标轴,可以根据这个坐标轴来书写我们的数值呢?

技术分享
Paste_Image.png

请注意,横轴向右是正,纵轴向下是正

2.5 绘制直线

我们既然要画一条直线,我们是不是至少应该有这么几个条件呢?

  • 线的起点
  • 线的终点
  • 线的颜色
  • 线的宽度

所以我们接下来,就需要开始我们的代码书写了。

我们该如何去进行绘制呢?

我们需要一些工具,需要具体的方法。

方法说明
beginPath()开始定义路径
closePath()关闭前面定义的路径
moveTo(float x,float y)把 canvas 的当前路径的结束点移动到 x, y 对应的点
lineTo(float x,float y)把 canvas 的当前路径从当前结束点连接到 x , y 对应的点

需要注意,moveTo 可以简单理解为,把当前绘制图像的起点设置为某一特定坐标,而 lineTo 则是将当前的起点和你想要设置的那个点之间连接起来。

而 beginPath 是表示开始定义路径,不会产生特殊的效果。而 closePath 除了表示关闭当前定义的路径之外,还会有一个特殊的作用,就是可以将当前绘制图形的最后一个点和我们绘制图形开始的点进行连接,这一点咱们在章节2.6 中详细去看一下。当然,如果你只需要画一条线,不去加beginPath 和 closep 你的内容实际也是可以出来的,但是推荐加上。

这个时候我们可以来运行一下,看看效果是否能够出来。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body>    <div>        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">            当前浏览器不支持 canvas        </canvas>    </div></body><script type="text/javascript">    // 获取 canvas 元素对应的 DOM 对象    var canvas_1 = document.getElementById("canvas_1");    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象    var ctx = canvas_1.getContext("2d");    // 打印一下,查看是否能够显示具体环境    console.log(ctx);    // 开始绘制    ctx.beginPath();    //设置绘制起点    ctx.moveTo(0,0);    //设置绘制下一个点    ctx.lineTo(700,400);    //结束绘制    ctx.closePath();</script></html>

发现了什么?我们的图形什么都没有出来呀,鹏哥你是不是坑我们呀?

怎么可能,我那么帅气。

效果没出来,只是因为 你已经把你的画笔的颜料,要画什么样的线条,全部都想好了,可是你往你的画布上绘画了么?

没有对吧,所以咯,我们还需要有其他的方法去进行配合。

--
fill()填充 canvas 当前路径
stroke()填充 canvas 当前路径绘制边框

这个时候我们添加上我们的 stroke() 之后,我们就发现我们的线条出现了。

可是这条线一直是灰色的呀,好丑,我们想要自己去修改我们的线,该怎么做呢?

--
fillStyle()设置填充 canvas 路径所使用的填充风格
strokeStyle()设置绘制 canvas 路径的填充风格

他们两个都支持三个属性值。

  1. 符合颜色格式的字符串值,表示使用纯色填充
  2. CanvasGradient,表明使用渐变填充
  3. CanvasPattern,表明使用位图填充

这几个值,咱们在后续的课程中会去详细说明,在当前不去做更多阐述。

除此之外,我们还可以设置一下线的宽度。

--
lineWidth()设置笔触线条的宽度

这样我们就可以画出一些我们想要的线条的样式了。

技术分享
Paste_Image.png

2.6 绘制三角形

我们已经创建了这一条线段,那么我们平常开发中不会仅仅让你去绘制一条线吧,最起码我们需要会绘制出一个小的三角形吧。

这时候我们就需要再去绘制两条线了。

怎么去添加线呢?lineTo对吧。

这个时候我们再去绘制一条线。

    //设置绘制起点    ctx.moveTo(100,100);    //设置绘制下一个点    ctx.lineTo(700,400);    //设置绘制下一个点    ctx.lineTo(400,100);

这时候神奇的事情发生了,我们的三角形直接就出现了,可是我们仅仅绘制了两条线呀。

技术分享
Paste_Image.png

这是因为,我们在绘制图形的时候,是不是设置了一个方法?

还记得上面对 closePath 的描述么?

    //结束绘制    ctx.closePath();

这时因为当我们结束绘制的,电脑会自动将你设置的线段自动连接起来。

技术分享
Paste_Image.png

这个时候我们应该有两个想法了。

  1. 我们可以用这个特性去做一个长方形或者多边形等。

  2. 我们需要给我们的方块内部设置一个颜色。

那么我们首先来说一下,如何设置一个背景颜色。

这时候我们需要使用填充。

    // 设置填充样式    ctx.fillStyle = "green";    // 填充当前视图    ctx.fill();

这个时候我们就能看见,我们的背景颜色就已经成功填充了。

技术分享
Paste_Image.png

当然,我的审美一直很特立独行,所以各位小伙伴也不要在意太多细节啦,科科。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body>    <div>        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">            当前浏览器不支持 canvas        </canvas>    </div></body><script type="text/javascript">    // 获取 canvas 元素对应的 DOM 对象    var canvas_1 = document.getElementById("canvas_1");    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象    var ctx = canvas_1.getContext("2d");    // 打印一下,查看是否能够显示具体环境    console.log(ctx);    // 开始绘制    ctx.beginPath();    //设置绘制起点    ctx.moveTo(100,100);    //设置绘制下一个点    ctx.lineTo(700,400);    //设置绘制下一个点    ctx.lineTo(400,100);    //设置绘制下一个点    ctx.lineTo(600,500);    //结束绘制    ctx.closePath();    //设置线的宽度    ctx.lineWidth = 10;    //设置绘制的样式    ctx.strokeStyle = "red";    //绘制点之间的线路    ctx.stroke();    // 设置填充样式    ctx.fillStyle = "green";    // 填充当前视图    ctx.fill();    // 注意:所有的绘制相应属性全部应该放在 closePath 之前</script></html>

除此之外,还有一个需要注意的点,就是我们现在的图形是不是角度都是非常尖锐的?

那我们是不是可以把这个效果修改一下,改的圆滑一点呢?

这时候再来跟大家说另外一个属性。

--
lineJoin设置返回所创建边角的类型,当两条线交汇时。

通过这个属性,我们就可以去修改我们图形的拐角的样式了,这个样式里面存在三个属性。需要注意一点,你去设置边角的样式,一定要设置在你的绘制矩形框之前,否则效果是不会出现的。

--
bevel创建斜角
round创建圆角
miter默认,创建尖角
技术分享
miter.png
技术分享
round.png
技术分享
bevel.png

这时候我们的效果就已经全部出现了。

那么大家可以去尝试制作一下下图的内容。

技术分享
Paste_Image.png

2.7 绘制矩形

不知道小伙伴们有没有将上面的内容成功设置出来呢?

如果出来了,我们发现一个非常坑爹的情况,他喵的每设置一次都需要专门去计算这个内容的对应数值么?

不能这么坑爹吧,所以这个时候我们要去学习另外一个方法。

--
strokeRect(float x,float y,float width,float height)绘制一个矩形边框
fillRect(float x,float y,float width,float height)填充一个矩形边框

有了这两个方法,我们的矩形绘制就非常方便啦。

那么我们来尝试一下。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body>    <div>        <h2>绘制矩形</h2>        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">            当前浏览器不支持 canvas        </canvas>    </div></body><script type="text/javascript">    // 获取 canvas 元素对应的 DOM 对象    var canvas_1 = document.getElementById("canvas_1");    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象    var ctx = canvas_1.getContext("2d");    // 设置填充颜色    ctx.fillStyle = ‘#f00‘;    // 填充一个矩形    ctx.fillRect(30,20,120,60);    // 设置填充颜色    ctx.fillStyle = ‘#ff0‘;    // 填充一个矩形    ctx.fillRect(80,60,120,60);    // 设置填充颜色    ctx.strokeStyle = ‘#00f‘;    // 填充一个矩形    ctx.strokeRect(30,130,120,60);    // 设置线条宽度    ctx.lineWidth = 20;    // 设置线条宽度    ctx.lineJoin = "round";    // 设置填充颜色    ctx.strokeStyle = ‘#0ff‘;    // 填充一个矩形    ctx.strokeRect(80,160,120,60);    // 设置线条宽度    ctx.lineJoin = "bevel";    // 设置填充颜色    ctx.strokeStyle = ‘#f0f‘;    // 填充一个矩形    ctx.strokeRect(130,190,120,60);    ctx.storke();</script></html>
技术分享
Paste_Image.png

2.8 绘制字符串

我猜现在很多小伙伴都在想,我们可以绘制线条,可以绘制多边形,还可以绘制矩形了,那么接下来是不是要开始学习绘制圆形呢?

当然不是,因为绘制圆形设计到的内容比较多,咱们放在下一篇文章中来书写。

今天咱们就先来看一下,我们该如何去绘制我们的字符串。

在绘制字符串之前同样需要跟大家说这么几个方法。

--
fillText(String Text, float x, float y, [float maxWidth])填充字符串
strokeText(String Text, float x, float y, [float maxWidth])绘制字符串边框

同时我们既然设置了字符串的内容,我们是不是还需要去对我们字符串的对齐方式什么的去做一做设置呢?

--
textAlign设置绘制字符串的水平对齐方式(start、end、left、right、center等)
textBaseAlign设置绘制字符串的垂直对齐方式(top、hanging、middle、alphabetic、idecgraphic、bottom 等)

了解了这些具体的方法,那我们再来看一下,我们该如何去设置我们的字符串内容。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body>    <div>        <h2>绘制文字</h2>        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">            当前浏览器不支持 canvas        </canvas>    </div></body><script type="text/javascript">    // 获取 canvas 元素对应的 DOM 对象    var canvas_1 = document.getElementById("canvas_1");    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象    var ctx = canvas_1.getContext("2d");    ctx.fillStyle = ‘#00f‘;    ctx.font = ‘italic 50px 隶书‘;    ctx.textBaseline = ‘top‘;    //填充字符串    ctx.fillText(‘李先生真是帅‘,0,0);    ctx.strokeStyle = ‘f0f‘;    ctx.font = ‘bold 45px 宋体‘;    // 绘制字符串的边框    ctx.strokeText(‘李鹏李鹏我爱你‘,0,50,200);</script></html>
技术分享
Paste_Image.png

2.9 设置阴影

我们在之前学习 HTML 的过程中,跟大家说过,我们的阴影可以简单分为两种,盒阴影和文字阴影,那在我们的画布中,是否也存在这么一个东西,能够为我们的文字去设置一个阴影呢?

当然有,要不我也不会专门去提这个事情,对吧。

我们学习设置阴影,同样要使用这么几个属性。

--
shadowBlur设置阴影的模糊程度。该值是一个浮点数,该数值越大,阴影的模糊程度也就越大。
shadowColor设置阴影的颜色。
shadowOffsetX设置阴影在 X 方向的偏移
shadowOffsetY设置阴影在 Y 方向的偏移

那么我们接下来,一起来看看我们该如何去设置阴影。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body>    <div>        <h2>绘制文字</h2>        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">            当前浏览器不支持 canvas        </canvas>    </div></body><script type="text/javascript">    // 获取 canvas 元素对应的 DOM 对象    var canvas_1 = document.getElementById("canvas_1");    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象    var ctx = canvas_1.getContext("2d");    // 设置阴影的模糊程度    ctx.shadowBlur = 5.6;    // 设置阴影的颜色    ctx.shadowColor = ‘#222‘;    // 设置阴影在 X,Y 方向的偏移    ctx.shadowOffsetX = 10;    ctx.shadowOffsetY = -6;    ctx.fillStyle = ‘#00f‘;    ctx.font = ‘italic 50px 隶书‘;    ctx.textBaseline = ‘top‘;    //填充字符串    ctx.fillText(‘李先生真是帅‘,0,0);    ctx.strokeStyle = ‘f0f‘;    ctx.font = ‘bold 45px 宋体‘;    // 绘制字符串的边框    ctx.strokeText(‘李鹏李鹏我爱你‘,0,50,200);</script></html>
技术分享
Paste_Image.png

怎么样?今天我教给大家的知识点都学会了么?

如果在学习中关于这篇文字有任何问题,欢迎浏览联系。

最后是国际惯例,撒泼打滚求点赞,求分享啦!~

李鹏
2016年07月14日11:41:34

【转】五分钟学会 Canvas 基础(一)