HTML5 canvas

什么是 canvas?

HTML5 <canvas> 元素用于图形的绘制,经过脚本 (一般是JavaScript)来完成.javascript

<canvas> 标签只是图形容器,您必须使用脚原本绘制图形。css

你能够经过多种方法使用 canvas 绘制路径,盒、圆、字符以及添加图像。html

浏览器支持:

Internet Explorer 九、Firefox、Opera、Chrome 和 Safari 支持 <canvas> 标签的属性及方法。java

注意:Internet Explorer 8 及更早的IE版本不支持 <canvas> 元素,IE9以上支持。canvas


建立一个画布(Canvas)

一个画布在网页中是一个矩形框,经过 <canvas> 元素来绘制.数组

注意: 浏览器

① 默认状况下 <canvas> 元素没有边框和内容服务器

② 默认尺寸是宽度: 300px 高度: 150pxide

③ 不可以使用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> 元素:

var c=document.getElementById("myCanvas");

而后,建立 context 对象:

var ctx=c.getContext("2d");

getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。

下面的两行代码绘制一个红色的矩形:

ctx.fillStyle="#FF0000";
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 使用异或操做对源图像目标图像进行组合。