前言

在早期web端的动画、广告、游戏等基本上都是使用Flash来实现的,要在网页上播放Flash需要一堆代码和插件,因此Flash的使用上比较复杂,还会给开发者带来一堆麻烦。 自从HTML5提供 Canvas 标签以来它就彻底颠覆了Flash的地位,到如今Flash基本已经淡出了人们的视线。那究竟canvas 强在何处呢?接下来我们将深入了解一下。

Canvas 概述

从翻译其实就能很好的了解到 canvas 是用来干什么的。画布!很好理解就是用来画画的。那具体怎么“画”咱们就得看一下具体的 API 文档了。下面是对 canvas 的一些概述:

  • canvas 是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素.
  • Canvas API 提供了一个通过JavaScript 和 HTML的Canvas元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。
  • Canvas API 主要聚焦于2D图形。而同样使用Canvas元素的 WebGL API 则用于绘制硬件加速的2D和3D图形。

Canvas使用

Canvas 最早是由 Apple 引入 WebKit,用于Mac OS X 的 Dashboard,随后被各个浏览器实现。如今除一些过时的浏览器不支持Canvas元素外,所有的新版本主流浏览器都支持它。

Canvas元素的学习需要具备一些基本的HTML和JavaScript知识。

基本用法

下面我们来简单创建一个例子,看看canvas究竟如何使用。

<!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>canvas 基本使用</title>
</head>
<body><canvas width="200" height="200">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas>
</body>
</html>
复制代码

上面代码就是一个基本的使用Canvas标签的例子。可以看到我们为它设置了宽和高,还在 Canvas标签内部给出一个提示文案。在这里需要说明一下:

  • Canvas标签的默认大小为:300 x 150 (像素),而这里咱们设置为了:200 x 200(像素)。
  • Canvas标签中的文字是在不支持Canvas标签的浏览器中使用的,因为支持Canvas标签的浏览器会忽略容器中包含的内容正常渲染Canvas标签,而不支持Canvas标签的浏览器则相反,浏览器会忽略容器而显示其中的内容。

可以看一下上面代码在浏览器上的展示样式:

渲染上下文

Canvas标签起初只是创造了一个固定大小的画布,它公开了一个或多个渲染上下文,而我们想对它进行绘制就需要找到渲染上下文。

Canvas标签提供了一个方法叫:getContext() ,通过它我们可以获得渲染上下文和绘画功能。简单写个例子:

<!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>canvas 基本使用</title>
</head>
<body><canvas id="canvas" width="200" height="200">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');}</script>
</body>
</html>
复制代码

这里需要注意一点,getContext方法是有一个接收参数,它是绘图上下文的类型,可能的参数有:

  • 2d:建立一个二维渲染上下文。这种情况可以用 CanvasRenderingContext2D()来替换getContext('2d')。
  • webgl(或 experimental-webgl): 创建一个 WebGLRenderingContext 三维渲染上下文对象。只在实现WebGL 版本1(OpenGL ES 2.0)的浏览器上可用。
  • webgl2(或 experimental-webgl2):创建一个 WebGL2RenderingContext 三维渲染上下文对象。只在实现 WebGL 版本2 (OpenGL ES 3.0)的浏览器上可用。
  • bitmaprenderer:创建一个只提供将canvas内容替换为指定ImageBitmap功能的ImageBitmapRenderingContext。

绘制形状

在我们获得绘制上下文以后,就可以根据绘制上下文开始绘制一些基本的形状,比如:直线、三角形、矩形、圆弧和圆。接下来咱们具体实现一下。

直线

绘制直线咱们需要了解三个函数:

moveTo(x, y)

设置初始位置,参数为初始位置x和y的坐标点

lineTo(x, y)

绘制一条从初始位置到指定位置的直线,参数为指定位置x和y的坐标点

stroke()

通过线条来绘制图形轮廓

接下里咱们应用上面的三个函数来试着绘制一条直线,代码如下:

<!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>canvas - 绘制直线</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一条从起点(x: 50, y:50)到 另一个点(x: 200, y:200)的直线ctx.moveTo(50, 50);ctx.lineTo(200, 200);ctx.stroke();}</script>
</body>
</html>
复制代码

为了展示的效果好一点,这里我调整了一下画布的大小:500 x 500,还给画布添加了一个阴影和圆角。得到的直线如图:

三角形

知道了如何绘制一条直线,那么绘制三角形也就不难了,咱们只需要画三条直线拼在一起就是一个三角形了,代码如下:

