canvas 可以获取上下文,2d 部分是CanvasRenderingContext2D,它用于绘制形状,文本,图像和其他对象。
画矩形
canvas提供了三种方法绘制矩形:
fillRect(x, y, width, height)
绘制一个填充的矩形
strokeRect(x, y, width, height)
绘制一个矩形的边框
clearRect(x, y, width, height)
清除指定矩形区域,让清除部分完全透明。
代码:
代码语言:javascript复制<!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>绘制矩形</title>
</head>
<body>
<canvas id="canvas2d" width="200" height="200" style="background:red"></canvas>
</body>
<script>
let canvas2d = document.getElementById('canvas2d')
console.log(canvas2d);
if (canvas2d.getContext) {
var ctx = canvas2d.getContext('2d');
ctx.fillRect(25, 25, 100, 100);
ctx.clearRect(45, 45, 60, 60);
ctx.strokeRect(50, 50, 50, 50);
}
</script>
</html>
结果:
绘制圆形
画圆形api
代码语言:javascript复制void ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
参数:
x 圆弧中心(圆心)的 x 轴坐标。
y 圆弧中心(圆心)的 y 轴坐标。
radius 圆弧的半径。
startAngle 圆弧的起始点, x轴方向开始计算,单位以弧度表示。
endAngle 圆弧的终点, 单位以弧度表示。
anticlockwise 可选 可选的Boolean值 ,如果为 true,逆时针绘制圆弧,反之,顺时针绘制。
例子代码:
代码语言:javascript复制<!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>绘制圆形</title>
</head>
<body>
<canvas id="canvas2d" width="200" height="200"></canvas>
</body>
<style>
#canvas2d{
border: 1px solid;
display: block;
margin: 0 auto;
}
</style>
<script>
let canvas2d = document.getElementById('canvas2d')
canvas2d.width = window.innerWidth/2
canvas2d.height = window.innerHeight
if (canvas2d.getContext) {
var ctx = canvas2d.getContext('2d');
ctx.beginPath();
ctx.arc(75, 75, 50, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(260,75)
ctx.arc(200, 75, 60, 0, 2 * Math.PI);
ctx.fill()
}
</script>
</html>
显示:
绘制五角星
首先整理下思路,看了别人一个图比较好,拿来一下。
思路:
- 两个圆各自五个点,每个点相差72度
- 点可以根据半径和度数求出x,y 坐标
- 循环点,canvans 连线
<!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>绘制五角星</title>
</head>
<body>
<canvas id="canvas2d" width="200" height="200"></canvas>
</body>
<style>
#canvas2d {
border: 1px solid;
display: block;
margin: 0 auto;
}
</style>
<script>
let canvas2d = document.getElementById("canvas2d");
canvas2d.width = window.innerWidth / 2;
canvas2d.height = window.innerHeight;
if (canvas2d.getContext) {
var ctx = canvas2d.getContext("2d");
ctx.beginPath();
// 将坐标移动到画布中央
ctx.translate(canvas2d.width / 2, canvas2d.height / 2);
// 设置大圆、小圆半径
let R = 200;
let r = 100;
let x;
let y;
// 逆时针计算五角星外围10个点的坐标
for (let i = 0; i < 5; i ) {
// 外围凸出的每个点坐标
x = Math.cos(((18 72 * i) / 180) * Math.PI) * R;
y = -Math.sin(((18 72 * i) / 180) * Math.PI) * R; // canvas中y轴的正向方向与直角坐标系相反
ctx.lineTo(x, y);
// 外围凹下去的每个点坐标
x = Math.cos(((54 72 * i) / 180) * Math.PI) * r;
y = -Math.sin(((54 72 * i) / 180) * Math.PI) * r; // canvas中y轴的正向方向与直角坐标系相反
ctx.lineTo(x, y);
}
ctx.closePath();
ctx.stroke();
}
</script>
</html>
绘制笑脸
官方示例,这是相比于五角星,会有一个移动画笔的动作。
代码:
代码语言:javascript复制<!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>绘制五角星</title>
</head>
<body>
<canvas id="canvas2d" width="200" height="200"></canvas>
</body>
<style>
#canvas2d {
border: 1px solid;
display: block;
margin: 0 auto;
}
</style>
<script>
let canvas2d = document.getElementById("canvas2d");
// canvas2d.width = window.innerWidth / 2;
// canvas2d.height = window.innerHeight;
if (canvas2d.getContext) {
var ctx = canvas2d.getContext("2d");
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI * 2, false); // 绘制
ctx.moveTo(110, 75);
ctx.arc(75, 75, 35, 0, Math.PI, false); // 口 (顺时针)
ctx.moveTo(65, 65);
ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // 左眼
ctx.moveTo(95, 65);
ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // 右眼
ctx.stroke();
}
</script>
</html>
效果:
二次贝塞尔曲线
贝塞尔曲线一般用来画曲线,波浪等图形,依赖于贝塞尔曲线公式。可借助在线工具帮助获取想要的曲线控制点。
贝塞尔画线工具
API 说明
quadraticCurveTo(cp1x, cp1y, x, y)
绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。
下面例子是用二次贝塞尔曲线画一个提示框
示例代码
代码语言:javascript复制<!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>二次贝塞尔曲线</title>
</head>
<body>
<canvas id="canvas2d" width="500" height="500"></canvas>
</body>
<style>
#canvas2d {
border: 1px solid;
display: block;
margin: 0 auto;
}
</style>
<script>
let canvas2d = document.getElementById("canvas2d");
if (canvas2d.getContext) {
var ctx = canvas2d.getContext("2d");
// 二次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(75, 25);
ctx.quadraticCurveTo(25, 25, 25, 62.5);
ctx.quadraticCurveTo(25, 100, 50, 100);
ctx.quadraticCurveTo(50, 120, 30, 125);
ctx.quadraticCurveTo(60, 120, 65, 100);
ctx.quadraticCurveTo(125, 100, 125, 62.5);
ctx.quadraticCurveTo(125, 25, 75, 25);
ctx.stroke();
}
</script>
</html>
效果展示
三次贝塞尔曲线
API 说明
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
下面利用三次贝塞尔曲线画一个心形
效果演示
代码示例
代码语言:javascript复制<!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>三次贝塞尔曲线</title>
</head>
<body>
<canvas id="canvas2d" width="200" height="200"></canvas>
</body>
<style>
#canvas2d {
border: 1px solid;
display: block;
margin: 0 auto;
}
</style>
<script>
let canvas2d = document.getElementById("canvas2d");
if (canvas2d.getContext) {
var ctx = canvas2d.getContext("2d");
// 三次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(75, 40);
ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
ctx.fill();
}
</script>
</html>
综合应用
把以上图形综合应用到项目里,添加
效果演示
代码示例
代码语言:javascript复制<!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>综合示例</title>
</head>
<body>
<canvas id="canvas2d" width="500" height="500"></canvas>
</body>
<style>
#canvas2d {
border: 1px solid;
display: block;
margin: 0 auto;
}
</style>
<script>
let canvas2d = document.getElementById("canvas2d");
if (canvas2d.getContext) {
var ctx = canvas2d.getContext("2d");
// 将坐标移动到画布中央
ctx.translate(160, 160);
//大石块障碍物
roundedRect(ctx, 12, 12, 200, 200, 15);
roundedRect(ctx, 19, 19, 200, 200, 9);
roundedRect(ctx, 53, 53, 49, 33, 10);
roundedRect(ctx, 53, 119, 49, 16, 6);
roundedRect(ctx, 135, 53, 49, 33, 10);
roundedRect(ctx, 135, 119, 25, 49, 10);
ctx.beginPath();
// 开始角度和结束角度限制形成缺口
ctx.arc(37, 37, 13, Math.PI / 7, -Math.PI / 7, false);
ctx.lineTo(31, 37);
ctx.fill();
// 小方块黑点
for (var i = 0; i < 8; i ) {
ctx.fillRect(51 i * 16, 35, 4, 4);
}
for (i = 0; i < 6; i ) {
ctx.fillRect(115, 51 i * 16, 4, 4);
}
for (i = 0; i < 8; i ) {
ctx.fillRect(51 i * 16, 99, 4, 4);
}
// 怪物,从左下角开始画
ctx.beginPath();
ctx.moveTo(83, 116);
ctx.lineTo(83, 102);
ctx.bezierCurveTo(83, 94, 89, 88, 97, 88);
ctx.bezierCurveTo(105, 88, 111, 94, 111, 102);
ctx.lineTo(111, 116);
ctx.lineTo(106.333, 111.333);
ctx.lineTo(101.666, 116);
ctx.lineTo(97, 111.333);
ctx.lineTo(92.333, 116);
ctx.lineTo(87.666, 111.333);
ctx.lineTo(83, 116);
ctx.fill();
// 怪兽眼睛,是贝塞尔曲线不是圆
ctx.fillStyle = "white";
ctx.beginPath();
ctx.moveTo(91, 96);
ctx.bezierCurveTo(88, 96, 87, 99, 87, 101);
ctx.bezierCurveTo(87, 103, 88, 106, 91, 106);
ctx.bezierCurveTo(94, 106, 95, 103, 95, 101);
ctx.bezierCurveTo(95, 99, 94, 96, 91, 96);
ctx.moveTo(103, 96);
ctx.bezierCurveTo(100, 96, 99, 99, 99, 101);
ctx.bezierCurveTo(99, 103, 100, 106, 103, 106);
ctx.bezierCurveTo(106, 106, 107, 103, 107, 101);
ctx.bezierCurveTo(107, 99, 106, 96, 103, 96);
ctx.fill();
// 怪兽黑眼珠
ctx.fillStyle = "black";
ctx.beginPath();
ctx.arc(101, 102, 2, 0, Math.PI * 2, true);
ctx.fill();
ctx.beginPath();
ctx.arc(89, 102, 2, 0, Math.PI * 2, true);
ctx.fill();
}
// 封装的一个用于绘制圆角矩形的函数。
// 方块从左上角弧度下开始化
function roundedRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x, y radius);
ctx.lineTo(x, y height - radius);
ctx.quadraticCurveTo(x, y height, x radius, y height);
ctx.lineTo(x width - radius, y height);
ctx.quadraticCurveTo(
x width,
y height,
x width,
y height - radius
);
ctx.lineTo(x width, y radius);
ctx.quadraticCurveTo(x width, y, x width - radius, y);
ctx.lineTo(x radius, y);
ctx.quadraticCurveTo(x, y, x, y radius);
ctx.stroke();
}
</script>
</html>
Path2D
Path2D 看这个名字已经明白了这个对象的意义,就是路径,我们可以把路径看做对象,路径对象可以添加多条轨迹集合。这样高效在画布上进行复用。
以三维贝塞尔曲线画心型为例,可以缓存心形路径达到复用路径的目的。
代码示例
代码语言:javascript复制<!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>path2d</title>
</head>
<body>
<canvas id="canvas2d" width="500" height="500"></canvas>
</body>
<style>
#canvas2d {
border: 1px solid;
display: block;
margin: 0 auto;
}
</style>
<script>
let canvas2d = document.getElementById("canvas2d");
if (canvas2d.getContext) {
var ctx = canvas2d.getContext("2d");
// 用path 对象画图
let heart = new Path2D();
heart.moveTo(75, 40);
heart.bezierCurveTo(75, 37, 70, 25, 50, 25);
heart.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
heart.bezierCurveTo(20, 80, 40, 102, 75, 120);
heart.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
heart.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
heart.bezierCurveTo(85, 25, 75, 37, 75, 40);
ctx.stroke(heart);
ctx.translate(30,10)
ctx.fill(heart)
}
</script>
</html>
效果演示
path2d svg 路径支持
新的 Path2D API 有另一个强大的特点,就是使用 SVG path data 来初始化 canvas 上的路径。这将使你获取路径时可以以 SVG 或 canvas 的方式来重用它们。
这条路径将先移动到点 (M10 10) 然后再水平移动 80 个单位(h 80),然后下移 80 个单位 (v 80),接着左移 80 个单位 (h -80),再回到起点处 (z)。你可以在Path2D constructor 查看这个例子。
代码示例
代码语言:javascript复制<!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>path2d</title>
</head>
<body>
<canvas id="canvas2d" width="500" height="500"></canvas>
</body>
<style>
#canvas2d {
border: 1px solid;
display: block;
margin: 0 auto;
}
</style>
<script>
let canvas2d = document.getElementById("canvas2d");
if (canvas2d.getContext) {
var ctx = canvas2d.getContext("2d");
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
ctx.strokeStyle = 'red'
ctx.stroke(p);
}
</script>
</html>