本文为稀土掘金技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!
大家好我是ndz,很高兴也很荣幸成为了一名稀土掘金技术社区签约作者,在这里真的很感谢平台给予的肯定和各位读者的支持,感谢 🙏 🙏 🙏。
本文为稀土掘金技术社区签约作者专栏 - 《从Canvas到PixiJs》 的第三篇文章,喜欢的小伙伴记得点赞加关注,以防需要用时回来不迷路 😂
前言
在上一篇文章 PixiJs学前篇(一):Canvas基础【上篇】🔥🔥 中说到了Canvas的基本绘制形状中的三角形、四边形、五边形等等多边形都可以用直线来绘制,接下来我们将介绍一些直线无法绘制的形状,比如圆弧、圆、椭圆、贝塞尔曲线等和一些直线能绘制但显得太繁琐Canvas提供了Api可以直接绘制的如:矩形。
基本绘制形状
上篇文章我们说过,在Canvas的绘制中,基本绘制形状主要有:直线
、三角形
、矩形
、圆和圆弧
、椭圆
、贝塞尔曲线
。直线和三角形在上一篇文章我们已经介绍完了,那么接下来我们开始说矩形的绘制。
矩形
矩形的绘制我们依旧可以用直线来绘制,四条直线首尾相连就可以绘制出一个矩形。但这样绘制矩形太繁琐,因此Canvas为我们提供了简易的Api方法,下面我们依次介绍一下。
语法
// 矩形描边
rect(x, y, width, height)
// 绘制矩形
strokeRect(x, y, width, height)
// 填充矩形
fillRect(x, y, width, height)
上述的三个方法都可以用来绘制矩形,他们的传参都是一样的,其中x和y是起始点的x坐标和y坐标,width为矩形的宽,height为矩形的高。
rect()
rect()
方法可以创建一个矩形路径,想要绘制矩形还需要结合描边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>
</head>
<body>
<canvas
id="canvas"
width="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5
// 描边一个矩形
ctx.rect(50, 50, 300, 100)
ctx.stroke()
ctx.beginPath()
// 填充一个矩形
ctx.rect(50, 300, 300, 100)
ctx.fill();
</script>
</body>
</html>
效果如下:
如图所示,当我们创建了矩形路径以后,我们就可以根据我们的需求来选择接下来怎么做。不仅仅是选择描边或者填充,在之后的学习中我们会发现它的更多用处,比如:裁剪。
strokeRect()
strokeRect()
方法是rect()
方法和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>
</head>
<body>
<canvas
id="canvas"
width="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5
// 先创将矩形路径,再描边矩形
ctx.rect(50, 50, 300, 100)
ctx.stroke()
ctx.beginPath()
// 直接创建矩形路径并描边
ctx.strokeRect(50, 300, 300, 100)
</script>
</body>
</html>
效果如下:
从图片我们可以看出,两种方法都能绘制一个矩形边框,但显然strokeRect()
方法比rect()
方法和stroke()
方法的合并使用更简单。
fillRect()
fillRect()
方法和strokeRect()
方法类似,是rect()
方法和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>
</head>
<body>
<canvas
id="canvas"
width="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5
// 先创将矩形路径,再描边矩形
ctx.rect(50, 50, 300, 100)
ctx.fill()
ctx.beginPath()
// 直接创建矩形路径并描边
ctx.fillRect(50, 300, 300, 100)
</script>
</body>
</html>
效果如下:
如图所示,两种填充矩形的方法,strokeRect()
方法显然比rect()
方法和fill()
方法的合并使用更简单。
圆弧和圆
Canvas提供了绘制圆弧或圆的方法:arc()
,该方法提供了给定坐标值(x,y)以后,按给定的半径(r)大小,从给定的起始点(startAngle)位置,默认顺时针方向绘制圆弧或圆到给定的终点(endAngle)。
语法
arc()
方法的语法如下:
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
参数说明:
- x,y 为圆弧中心或圆的圆心坐标、
- radius 为圆弧的半径或圆的半径、
- startAngle 为圆弧或圆的起始点,从x轴方向开始计算,且单位为弧度、
- endAngle 为圆弧或圆的终点,单位也是为弧度
- anticlockwise 是一个可选参数,可选值为Boolean类型,用它来表示圆弧或圆的绘制方向,默认为false,顺时针绘制圆弧或圆。
角度转弧度的公式为:弧度 = 角度 * Math.PI / 180
下面我们尝试着绘制一段圆弧看一下。
<!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="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5,
// 顺时针绘制一段90度的圆弧
ctx.arc(100, 100, 50, 0, 90 * Math.PI /180 );
ctx.stroke();
// 逆时针绘制一段90度的圆弧
ctx.beginPath();
ctx.arc(300, 100, 50, 0, 90 * Math.PI /180, true );
ctx.stroke();
</script>
</body>
</html>
效果如下:
从效果我们可以看出,90度弧度的圆弧顺时针和逆时针绘制出来的圆弧不一样,因此在绘制的时候应该注意一下顺时针和逆时针的区别。
圆弧的绘制我们知道了,那么圆的绘制也就比较简单了,我们只需要绘制一个起点为0(0 * Math.PI /180 或 0),结束点为360(360 * Math.PI /180)的弧度就是一个圆,下面直接看代码:
<!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="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5,
// 顺时针绘制一段90度的圆弧
ctx.arc(100, 100, 50, 0, 360 * Math.PI /180 );
ctx.stroke();
// 逆时针绘制一段90度的圆弧
ctx.beginPath();
ctx.arc(300, 300, 50, 0, 360 * Math.PI /180);
ctx.fill();
</script>
</body>
</html>
效果为:
椭圆
椭圆的绘制Canvas的2D绘制上下文也提供了对应的Api,具体的语法如下:
语法
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
- x、y:椭圆的圆心坐标
- radiusX:x轴的半径大小
- radiusY: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>
效果如下:
贝塞尔曲线
我们介绍的最后一个基本绘制形状是贝塞尔曲线,贝塞尔曲线是应用于二维图形应用程序的数学曲线。 一般用来绘制复杂有规律的图形。下面我们看一下二次贝塞尔曲线和三次贝塞尔曲线。
二次贝塞尔曲线
如图就是一个二次贝塞尔曲线,他的绘制需要一个控制点来控制曲线,具体的语法为:
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>
</head>
<body>
<canvas
id="canvas"
width="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#333";
ctx.beginPath();
ctx.moveTo(100, 250);
ctx.quadraticCurveTo(250, 100, 400, 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>
</head>
<body>
<canvas
id="canvas"
width="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.lineWidth = 6;
ctx.strokeStyle = "#333";
ctx.beginPath();
ctx.moveTo(100, 250);
ctx.bezierCurveTo(150, 100, 350, 100, 400, 250);
ctx.stroke();
</script>
</body>
</html>
效果如下:
这里也有一个在线例子,大家可以体验一下三次贝塞尔曲线调试工具来看一下效果:
贝塞尔曲线就介绍这些,但并不止于这些,还有四次贝塞尔曲线,五次贝塞尔曲线......
下面是我在网络上找的一些GIF图,小伙伴们可以看图了解一下:
一次贝塞尔曲线:
二次贝塞尔曲线:
三次贝塞尔曲线:
四次贝塞尔曲线:
五次贝塞尔曲线:
路径的开启和闭合
在前面的例子中我们经常能看到beginPath()
这个方法,虽然使用了很多次,但咱们并没有细说它的功能,下面咱们详细说一下。
beginPath()
beginPath()
方法用于开始一条路径或重置当前的路径,以刚才的圆弧的例子为例,咱们看一下如果不使用beginPath()
方法,注释了再看看绘制出来的样子。
代码如下:
<!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="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5,
// 顺时针绘制一段90度的圆弧
ctx.arc(100, 100, 50, 0, 90 * Math.PI /180 );
ctx.stroke();
// 逆时针绘制一段90度的圆弧
// ctx.beginPath();
ctx.arc(300, 100, 50, 0, 90 * Math.PI /180, true );
ctx.stroke();
</script>
</body>
</html>
效果如下:
如图,当我们不重新开启一条新路径,两条路径就会默认为是一条路径来绘制,因此就得不到我们想要的效果。想分开绘制我们就需要重新开启新的路径。
closePath()
closePath()
方法和beginPath()
方法正好相反,用来关闭一条路径,规范的用法其实是他们两个搭配使用,每次绘制都先开启一条新路径,完事关闭该路径,代码如下:
<!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="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5,
// 顺时针绘制一段90度的圆弧
ctx.beginPath();
ctx.arc(100, 100, 50, 0, 90 * Math.PI /180 );
ctx.stroke();
ctx.closePath()
// 逆时针绘制一段90度的圆弧
ctx.beginPath();
ctx.arc(300, 100, 50, 0, 90 * Math.PI /180, true );
ctx.stroke();
ctx.closePath()
</script>
</body>
</html>
效果如下:
因此每次我们连续绘制时,若需要分开绘制,那么一定要在每次绘制前重新开启新的路径。
透明度
透明度是我们经常在Canvas中绘制图像时常用的一个属性。这里咱们简单介绍一下,透明度的实现我们可以通过设置 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>
</head>
<body>
<canvas
id="canvas"
width="500"
height="500"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5,
// 绘制一个矩形边框
ctx.beginPath();
ctx.strokeStyle = "rgba(255, 0, 0, 0.7)"; // 指定透明度的描边样式
ctx.strokeRect(10,10,300,100);
// 绘制一个矩形
ctx.beginPath();
ctx.fillStyle = "rgba(0, 255, 0, 0.2)"; // 指定透明度的填充样式
ctx.fillRect(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)
- 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>
</head>
<body>
<canvas
id="canvas"
width="450"
height="450"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5
// 创建渐变
var gradient1 = ctx.createLinearGradient(10, 10, 400, 10);
gradient1.addColorStop(0, "#000000");
gradient1.addColorStop(1, "#ffffff");
var gradient2 = ctx.createLinearGradient(10, 10, 400, 10);
// 从0.5的位置才开始渐变
gradient2.addColorStop(0.5, "#000000");
gradient2.addColorStop(1, "#ffffff");
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)
参数:
- 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>
</head>
<body>
<canvas
id="canvas"
width="450"
height="450"
style="box-shadow: 0px 0px 5px #ccc; border-radius: 8px;">
当前浏览器不支持canvas元素,请升级或更换浏览器!
</canvas>
<script>
const canvas = document.getElementById('canvas'); // 获取Canvas
const ctx = canvas.getContext('2d'); // 获取绘制上下文
ctx.strokeStyle = "#f00" // 描边样式设置为红色
ctx.fillStyle = "#00f" // 填充样式设置为蓝色
ctx.lineWidth = 5
// 创建渐变
// 结束坐标为点
var gradient1 = ctx.createRadialGradient(100, 100, 100, 100, 100, 0);
gradient1.addColorStop(0, "#000000");
gradient1.addColorStop(1, "#ffffff");
// 结束坐标为半径30的圆
var gradient2 = ctx.createRadialGradient(320, 100, 100, 320, 100, 30);
gradient2.addColorStop(0, "#000000");
gradient2.addColorStop(1, "#ffffff");
// 从0.5的位置才开始渲染
var gradient3 = ctx.createRadialGradient(100, 320, 100, 100, 320, 0);
gradient3.addColorStop(0.5, "#000000");
gradient3.addColorStop(1, "#ffffff");
// 开始坐标和结束坐标不一样
var gradient4 = ctx.createRadialGradient(320, 320, 100, 250, 250, 0);
gradient4.addColorStop(0, "#000000");
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中的情况,而想在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来绘制canvas2
var ptrn2 = ctx2.createPattern(canvas, 'repeat');
ctx2.fillStyle = ptrn2;
ctx2.fillRect(0, 0, 500, 500);
}
}
</script>
</body>
</html>
效果如下:
上面的例子可以看出,canvas2是用canvas1来绘制图案的