<!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>canvas - 绘制三角形</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一个三角形ctx.moveTo(50, 50);ctx.lineTo(200, 200);ctx.lineTo(200, 50);ctx.lineTo(50, 50);ctx.stroke();}</script>
</body>
</html>
复制代码

具体效果如下:

矩形

知道了三角形的绘制,那么矩形的绘制是不是也用直线来拼凑呢?答案是否定的,矩形虽然可以用四条直线来拼凑成,但那样太复杂了,Canvas API 给提供了三种绘制矩形的方法:

  • strokeRect(x, y, width, height) 绘制一个矩形的边框
  • fillRect(x, y, width, height) 绘制一个填充的矩形
  • clearRect(x, y, width, height) 清除指定矩形区域,让清除部分完全透明。

下面我们依次看一下他们有什么异同。

strokeRect

strokeRect(x, y, width, height) 是用来绘制一个矩形的边框,x和y 是矩形的起点坐标,width和height 是矩形的宽高。举个例子,代码如下:

<!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>canvas - 绘制矩形</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一个矩形边框ctx.strokeRect(50, 50, 200, 100);}</script>
</body>
</html>
复制代码

如下图,strokeRect方法绘制的就是一个矩形框:

fillRect

fillRect(x, y, width, height) 绘制一个填充的矩形,x和y 是矩形的起点坐标,width和height 是矩形的宽高。举个例子,代码如下:

<!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>canvas - 绘制矩形</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一个填充矩形ctx.fillRect(100, 100, 200, 100);}</script>
</body>
</html>
复制代码

如下图,fillRect方法实现的是填充了一个矩形:

clearRect

clearRect(x, y, width, height) 清除指定矩形区域,让清除部分完全透明,x和y 是矩形的起点坐标,width和height 是矩形的宽高。这里需要结合结合另外两种画法来对比一下,才能看出具体的效果,代码如下:

<!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>canvas - 绘制矩形</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一个填充矩形ctx.fillRect(100, 100, 200, 100);ctx.fillRect(50, 50, 200, 100);ctx.clearRect(75, 75, 100, 70);}</script>
</body>
</html>
复制代码

如下图,中间白色的矩形就是被指定清除的区域:

圆弧和圆

绘制圆弧或者圆,使用的方法是:arc(x, y, radius, startAngle, endAngle, anticlockwise)。x和Y为圆心的坐标,radius为半径,startAngle为圆弧或圆的开始位置,endAngle为圆弧或圆的结束位置,anticlockwise是绘制的方向(不写默认为false,从顺时针方向)。

下面画一个半圆弧看看效果,代码如下:

<!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>canvas - 绘制圆弧</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一段圆弧ctx.arc(60, 60, 50, 0, Math.PI, false);ctx.stroke();}</script>
</body>
</html>
复制代码

效果如下图:

这里需要注意的是:在画弧的时候,arc()函数中角的单位是弧度而不是角度。角度换算为弧度的表达式为:弧度=(Math.PI/180)*角度。

所以想要画一个圆的弧度就是:Math.PI*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>canvas - 绘制圆弧</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一段圆弧ctx.arc(60, 60, 50, 0, Math.PI, false);ctx.stroke();// 绘制一个圆弧ctx.arc(200, 60, 50, 0, Math.PI*2, false);ctx.stroke();}</script>
</body>
</html>
复制代码

但效果似乎不想我们想象的一样,如下图:

如上图所示,先画的半圆弧和后画的圆弧被连在了一起,其实这是因为在咱们每次新建路径的时候都需要开启和闭合路径,这样不同路径之间才不会相互干扰。下面咱们就来介绍一下如何开启和闭合路径。

beginPath

新建一条路径,生成之后,图形绘制命令被指向到路径上。

closePath

闭合路径之后图形绘制命令又重新指向到上下文中。 具体怎么使用这两个函数呢?下面咱们介绍一下,直接上代码:

<!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>canvas - 绘制圆弧</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一段圆弧ctx.beginPath() // 开启路径ctx.arc(60, 60, 50, 0, Math.PI, false);ctx.stroke();ctx.closePath() // 闭合路径// 绘制一个圆弧ctx.beginPath() // 开启路径ctx.arc(200, 60, 50, 0, Math.PI*2, false);ctx.stroke();ctx.closePath() // 闭合路径}</script>
</body>
</html>
复制代码

