什么是 canvas?
HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成.
<canvas> 标签只是图形容器,您必须使用脚本来绘制图形。
你可以通过多种方法使用 canvas 绘制路径,盒、圆、字符以及添加图像。
浏览器支持:
Internet Explorer 9、Firefox、Opera、Chrome 和 Safari 支持 <canvas> 标签的属性及方法。
注意:Internet Explorer 8 及更早的IE版本不支持 <canvas> 元素,IE9以上支持。
创建一个画布(Canvas)
一个画布在网页中是一个矩形框,通过 <canvas> 元素来绘制.
注意:
① 默认情况下 <canvas> 元素没有边框和内容
② 默认尺寸是宽度: 300px 高度: 150px
③ 不能够使用CSS去操作它的宽高 而是使用HTML标准属性去操作
在JS中操作css的方式是 元素.style.xx =
JS中操作html标准属性的方式是 元素.width =
注意: 标签通常需要指定一个id属性 (脚本中经常引用), width 和 height 属性定义的画布的大小.
提示: 可以在HTML页面中使用多个 <canvas> 元素.
<canvas id="myCanvas" width="200" height="100"></canvas>
使用 JavaScript 来绘制图像
canvas 元素本身是没有绘图能力的。所有的绘制工作必须在 JavaScript 内部完成:
上下文对象(画笔)
var ctx = canvas.getContext("2d");
属性:
canvas属性: 该画笔对应的画布元素
fillStyle:填充时使用的颜色
strokeStyle:描边时使用的颜色
font: 文本 决定文本的字号和字体
lineWitdh: 线宽
globalCompositeOperation: 融合 该属性在多个图形有交汇区域时决定谁覆盖谁 11种
方法:
beginPath( ): 用于开启路径
closePath( ): 用于闭合路径
弧度转角度: 360 deg = Math.PI * 2 => 1deg = Math.PI / 180
arc(x, y, r, start, end, boolean) 绘制圆弧
x:弧所在圆心点xy:弧所在圆心点y
r: 弧所在圆的半径
start: 开启的位置 (以弧度制表示)
end: 弧结束位置
boolean:顺时针绘制还是逆时针绘制
fill(): 用于填充路径
stroke(): 用于描边路径
clearRect(x,y,w,h)清除矩形区域内的所有像素
x:矩形左上角位于坐标系中的x位置
y:矩形左上角位于坐标系中的y位置
w:矩形宽
h:矩形高
fillRect(x, y, w, h) 填充矩形
x:矩形左上角位于坐标系中的x位置
y:矩形左上角位于坐标系中的y位置
w:矩形宽
h:矩形高
strokeRect(x, y, w, h) 描边矩形
x:矩形左上角位于坐标系中的x位置
y:矩形左上角位于坐标系中的y位置
w:矩形宽
h:矩形高
moveTo(x, y) 将画笔放在某个位置 不会产生路径
lineTo(x, y) 将画笔放在某个位置 会产生路径
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);
首先,找到 <canvas> 元素:
然后,创建 context 对象:
getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
下面的两行代码绘制一个红色的矩形:
ctx.fillRect(0,0,150,75);
设置fillStyle属性可以是CSS颜色,渐变,或图案。fillStyle 默认设置是#000000(黑色)。
fillRect(x,y,width,height) 方法定义了矩形当前的填充方式。
Canvas 坐标
canvas 是一个二维网格。
canvas 的左上角坐标为 (0,0)
x轴正方向向右 y轴正方向向下 原点位于canvas的左上角
Canvas 路径
在Canvas上画线条,我们将使用以下两种方法:
- moveTo(x,y) 定义线条开始坐标
- lineTo(x,y) 定义线条结束坐标
绘制线条必须使用到 "ink" 的方法,就像stroke()
//定义开始坐标(0,0), 和结束坐标 (200,100)。然后使用 stroke() 方法来绘制线条:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.moveTo(0,0);
ctx.lineTo(200,100);
ctx.stroke();
在canvas中,有不少方法都是在绘制路径,路径决定一块区域。路径默认是透明的。
路径不会显示出来的原因:路径默认是透明的,只有当描边或者填充之后才能看得到
// 获取元素
var canvas = document.getElementById("myCanvas");
// 获取画笔
var ctx = canvas.getContext("2d");
// 开始绘制路径
// 绘制路径之前要先调用一下beginPath方法
ctx.beginPath();
// 绘制圆
// canvas没有提供直接绘制圆的方法 而是提供了弧线的方法
ctx.arc(100, 100, 50, 0, Math.PI * 2, false); // arc方法只是绘制了弧线的路径 没有填充 没有描边 想要填充、描边请另行调用对应方法
// 闭合路径
// 绘制完毕路径之后 看情况是否需要闭合路径
ctx.closePath();
// 想要更改填充颜色
ctx.fillStyle = "rgba(33, 187, 143, .8)";
// 想要填充
ctx.fill();
// 想要更改描边颜色
ctx.strokeStyle = "rgba(33, 187, 143, .8)";
// 想要描边
ctx.stroke();
Canvas - 文本
使用 canvas 绘制文本,重要的属性和方法如下:
- font - 定义字体
- fillText(text,x,y) - 在 canvas 上绘制实心的文本
- strokeText(text,x,y) - 在 canvas 上绘制空心的文本
//使用 fillText():
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.fillText("Hello World",10,50);
//使用strokeText()
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.strokeText("Hello World",10,50);
Canvas - 渐变
渐变可以填充在矩形, 圆形, 线条, 文本等等, 各种形状可以自己定义不同的颜色。
以下有两种不同的方式来设置Canvas渐变:
- createLinearGradient(x,y,x1,y1) - 创建线条渐变
- createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
当我们使用渐变对象,必须使用两种或两种以上的停止颜色。
addColorStop()方法指定颜色停止,参数使用坐标来描述,可以是0至1.
使用渐变,设置fillStyle或strokeStyle的值为 渐变,然后绘制形状,如矩形,文本,或一条线。
//使用createLinearGradient()
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
// 创建渐变
var grd=ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// 填充渐变
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);
//使用createRadialGradient()
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
// 创建渐变
var grd=ctx.createRadialGradient(75,50,5,90,60,100);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// 填充渐变
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);
Canvas - 平移
平移坐标系:ctx.translate(x,y)
平移坐标系其实就是平移原点
x: 表示x轴平移量 x正方向朝右,反方向朝左
y: 表示y轴平移量 y正方向朝下,反方向朝上
Canvas - 旋转
旋转坐标系:ctx.rotate(x)
旋转坐标系其实就是以原点旋转
x: 表示弧度值 正数顺时针旋转 负数逆时针旋转
Canvas - 绘制图像
1. drawImage三个参数
drawImage(source, x, y);
source: 表示要绘制的源
x: 要将源图像以原尺寸放在canvas上的x点
y: 要将源图像以原尺寸放在canvas上的y点
2. drawImage五个参数
drawImage(source, x, y, w, h);
source: 表示要绘制的源
x: 要将源图像以w放在canvas上的x点
y: 要将源图像以h放在canvas上的y点
w: 展示宽度
h: 展示高度
3. drawImage九个参数
drawImage(source, img_x, img_y, img_w, img_h, canvs_x, canvas_y, canvas_w, canvas_h);
source: 表示要绘制的源
img_x img_y img_w img_h 共同确定图片上的一个矩形
canvas_x canvas_y canvas_w canvas_h 共同确定canvas上的一个矩形
效果: 将图片上的截取到的矩形内容展示在canvas上的矩形上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="1000" height="500"></canvas>
<script type="text/javascript">
// 获取元素
var myCanvas = document.getElementById("myCanvas");
// 获取画笔
var ctx = myCanvas.getContext("2d");
// 初始化Image构造函数
var img = new Image(); // 等价于 var img = document.createElement("img");
// 设置src
img.src = "imgs/head_pic.jpg";
// 图片有一个加载过程
// 当加载完成时 会触发onload事件
img.onload = function() {
// 可以通过this获取图片 可以使用img代表图片
console.log(this);
console.log(img);
// 绘制到canvas上
// 绘制的第一种方式 3个参数
// ctx.drawImage(img, 0, 0);
// 绘制的第二种方式 5个参数
// ctx.drawImage(img, 0, 0, 1000, 1000 / (2048 / 1365));
// 绘制的第三种方式 9个参数
ctx.drawImage(img, 900, 100, 825, 1265, 0, 0, 825, 1265);
}
</script>
</body>
</html>
Canvas - 绘制视频
跟绘制图像一样,把src换成视频的src地址
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<video src="video/2.mp4" autoplay></video>
<canvas id="myCanvas" width="1000" height="500"></canvas>
<script type="text/javascript">
// 获取元素
var myCanvas = document.getElementById("myCanvas");
// 获取画笔
var ctx = myCanvas.getContext("2d");
var video = document.getElementsByTagName("video")[0];
setInterval(function() {
ctx.drawImage(video, 0, 0);
}, 20)
</script>
</body>
</html>
Canvas - 保存和恢复状态
1. 保存
ctx.save() 该方法用于将ctx的状态保存一份。 相当于游戏的存档。
2. 恢复
ctx.restore() 该方法用于将ctx.save()方法保存的状态恢复。 相当于游戏的读档。
一次save对应一次restore。
canvas 操作像素
获取像素
ctx.getImageData(x,y,w,h)
注:该方法最好依赖于服务器环境
参数:
x:表示获取像素的矩形区域的左上角x点
y:表示获取像素的矩形区域的左上角y点
w: 表示获取像素的矩形区域的宽
h: 表示获取像素的矩形区域的高
返回值:ImageData对象
该实例有3个属性
data:是一个一维数组,里面包含了获取的矩形区域的所有像素点的信息,每4位表示一个像素点(r、g、b、a)
如:
第10个像素点的信息:
data[40] =>红 data[41] =>绿 data[42] =>蓝 data[43] =>透明度
width:宽
height:高
设置像素
对于ctx.getImageData()获取的ImageData对象的data进行修改之后,可以再次将这些修改后的像素放回canvas
ctx.putImageData(ImageData,x,y)
ImageData:获取的ImageData对象
x:放置的x
y:放置的y
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
canvas {
display: block;
margin: 100px auto;
border: 1px solid blue;
}
</style>
</head>
<body>
<canvas width="1000" height="500" id="myCanvas"></canvas>
<button id="red">去掉红色</button>
<button id="blue">去掉蓝色</button>
<button id="green">去掉绿色</button>
<button id="gray">灰度</button>
<script type="text/javascript">
// 获取元素
var canvas = document.getElementById("myCanvas");
var red = document.getElementById("red");
var blue = document.getElementById("blue");
var green = document.getElementById("green");
var gray = document.getElementById("gray");
// 获取画笔
var ctx = canvas.getContext("2d");
// 绘制一张图片
var img = new Image();
// 设置src
img.src = "imgs/head_pic.jpg";
// 设置onload事件
img.onload = function() {
ctx.drawImage(this, 0, 0, 1000, 600)
// 获取像素点的信息
// var imgData = ctx.getImageData(0, 0, 1000, 500);
// console.log(imgData);
}
red.onclick = function() {
// 获取像素点的信息 并把所有的红色像素去掉
var imgData = ctx.getImageData(0, 0, 1000, 500);
// 循环去掉所有红色
for(var i = 0; i < imgData.data.length; i += 4) {
imgData.data[i] = 0;
}
// 循环完毕 所有的红色信息已经去掉了 但是因为getImageData得到的是副本 也就是在这里修改 不会体现到canvas上
// 放回去
ctx.putImageData(imgData, 0, 0);
}
green.onclick = function() {
// 获取像素点的信息 并把所有的红色像素去掉
var imgData = ctx.getImageData(0, 0, 1000, 500);
// 循环去掉所有红色
for(var i = 1; i < imgData.data.length; i += 4) {
imgData.data[i] = 0;
}
// 循环完毕 所有的红色信息已经去掉了 但是因为getImageData得到的是副本 也就是在这里修改 不会体现到canvas上
// 放回去
ctx.putImageData(imgData, 0, 0);
}
blue.onclick = function() {
// 获取像素点的信息 并把所有的红色像素去掉
var imgData = ctx.getImageData(0, 0, 1000, 500);
// 循环去掉所有红色
for(var i = 2; i < imgData.data.length; i += 4) {
imgData.data[i] = 0;
}
// 循环完毕 所有的红色信息已经去掉了 但是因为getImageData得到的是副本 也就是在这里修改 不会体现到canvas上
// 放回去
ctx.putImageData(imgData, 0, 0);
}
gray.onclick = function() {
// 获取像素点的信息 并把所有的红色像素去掉
var imgData = ctx.getImageData(0, 0, 1000, 500);
// 循环去掉所有红色
for(var i = 0; i < imgData.data.length; i += 4) {
// 获取平均值
var avg = (imgData.data[i] + imgData.data[i + 1] + imgData.data[i + 2]) / 3;
imgData.data[i] = avg;
imgData.data[i + 1] = avg;
imgData.data[i + 2] = avg;
}
// 循环完毕 所有的红色信息已经去掉了 但是因为getImageData得到的是副本 也就是在这里修改 不会体现到canvas上
// 放回去
ctx.putImageData(imgData, 0, 0);
}
</script>
</body>
</html>
canvas 合成融合
ctx.globalCompositeOperation属性
值 | 描述 |
---|---|
source-over | 默认。在目标图像上显示源图像。 |
source-atop | 在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。 |
source-in | 在目标图像中显示源图像。只有目标图像之内的源图像部分会显示,目标图像是透明的。 |
source-out | 在目标图像之外显示源图像。只有目标图像之外的源图像部分会显示,目标图像是透明的。 |
destination-over | 在源图像上显示目标图像。 |
destination-atop | 在源图像顶部显示目标图像。目标图像位于源图像之外的部分是不可见的。 |
destination-in | 在源图像中显示目标图像。只有源图像之内的目标图像部分会被显示,源图像是透明的。 |
destination-out | 在源图像之外显示目标图像。只有源图像之外的目标图像部分会被显示,源图像是透明的。 |
lighter | 显示源图像 + 目标图像。 |
copy | 显示源图像。忽略目标图像。 |
xor | 使用异或操作对源图像与目标图像进行组合。 |