一、认识canvas
canvas是H5新增的一个标签。它的作用是在浏览器上创建一个画布,用来绘画。
二、使用场景
(1)简单游戏的开发;
(2)简单图像;
(3)验证码;
(4)绘制图表;
(5)绘制地图;
(6)制作马赛克效果;
(7)模拟帧动画等。
三、基本用法
<canvas id="canvas"></canvas>
var canvas = document.querySelector('#canvas');
// 渲染上下文
var ctx = canvas.getContext('2d');// 2d表示绘制的是2d图形,webgl表示绘制的是3d图形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#canvas{
width: 500px;
height: 400px;
}
</style>
</head>
<body>
<!-- canvas的宽高最好通过属性设置,而是不是通过CSS实现。 -->
<!-- <canvas id="canvas" width="400" height="300"></canvas> -->
<canvas id="canvas"></canvas>
</body>
<script>
var canvas = document.querySelector('#canvas');
// 渲染上下文
var ctx = canvas.getContext('2d');// 2d表示绘制的是2d图形,webgl表示绘制的是3d图形
console.log(ctx);
</script>
</html>
四、兼容处理
<canvas id="cv" width="300" height="300">您的浏览器不支持canvas</canvas>
var cv = document.getElementById('cv');
if(cv.getContext){
// 绘图代码处
} else {
console.log('您的浏览器不支持canvas!');
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<canvas id="cv" width="300" height="300">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if(cv.getContext){
console.log('您的浏览器支持canvas!');
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
五、canvas与svg的区别(了解)
Canvas
1)依赖分辨率
2)不支持事件处理器
3)弱的文本渲染能力
4)能够以 .png 或 .jpg 格式保存结果图像
5)最适合图像密集型的游戏,其中的许多对象会被频繁重绘
SVG
1)不依赖分辨率
2)支持事件处理器
3)最适合带有大型渲染区域的应用程序(比如谷歌地图)
4)复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
5)不适合游戏应用
六、canvas常用方法
1、绘制路径
绘制路径方法:
1)首先,你需要创建路径起始点。
2)然后你使用画图命令去画出路径。
3)之后你把路径封闭。
4)一旦路径生成,你就能通过描边或填充路径区域来渲染图形。
beginPath():开启一条路径,或重置当前路径
closePath():创建从当前点回到起始点的路径
ctx.moveTo(x,y):移动笔触(x,y表示坐标)
ctx.stroke():描边
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<canvas id="cv" width="400" height="400">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if(cv.getContext){
var ctx = cv.getContext('2d');
ctx.beginPath();// 开始笔触(表示可以开始绘画了)
ctx.arc(200, 200, 200, 0, 2 * Math.PI, true); // 绘制圆
ctx.moveTo(100,100); // 移动笔触
ctx.arc(100, 100, 20, 0, 2 * Math.PI, false);
ctx.moveTo(300,100);
ctx.arc(300, 100, 20, 0, 2 * Math.PI, false);
ctx.moveTo(200,250);
ctx.arc(200, 250, 100, 0, Math.PI, false);
ctx.stroke();// 描边
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
2、绘制直线
lineTo(x,y):绘制一条从x到y的直线。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>绘制直线</title>
<style>
#cv {
border: 1px solid #999;
}
</style>
</head>
<body>
<canvas id="cv" width="400" height="400">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if(cv.getContext){
var ctx = cv.getContext('2d');
// 画一个描边三角形
ctx.beginPath();// 开启路径绘制
ctx.moveTo(25, 25);
ctx.lineTo(105, 25);
ctx.lineTo(25, 105);
ctx.lineTo(25, 25);
ctx.stroke();
// 画一个填充三角形
ctx.beginPath();// 重置路径绘制
ctx.moveTo(125, 125);
ctx.lineTo(205, 125);
ctx.lineTo(125, 205);
ctx.fill();
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
3、绘制圆弧
ctx.arc(圆心x坐标,圆心y坐标,半径,圆起始角(弧度),圆终止角(弧度),true(逆时针)/false(顺时针))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>绘制圆弧</title>
<style>
#cv {
border: 1px solid #999;
}
</style>
</head>
<body>
<canvas id="cv" width="400" height="400">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if (cv.getContext) {
var ctx = cv.getContext('2d');
for (var i = 0; i < 4; i++) { // 行
for (var j = 0; j < 3; j++) { // 列
ctx.beginPath();
var x = 25 + j * 50; // x坐标
var y = 25 + i * 50; // y坐标
var radius = 20; // 半径
var start = 0;
var end = Math.PI + j * Math.PI / 2;
var direction = i % 2 === 0 ? false : true;
ctx.arc(x, y, radius, start, end, direction);
if( i <= 1){
ctx.stroke();
}else {
ctx.fill();
}
}
}
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
4、贝塞尔曲线(了解)
二次贝塞尔曲线(由三个点组成):quadraticCurveTo(cp1x, cp1y, x, y)//绘制二次贝塞尔曲线(调整方向和线的弧度),cp1x,cp1y为一个控制点,x,y为结束点。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>二次贝塞尔曲线</title>
<style>
#cv {
border: 1px solid #999;
}
</style>
</head>
<body>
<canvas id="cv" width="200" height="150">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if (cv.getContext) {
var ctx = cv.getContext('2d');
ctx.beginPath(); // 开启一个路径的绘制
ctx.moveTo(75, 25);
ctx.quadraticCurveTo(25,25,25,62);
ctx.quadraticCurveTo(25,100,50,100);
ctx.quadraticCurveTo(50,120,30,125);
ctx.quadraticCurveTo(60,120,65,100);
ctx.quadraticCurveTo(125,100,125,62);
ctx.quadraticCurveTo(125,25,75,25);
ctx.lineWidth = 3;
ctx.strokeStyle = 'red';
ctx.stroke();
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
三次贝塞尔曲线(由四个点组成):bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>三次贝塞尔曲线</title>
<style>
#cv {
border: 1px solid #999;
}
</style>
</head>
<body>
<canvas id="cv" width="200" height="150">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if (cv.getContext) {
var ctx = cv.getContext('2d');
ctx.beginPath(); // 开启一 个路径的绘制
ctx.moveTo(75,40);
ctx.bezierCurveTo(75,37,70,25,50,25);
ctx.bezierCurveTo(20,25,20,62,20,62);
ctx.bezierCurveTo(20,80,40,102,75,120);
ctx.bezierCurveTo(110,102,130,80,130,62);
ctx.bezierCurveTo(130,62,130,25,100,25);
ctx.bezierCurveTo(85,25,75,37,75,40);
ctx.fillStyle = 'red';
ctx.fill();
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
说明:cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
5、绘制矩形
fillRect(x, y, width, height) // 绘制一个填充的矩形
strokeRect(x, y, width, height) // 绘制一个矩形的边框
clearRect(x, y, width, height) // 清除指定矩形区域,让清除部分完全透明。通常与fillRect()结合使用,可以绘制镂空效果或执行删除效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>绘制矩形</title>
<style>
#cv {
border: 1px solid #999;
}
</style>
</head>
<body>
<canvas id="cv" width="300" height="300">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if (cv.getContext) {
var ctx = cv.getContext('2d');
ctx.fillRect(100,100,100,100);
// ctx.strokeRect(50,100,150,100);
ctx.clearRect(120,120,50,50)
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
6、绘制文本
fillText(文本内容,x坐标,y坐标[,最大宽度]); // 绘制填充文本
strokeText(文本内容,x坐标,y坐标[,最大宽度]); // 绘制空心文本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>绘制文本</title>
<style>
#cv {
border: 1px solid #999;
}
</style>
</head>
<body>
<canvas id="cv" width="600" height="300">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if (cv.getContext) {
var ctx = cv.getContext('2d');
// ctx.fillText('学好前端,找一份高薪的工作!',100,100);
// ctx.fillText('学好前端,找一份高薪的工作!',100,100,100);
// ctx.font = '20px 微软雅黑'
// ctx.fillText('学好前端,找一份高薪的工作!',10,100);
ctx.font = '40px 微软雅黑'; // 设置字体、字号
ctx.strokeStyle = 'red';// 设置边框色
ctx.textAlign = 'left';// 设置对齐方式
ctx.textBaseline = 'bottom';// 设置基线
ctx.strokeText('学好前端,找一份高薪的工作!',10,150);
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
7、绘制图像
支持.png,.jpg,.gif以及canvas源。
第一步:var img = new Image(); // 创建一个img标签
第二步:img.src = '图片源'; // 设置图片源地址
第三步:
img.onload = function(){
ctx.drawImage(img, 100,100) // 绘制图像
}
7.1、基本绘制:ctx.drawImage(img, x,y); // img表示要绘制的图像,x和y表示图像绘制的起始坐标
7.2、绘制时同时进行缩放:ctx.drawImage(img, x,y,width,height); // width表示缩放后的宽度,height为高度
7.3、生成切片:
ctx.drawImage(img,sx,sy,swidth,sheight,dx,dy,dwidth,dheight);
sx,sy,swidth,sheight:用于对源图形成切片,多余部分会被裁切掉;
dx,dy,dwidth,dheight:表示切片在canvas画布中绘制的位置及大小。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>绘制图像</title>
<style>
#cv {
border: 1px solid #999;
}
</style>
</head>
<body>
<canvas id="cv" width="600" height="300">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if (cv.getContext) {
var ctx = cv.getContext('2d');
var img = new Image();
// img.src = 'images/Canvas_backdrop.png'
img.src = 'images/rhino.jpg'
img.onload = function(){
// 基本绘制
// ctx.drawImage(img, 100,100);
// 缩放
ctx.drawImage(img, 100,100,100,100,100,100,150,150);
// 生成切片
}
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>
8、其他
save():保存环境状态
restore():恢复到上一个保存的状态点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>save和restore方法</title>
<style>
#cv {
border: 1px solid #999;
}
</style>
</head>
<body>
<canvas id="cv" width="600" height="300">您的浏览器不支持canvas</canvas>
</body>
<script>
var cv = document.getElementById('cv');
if (cv.getContext) {
var ctx = cv.getContext('2d');
var img = new Image();
ctx.fillRect(50,50,150,150);
ctx.save();// 设置保存点(restore()的还原点)
ctx.fillStyle = '#fff';
ctx.fillRect(80,80,80,80);
ctx.save();
ctx.fillStyle = 'red'
ctx.fillRect(100,100,40,40);
ctx.restore();// 还原到上一个还原点
ctx.restore();
ctx.fillRect(110,110,20,20);
} else {
console.log('您的浏览器不支持canvas!');
}
</script>
</html>