如上代码,咱们为每一条路径都设置了开启和闭合。那么看一下效果如何:

这里有一点需要说明一下,其实在咱们开启和关闭路径的时候,关闭路径其实并不是必须的,对于新路径其实每次都开启新路径就ok。

以上其实都是通过stroke方法来做描边,那么如果想填充有没有对应的方法呢?

fill

stroke方法是通过线条来绘制图形轮廓,而fill方法则是通过填充路径的内容区域生成实心的图形。

具体如何使用举个例子看一下。代码如下:

<!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>canvas - 填充</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一段圆弧ctx.beginPath() // 开启路径ctx.arc(60, 60, 50, 0, Math.PI, false);ctx.stroke();// 绘制一个圆弧ctx.beginPath() // 开启路径ctx.arc(200, 60, 50, 0, Math.PI*2, false);ctx.stroke();// 填充一个四分之一圆弧ctx.beginPath() // 开启路径ctx.arc(60, 200, 50, 0, Math.PI/2, false);ctx.fill();// 填充一个半圆弧ctx.beginPath() // 开启路径ctx.arc(200, 200, 50, 0, Math.PI, false);ctx.fill();// 填充一个圆弧ctx.beginPath() // 开启路径ctx.arc(350, 200, 50, 0, Math.PI*2, false);ctx.fill();}</script>
</body>
</html>
复制代码

效果如下图:

椭圆

添加椭圆路径。

语法:ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)

  • x、y:椭圆的圆心位置
  • radiusX、radiusY:x轴和y轴的半径
  • rotation:椭圆的旋转角度,以弧度表示
  • startAngle:开始绘制点
  • endAngle:结束绘制点
  • anticlockwise:绘制的方向(默认顺时针),可选参数。

举个例子看一下:

<!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>canvas - 裁剪</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');ctx.beginPath();ctx.ellipse(100, 150, 50, 100, 0, 0, 2 * Math.PI);ctx.stroke();ctx.beginPath();ctx.ellipse(400, 150, 50, 100, 0, 0, 2 * Math.PI);ctx.stroke();ctx.beginPath();ctx.ellipse(250, 350, 50, 100, Math.PI/2, 0, 2 * Math.PI); // 旋转90°ctx.fill();}</script>
</body>
</html>
复制代码

效果如下:

贝塞尔曲线

贝塞尔曲线一般用来绘制复杂有规律的图形,在Canvas中也是一个十分有用的路径类型。

二次贝塞尔曲线

语法:quadraticCurveTo(cp1x, cp1y, x, y),其中cp1x和cp1y为一个控制点,x和y为结束点。

举个例子,代码如下:

<!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>canvas - 绘制二次贝塞尔曲线</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一段二次贝塞尔曲线ctx.moveTo(50, 50);ctx.quadraticCurveTo(200, 200, 350, 50);// 绘制ctx.stroke();}</script>
</body>
</html>
复制代码

得到的效果图如下:

如上图,一段二次贝塞尔曲线是通过一个起点、终点和结束点来控制的。下面通过控制点的变化来看一下二次贝塞尔曲线的变化。

把控制点往左移100像素点,代码如下:

<!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>canvas - 绘制二次贝塞尔曲线</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一段二次贝塞尔曲线ctx.beginPath() // 开启路径ctx.moveTo(50, 50);ctx.quadraticCurveTo(200, 200, 350, 50);// 绘制ctx.stroke();// 绘制一段二次贝塞尔曲线ctx.beginPath() // 开启路径ctx.moveTo(50, 250);ctx.quadraticCurveTo(100, 400, 350, 250);// 绘制ctx.stroke();}</script>
</body>
</html>
复制代码

效果如下:

这个其实可以借助一个网页版的二次贝塞尔曲线调试工具来看一下效果

三次贝塞尔曲线

和二次贝塞尔曲线不同的是三次贝塞尔曲线有两个控制点。

语法:ctx.bezierCurveTo(cp1x,cp1y, cp2x,cp2y, x, y),其中cp1x和cp1y为一个控制点,cp2x和cp2y为第二个控制点,x和y为结束点。

举个例子,代码如下:

<!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>canvas - 绘制三次贝塞尔曲线</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一段三次贝塞尔曲线ctx.beginPath() // 开启路径ctx.moveTo(50, 200);ctx.bezierCurveTo(150, 50, 250, 350, 350, 200);// 绘制ctx.stroke();}</script>
</body>
</html>
复制代码

效果如下:

这里也可以借助一个网页版的三次贝塞尔曲线调试工具来看一下效果:

绘制样式

在上面的图形绘制中都只是默认的样式。接下来说一下具体有哪些绘制样式。

线条的样式

线条的样式可以通过下面一系列属性来设置。

lineWidth

lineWidth 设置当前绘线的粗细。属性值必须为正数。默认值是 1.0。

<!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>canvas - 绘制样式</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="300" height="300">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一条宽度为10的直线ctx.beginPath()ctx.lineWidth = 10;ctx.moveTo(50, 20);ctx.lineTo(250, 20);ctx.stroke();ctx.closePath();// 绘制一条宽度为20的直线ctx.beginPath()ctx.lineWidth = 20;ctx.moveTo(50, 50);ctx.lineTo(250, 50);ctx.stroke();ctx.closePath();}</script>
</body>
</html>
复制代码

效果如下:

lineCap

lineCap 设置线段端点显示的样子。可选值为:butt,round 和 square。默认是 butt。

<!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>canvas - 绘制样式</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="300" height="300">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// lineCap 值为 buttctx.beginPath()ctx.lineWidth = 10;ctx.lineCap='butt'ctx.moveTo(50, 20);ctx.lineTo(250, 20);ctx.stroke();ctx.closePath();// lineCap 值为 roundctx.beginPath()ctx.lineWidth = 10;ctx.lineCap='round'ctx.moveTo(50, 50);ctx.lineTo(250, 50);ctx.stroke();ctx.closePath();// lineCap 值为 squarectx.beginPath()ctx.lineWidth = 10;ctx.lineCap='square'ctx.moveTo(50, 80);ctx.lineTo(250, 80);ctx.stroke();ctx.closePath();}</script>
</body>
</html>
复制代码

效果如下:

lineJoin

lineJoin 该属性可以设置两线段连接处所显示的样子。可选值为:round, bevel 和 miter。默认是 miter。

<!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>canvas - 绘制样式</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="300" height="300">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// lineJoin 值为 miterctx.beginPath()ctx.lineWidth = 10;ctx.lineJoin='miter'ctx.moveTo(50, 20);ctx.lineTo(100, 60);ctx.lineTo(150, 20);ctx.lineTo(200, 60);ctx.lineTo(250, 20);ctx.stroke();ctx.closePath();// lineJoin 值为 roundctx.beginPath()ctx.lineWidth = 10;ctx.lineJoin='round'ctx.moveTo(50, 100);ctx.lineTo(100, 140);ctx.lineTo(150, 100);ctx.lineTo(200, 140);ctx.lineTo(250, 100);ctx.stroke();ctx.closePath();// lineJoin 值为 bevelctx.beginPath()ctx.lineWidth = 10;ctx.lineJoin='bevel'ctx.moveTo(50, 180);ctx.lineTo(100, 220);ctx.lineTo(150, 180);ctx.lineTo(200, 220);ctx.lineTo(250, 180);ctx.stroke();ctx.closePath();}</script>
</body>
</html>
复制代码

效果为:

miterLimit

miterLimit 限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。

线段之间夹角比较大时,交点不会太远,但随着夹角变小,交点距离会呈指数级增大。

如果交点距离大于miterLimit值,连接效果会变成了 lineJoin = bevel 的效果。

举个例子看一下

<!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>canvas - 绘制样式</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="300" height="300">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// miterLimit为定值,角度越大ctx.beginPath()ctx.lineWidth = 5;ctx.lineJoin='miter'ctx.miterLimit = 10ctx.moveTo(0, 100);for (i = 0; i < 30 ; i++) {var dy = i % 2 == 0 ? 200 : 100;ctx.lineTo(Math.pow(i, 1.5) * 2, dy);}ctx.stroke();ctx.closePath();}</script>
</body>
</html>
复制代码

效果为:

setLineDash/getLineDash

setLineDash 可以设置当前虚线样式。

getLineDash 则是返回当前虚线设置的样式,长度为非负偶数的数组。

举个例子看一下

<!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>canvas - 绘制虚线</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一条虚线ctx.setLineDash([5, 10, 20]);console.log(ctx.getLineDash()); // [5, 10, 20, 5, 10, 20]ctx.beginPath();ctx.moveTo(0,100);ctx.lineTo(400, 100);ctx.stroke();// 再绘制一条虚线ctx.setLineDash([5, 10, 20, 40]);console.log(ctx.getLineDash()); // [5, 10, 20, 40]ctx.beginPath();ctx.moveTo(0,200);ctx.lineTo(400, 200);ctx.stroke();}</script>
</body>
</html>
复制代码

先看效果再讲解,效果如下:

首先这里画两条虚线是想对比一下传参为奇数数组和偶数数组的区别,在我们设置虚线的时候,如果传参为奇数,例如:ctx.setLineDash([5, 10, 20]),那么 setLineDash 会复制一份数组补全为偶数,相当于我们设置的是:ctx.setLineDash([5, 10, 20, 5, 10, 20])。所以这也就是为什么上图中我们设置的是 [5, 10, 20],结果打印出来是 [5, 10, 20, 5, 10, 20]

lineDashOffset

lineDashOffset 设置虚线样式的起始偏移量。

这里咱们再画第三条虚线来对比一下

<!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>canvas - 绘制虚线</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一段圆弧ctx.setLineDash([5, 10, 20]);console.log(ctx.getLineDash()); // [5, 10, 20, 5, 10, 20]ctx.beginPath();ctx.moveTo(0,100);ctx.lineTo(400, 100);ctx.stroke();ctx.setLineDash([5, 10, 20, 40]);console.log(ctx.getLineDash()); // [5, 10, 20, 40]ctx.beginPath();ctx.moveTo(0,200);ctx.lineTo(400, 200);ctx.stroke();ctx.setLineDash([5, 10, 20, 40]);ctx.lineDashOffset = 3;ctx.beginPath();ctx.moveTo(0,300);ctx.lineTo(400, 300);ctx.stroke();}</script>
</body>
</html>
复制代码

效果为:

这里可以明显看出虚线的总长度没有变化,只是起始点向左位移了3像素。

透明度

除了绘制实色的图形,还可以绘制有透明度的图形。通过设置 globalAlpha 属性或者使用有透明度的样式作为轮廓或填充都可以实现

举个例子看一下:

<!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>canvas - 设置透明度</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 绘制一个矩形ctx.beginPath();// 指定透明度的填充样式ctx.fillStyle = "rgba(0, 255, 0, 0.2)";ctx.fillRect(10,10,300,100);// 绘制一个矩形边框ctx.beginPath();// 指定透明度的描边样式ctx.strokeStyle = "rgba(255, 0, 0, 0.7)";ctx.strokeRect(10, 90, 100, 300);// 绘制一个圆ctx.beginPath()ctx.fillStyle = "rgba(255, 255, 0, 1)";// 设置透明度值ctx.globalAlpha = 0.5;ctx.arc(200, 200, 100, 0, Math.PI*2, true);ctx.fill();}</script>
</body>
</html>
复制代码

效果如下:

渐变

渐变分为两种,分别是线性渐变和径向渐变,在绘图中我们可以用线性或者径向的渐变来填充或描边。

线性渐变

语法: createLinearGradient(x1, y1, x2, y2),参数分别为 起点的坐标和终点的坐标。

在渐变的设置中还需要一个方法来添加渐变的颜色,语法为:gradient.addColorStop(offset, color),其中color就是颜色,offset 则是颜色的偏移值,只为0到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>canvas - 渐变</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 创建渐变var gradient1 = ctx.createLinearGradient(10, 10, 400, 10);gradient1.addColorStop(0, "#00ff00");gradient1.addColorStop(1, "#ff0000");var gradient2 = ctx.createLinearGradient(10, 10, 400, 10);// 从0.5的位置才开始渐变gradient2.addColorStop(0.5, "#00ff00");gradient2.addColorStop(1, "#ff0000");ctx.beginPath()ctx.fillStyle = gradient1;ctx.fillRect(10, 10, 400, 100);ctx.beginPath();ctx.fillStyle = gradient2;ctx.fillRect(10, 150, 400, 100);}</script>
</body>
</html>
复制代码

效果如下:

径向渐变

语法:ctx.createRadialGradient(x0, y0, r0, x1, y1, r1),参数分别为开始圆的坐标和半径以及结束圆的坐标和半径。

举个例子看一下:

<!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>canvas - 渐变</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 创建渐变// 结束坐标为点var gradient1 = ctx.createRadialGradient(100, 100, 100, 100, 100, 0);gradient1.addColorStop(0, "#ff770f");gradient1.addColorStop(1, "#ffffff");// 结束坐标为半径30的圆var gradient2 = ctx.createRadialGradient(320, 100, 100, 320, 100, 30); gradient2.addColorStop(0, "#ff770f");gradient2.addColorStop(1, "#ffffff");// 从0.5的位置才开始渲染var gradient3 = ctx.createRadialGradient(100, 320, 100, 100, 320, 0); gradient3.addColorStop(0.5, "#ff770f"); gradient3.addColorStop(1, "#ffffff");// 开始坐标和结束坐标不一样var gradient4 = ctx.createRadialGradient(320, 320, 100, 250, 250, 0);gradient4.addColorStop(0, "#ff770f");gradient4.addColorStop(1, "#ffffff");ctx.beginPath();ctx.fillStyle = gradient1;ctx.fillRect(10, 10, 200, 200);ctx.beginPath();ctx.fillStyle = gradient2;ctx.fillRect(220, 10, 200, 200);ctx.beginPath();ctx.fillStyle = gradient3;ctx.fillRect(10, 220, 200, 200);ctx.beginPath();ctx.fillStyle = gradient4;ctx.fillRect(220, 220, 200, 200);}

</script>
</body>
</html>
复制代码

效果如下:

图案样式

Canvas中想绘制图案效果,需要用 createPattern 方法来实现。

语法:createPattern(image, type),参数分别为:Image 参数可以是一个 Image 对象,也可以是一个 canvas 对象,Type 为图案绘制的类型,可用的类型分别有:repeat,repeat-x,repeat-y 和 no-repeat。

首先先看一下如何应用 Image 对象来绘制图案。

举个例子看一下:

<!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>canvas - 绘制图案</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 创建一个 image对象var img = new Image();img.src = "./image.png";img.onload = function() {// 图片加载完以后// 创建图案var ptrn = ctx.createPattern(img, 'no-repeat');ctx.fillStyle = ptrn;ctx.fillRect(0, 0, 500, 500);}}</script>
</body>
</html>
复制代码

上面是一个用image对象绘制的例子,效果如下:

从上面的代码我们可以看出,本来我们想填充的是一个500*500的长方形,但是因为咱们绘制的类型设置为不平铺(no-repeat)所以看到的效果不能让我们满意,那么咱们分别看看这四个类型分别是什么效果。

<!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>canvas - 绘制图案</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');// 创建一个 image对象var img = new Image();img.src = "./image.png";img.onload = function() {// 图片加载完以后// 创建图案var ptrn = ctx.createPattern(img, 'repeat');ctx.fillStyle = ptrn;ctx.fillRect(0, 0, 500, 500);}}</script>
</body>
</html>
复制代码

设置为平铺(repeat),效果如下: 这其实才是我们想要的效果,那么咱们再看看沿X轴平铺(repeat-x)和沿Y轴平铺(repeat-y)

效果分别是:

最后看一下如何应用 canvas 对象来绘制图案。 举个例子看一下:

<!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>canvas - 绘制图案</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;margin-right: 50px;}</style>
</head>
<body><canvas id="canvas" width="200" height="200">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><canvas id="canvas2" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');var canvas2 = document.getElementById('canvas2');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext && canvas2.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');var ctx2 = canvas2.getContext('2d');// 创建一个 canvas对象var img = new Image();img.src = "./image.png";img.onload = function() {// 图片加载完以后// 创建图案var ptrn = ctx.createPattern(img, 'repeat');ctx.fillStyle = ptrn;ctx.fillRect(0, 0, 200, 200);// 用canvas来绘制canvas2var ptrn2 = ctx2.createPattern(canvas, 'repeat');ctx2.fillStyle = ptrn2;ctx2.fillRect(0, 0, 500, 500);}}</script>
</body>
</html>
复制代码

效果如下:

上面的例子可以看出,canvas2是用canvas1来绘制图案的

绘制文本

canvas 中依旧提供了两种方法来渲染文本,一种是描边一种是填充。

strokeText(描边)

语法:ctx.strokeText(text, x, y, maxWidth)参数分别为:

  • text:绘制的文案
  • x、y:文本的起始位置
  • maxWidth:可选参数,最大宽度。需要注意的是当文案大于最大宽度时不是裁剪或者换行,而是缩小字体。

举个例子看一下:

<!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>canvas - 绘制文本</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');ctx.font = "50px serif"; // 设置文案大小和字体ctx.strokeText("Canvas 详解", 50, 50);}</script>
</body>
</html>
复制代码

看一下效果:

fillText(填充)

语法:ctx.fillText(text, x, y, maxWidth)参数分别为:

  • text:绘制的文案
  • x、y:文本的起始位置
  • maxWidth:可选参数,最大宽度。需要注意的是当文案大于最大宽度时不是裁剪或者换行,而是缩小字体。

举个例子看一下:

<!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>canvas - 绘制文本</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');ctx.font = "50px serif"; // 设置文案大小和字体ctx.fillText("Canvas 详解", 50, 50);}</script>
</body>
</html>
复制代码

文本样式

文本也是可以添加样式的,下面看一下可以设置那些样式

font

用于绘制文本的样式。默认的字体是 10px sans-serif。

textAlign

文本对齐的方式。可选值为:left、right、center、start和end。默认值是 start。

direction

文本的方向。可选值为:ltr(文本方向从左向右)、rtl(文本方向从右向左)、inherit(根据情况继承 Canvas元素或者 Document 。)。默认值是 inherit。

需要注意的是 direction 属性会对 textAlign 属性产生影响。如果 direction 属性设置为 ltr,则textAlign属性的 left 和 start 的效果相同,right 和 end 的效果相同,如果 direction 属性设置为 rtl,则 textAlign属性的 left 和 end 的效果相同,right 和 start 的效果相同。

<!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>canvas - 绘制图案</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;margin-right: 50px;}</style>
</head>
<body><canvas id="canvas" width="500" height="700">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');ctx.font = "30px serif"; // 设置文案大小和字体ctx.direction = "ltr"; // 文本方向从左向右ctx.textAlign = "left"; // 左对齐ctx.strokeText("Hi Canvas !", 150, 100);ctx.direction = "ltr"; // 文本方向从左向右ctx.textAlign = "center"; // 右对齐ctx.strokeText("Hi Canvas !", 150, 200);ctx.direction = "ltr"; // 文本方向从左向右ctx.textAlign = "right"; // 右对齐ctx.strokeText("Hi Canvas !", 150, 300);ctx.direction = "rtl"; // 文本方向从左向右ctx.textAlign = "left"; // 左对齐ctx.strokeText("Hi Canvas !", 150, 400);ctx.direction = "rtl"; // 文本方向从左向右ctx.textAlign = "center"; // 右对齐ctx.strokeText("Hi Canvas !", 150, 500);ctx.direction = "rtl"; // 文本方向从左向右ctx.textAlign = "right"; // 右对齐ctx.strokeText("Hi Canvas !", 150, 600);}</script>
</body>
</html>
复制代码

效果如下:

textBaseline

基线对齐选项,决定文字垂直方向的对齐方式。可选值为:top、hanging、middle、alphabetic、ideographic和bottom。默认值是 alphabetic。

举个例子看一下:

<!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>canvas - 绘制图案</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;margin-right: 50px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');ctx.font = "25px serif"; // 设置文案大小和字体ctx.strokeStyle = 'red';const baselines = ['top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom'];baselines.forEach(function (baseline, index) {ctx.textBaseline = baseline;let y = 60 + index * 60;ctx.beginPath();ctx.moveTo(10, y + 0.5);ctx.lineTo(500, y + 0.5);ctx.stroke();ctx.fillText('Hi Canvas, Welcome to my world! (' + baseline + ')', 10, y);});}</script>
</body>
</html>
复制代码

效果如下:

measureText

测量文本,返回一个 TextMetrics对象。

<!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>canvas - 绘制图案</title><style>/* 给画布增加一个阴影和圆角的样式 */canvas {box-shadow: 0px 0px 5px #ccc;border-radius: 8px;margin-right: 50px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500">当前浏览器不支持canvas元素,请升级或更换浏览器!</canvas><script>// 获取 canvas 元素var canvas = document.getElementById('canvas');// 通过判断getContext方法是否存在来判断浏览器的支持性if(canvas.getContext) {// 获取绘图上下文var ctx = canvas.getContext('2d');ctx.font = "30px serif"; // 设置文案大小和字体ctx.beginPath();ctx.strokeText("Hi Canvas !", 150, 100);var text = ctx.measureText("Hi Canvas !");console.log("												

案例+图解带你一文读懂Canvas【2W字,建议收藏】相关推荐

  1. 案例+图解带你一文读懂SVG

    资料链接 案例+图解带你一文读懂SVG (2.6W+字) 简介 SVG 是 Scalable Vector Graphics 的缩写,意为可缩放矢量图形.于 2003年1月14日 SVG 1.1 被S ...

  2. 【强化学习炼金术】李飞飞高徒带你一文读懂RL来龙去脉

    强化学习炼金术 · 背景介绍(上) 欢迎来到<强化学习炼金术>第一讲.手摇芭蕉扇,支起八仙炉,再点上三昧真火.各位炼金术师,你们都准备好了吗? 在这一课里,我会跟大家说说强化学习的概念和目 ...

  3. 带你一文读懂Javascript中ES6的Symbol

    带你一文读懂Javascript中ES6的Symbol 前言 基础类型 Symbol Symbol.for 与 Symbol.keyFor Symbol.iterator Symbol.search ...

  4. 一文带你全方位(架构,原理及代码实现)了解Flink(3.2W字建议收藏)

    注:最底部有PDF目录 一 flink简介 1.1 什么是flink Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎.F ...

  5. “浪潮信息龙蜥联合实验室”正式成立!2万+人在线,带你一文读懂MeetUp精彩瞬间

    12 月 24 日,龙蜥社区(OpenAnolis) "走进系列" 第 4 期--走进浪潮信息 MeetUp  于线上开展并圆满结束.本次走进浪潮信息 MeetUp 线上观看 2 ...

  6. 带你一文读懂SaaS版多租户商城系统对多品牌企业的应用价值

    ​ 近年来,随着中国的企业级SaaS软件服务的方兴未艾,企业的信息化建设覆盖从底层基础设施到上层应用软件,具备即需即用.按需付费的服务正在给企业信息化带来前所未有的变革. 目前,面向大型企业/集团搭建 ...

  7. 全新视角!带你一文读懂ChatGPT!

    最了解你的人不是你的朋友,而是你的敌人. --<东邪西毒> 目录 什么是ChatGPT? ChatGPT为什么会突然爆红网络? ChatGPT能帮助我们做什么? 获取源码?私信?关注?点赞 ...

  8. 一文读懂Java中File类、字节流、字符流、转换流

    一文读懂Java中File类.字节流.字符流.转换流 第一章 递归:File类: 1.1:概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. ...

  9. 原创 | 一文读懂机器学习中的shapley值方法

    作者:贾恩东本文约2000字,建议阅读9分钟本文为你介绍更公平分配利益权重的一种算法--Shapley值方法. 本篇文章是数据派一文读懂系列的新年第一篇原创,在这里祝贺大家新年学业有新成就,生活有新气 ...

最新文章

  1. Node.js process 模块常用属性和方法
  2. alertdialog怎么水平排列_轻钢二级吊顶怎么安装
  3. vba如何让文本框显示指定的内容_室内LED显示屏如何安装?一篇内容了解清楚
  4. linux权限源码分析,Linux基础之文件权限详解
  5. 入侵网站简单方法总结
  6. Bootstrap3 Affix插件
  7. 6月8日任务(12.10 Nginx访问日志 12.11 Nginx日志切割 12.12 静态文件)
  8. 在线解压rar_解压指南!新手必看
  9. 发字的楷书写法图片_硬笔书法笔顺正确写法,手写示范动态图
  10. OpenCV学习——摄像头人脸识别
  11. java poi设置导出的excel带下拉
  12. jupyter notebook 更改工作环境和浏览器
  13. 在Octane中提升渲染速度的技巧(第2部分)
  14. 支持m3u8的php视频cms,分享一个苹果CMS可用P2P的M3U8解析代码
  15. 服务器安全设置全攻略
  16. 小米3c虚拟服务器,小米路由器3和3C哪个好?小米路由器3和3C区别
  17. 用java画哆啦a梦,来画哆啦A梦吧!
  18. STM32F103 485通信开发实例
  19. IT职场,技能比情商重要N倍
  20. 记录爬虫实战——有道翻译(反js加密)

热门文章

  1. 2021年辽宁省大学生数学建模
  2. JS设置请在微信客户端打开链接提示页面
  3. 随身车联网——车联网生态新物种(附发布会视频)
  4. 汇编语言的七种寻址方式
  5. esp8266局域网内的TCP通信实验
  6. 007-寄存器EAX与AX,AH,AL关系
  7. OMNET随笔(初学感悟)
  8. 1.什么是Cython
  9. Python网络数据采集9(译者:哈雷)
  10. oracle dba技术培训视频分享