canvas基础 | 七日打卡

838 阅读8分钟

一、理解

HTML5添加了非常受欢迎的功能就是元素。这个元素负责在页面中设定一个区域,然后就可以通过JavaScript动态的在这个区域绘制图形。

与浏览器环境的其他组件类似,由机组API构成,但并非所有浏览器都支持这些API,输了具备绘图能力的2D上下文,还建议了一个名为WebGL的3D上下文。目前,支持该元素的浏览器都支持2D上下文及文本API,但对于WebGL的支持还不够好。由于WebGL还是实验性的,因此要得到所有浏览器的支持还需要很长一段时间。

二、准备工作

要使用元素,必须先设置其width和height属性,指定可以绘图的区域大小,出现在开始和结束标签中的内容是后背信息,如果浏览器不支持,就会显示这些信息。

<canvas id="canvas" width="1000" height="500">您的浏览器版本不支持canvas,建议您升级浏览器</canvas>

与其他标签元素一样,元素的DOM元素对象也有基本属性height,width,可以随意修改,也能通过css为该元素添加样式。如果不添加任何样式,在页面中是看不到该元素的。

要在这块画布上画图,需要取得绘图上下文。即调用getContext()方法并传入上下文的名字。传入“2d”就可以取得2D上下文对象。

var ctx = canvas.getContext("2d")

但是在使用元素之前,最后先检测getContext()方法是否存在。

<script>
//获取canvas的DOM节点
var canvas = document.querySelector("#canvas");
//确定浏览器支持<canvas>元素
  if ( ctx.getContext ){
     var ctx = canvas.getContext("2d")
  }
</script>

三、2D上下文

使用2D绘图上下文提供的方法,可以绘制见得2D图形,比如矩形,弧线和路径。2D上下文的坐标开始于元素的左上角,原点坐标是(0,0),所有坐标值都基于这个原点计算,width和height表示水平和垂直两个方向上可用的像素数目。

四、关于绘制

4.1填充和描边

fillStyle:填充
strokeStyle:描边
这两个属性的值可以是字符串,渐变对象,默认颜色是#000000,但是支持使用css中指定的颜色值得任何形式

4.2绘制矩形

矩形是唯一一种可以直接绘制的形状。

4.2.1 实心矩形:fillRect(x,y,宽,高)

矩形是唯一一种可以直接绘制的形状。 四个参数,分别代表x坐标,y坐标,宽,高

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	//改变背景颜色,默认背景颜色是黑色
    //注意:要先给填充颜色,否则会默认效果是黑色
	ctx.fillStyle="pink";						
	//绘制在坐标x,y位置的一个宽
	ctx.fillRect(100,100,200,200);
</script>

效果
捕获.PNG

4.2.2边框矩形:strokeRect(x,y,宽,高)

四个参数,分别代表x坐标,y坐标,宽,高

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	//改变背景颜色,默认背景颜色是黑色
	ctx.strokeStyle = "deeppink"					
	//绘制在坐标x,y位置的一个宽
	ctx.strokeRect(100,100,200,200);
</script>

效果

捕获.PNG

4.2.2清除矩形:clearRect(x,y,宽,高)

清除矩形在页面中单独使用时看不出来,在某个图形区域内使用,用来清除一块区域

四个参数,分别代表x坐标,y坐标,宽,高

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	ctx.fillStyle="pink";//改变背景颜色
	ctx.fillRect(100,100,200,200)//默认背景颜色是黑色
	//绘制一个清除矩形,清除图像上的一块区域
	ctx.clearRect(150,150,100,100);
</script>

效果

捕获.PNG

4.3路径绘制

通过绘制路径可以创造出复杂的形状和线条。 首先先调用beginPath()方法,表示要开始绘制新路径。然后再调用方法来实际的绘制路径。

4.3.1绘制直线

画直线的顺序

1.开始绘制:ctx.beginPath() 2.起点:ctx.moveTo(x,y); 3.终点:ctx.lineTo(x,y); 4.绘制:ctx.stroke(); 5.结束绘制:ctx.closePath();

参数x,y为坐标

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	//开始绘制
	ctx.beginPath();
	//绘制起点
	ctx.moveTo(100,150);
	//绘制终点
	ctx.lineTo(200,250);
	//绘制
	ctx.stroke();
	//结束路径
	ctx.closePath();
</script>

效果

捕获.PNG

4.3.1绘制线段三角形

画三角形顺序

1.开始绘制:ctx.beginPath() 2.起点:ctx.moveTo(x,y); 3.绘制一点:ctx.lineTo(x1,y1); 4.绘制下一点:ctx.lineTo(x2,y2); 5.回到起点:ctx.lineTo(x,y); 4.绘制:ctx.stroke(); 5.结束绘制:ctx.closePath();

参数x,y为坐标

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	//绘制边框三角形
	//开始路径
	ctx.beginPath();
	//起始点
	ctx.moveTo(450,100);
	//终点
	ctx.lineTo(600,100);
	//继续画
	ctx.lineTo(600,200);
	//回到起点
	ctx.lineTo(450,100);
	//绘制
	ctx.stroke();
	//结束路径
	ctx.closePath();
</script>

效果
捕获.PNG

4.3.2绘制实心三角形

画三角形顺序

1.开始绘制:ctx.beginPath( ) 2.起点:ctx.moveTo( x , y ); 3.绘制一点:ctx.lineTo( x1 , y1 ); 4.绘制下一点:ctx.lineTo( x2 , y2 ); 5.回到起点:ctx.lineTo( x , y ); 4.绘制:ctx.fill( ); 5.结束绘制:ctx.closePath( );

参数x,y为坐标

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	//绘制边框三角形
	//开始路径
	ctx.beginPath();
	//起始点
	ctx.moveTo(450,100);
	//终点
	ctx.lineTo(600,100);
	//继续画
	ctx.lineTo(600,200);
	//回到起点
	ctx.lineTo(450,100);
	//改变背景颜色
	ctx.fillStyle="pink";
	//绘制
	ctx.fill();
	//结束路径
	ctx.closePath();
</script>

效果

捕获.PNG

4.3.3绘制圆形

ctx.arc(x,y,半径,起始角度,终止角度,方向(true表示逆时针,false表示顺时针));

参数分别代表:

绘制弧形的参数分别是: 弧形圆心x坐标、 y坐标、 半径、 起始角(以3点钟的位置开始)、 结束角、 方向(true表示逆时针,false表示顺时针)

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	//绘制边框三角形
	//开始路径
	ctx.beginPath();
	//绘制圆
	ctx.arc(650,350,100,0,Math.PI*2,false);
	ctx.fill();//实心圆
   //ctx.stroke();空心圆
	ctx.closePath();
</script>

效果

捕获.PNG

注意:
绘制弧形的时候,只需改变终止的角度即可。Math.PI*2,表示绘制2π弧度,也就是一个整圆。

4.4绘制文本

绘制文本主要有两个方法。

fillText():使用fillStyle属性绘制文本;
strokeText():使用strokeStyle属性为文本描边;

一般使用fillText(),因为该方法模仿了网页中正常显示文本。

这两个方法都可以接收4个参数。绘制的文本字符串、x坐标,y坐标,可选的最大像素宽度

但是,这两个方法都以下列3个属性为基础 font:文本样式,大小及字体 textAlign:表示文本对齐方式 textBaseline:表示文本的基线

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	ctx.font = "bold 20px Arial"
	ctx.textAlign = "center"
	ctx.textBaseline = "middle"
	ctx.fillText("文本信息",300,100)
</script>

效果

捕获.PNG

额外信息

因为这里把textAlign设置为center,把textBaseline设置为middle,所以坐标(300,100)表示的文本水平和垂直终点的坐标。如果将textAlign设置为start,则x坐标表示的是文本左端的位置(从左到右阅读的语言);设置为end,则x坐标表示的是文本右端的位置。

栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	ctx.font = "bold 20px Arial"
	
	ctx.textAlign = "center"
	ctx.textBaseline = "middle"
	ctx.fillText("文本信息",300,100)
	
	ctx.textAlign = "start"
	ctx.fillText("文本信息",300,150)
	
	ctx.textAlign = "end"
	ctx.fillText("文本信息",300,200)
</script>

效果

捕获.PNG

4.5变换

通过上下文的变化,可以吧处理后的图像绘制到画布上。2D绘制上下文支持各种基本绘制变换,创建绘制上下文时,会以默认值初始化变换矩阵,在默认的变换矩阵下,所有处理都按照描述直接绘制,为绘制上下文应用变换,会导致使用不同的变换矩阵应用处理,从而产生不同的结果。

可以通过如下方法来修改变换
rotate(angle): 围绕原点旋转图像angle弧度

scale(scaleX,scaleY): 缩放图像,在x轴方向乘以scaleX,在y轴方向乘以scaleY,scaleX和scaleY的默认值都是1.0

translate(x,y): 将坐标原点移动到(x,y)。执行这个操作后,坐标(0,0)会变成之前由(x,y)表示的点。

由于暂时无特别的小栗子助于消化,以后有好的小例子会补充_

4.6 绘制图像

2D绘图上下文内置了对对象图像的支持。如果你想把一幅图像绘制到画布上,可以使用drawImage()方法

drawImage(image,x,y):表示在坐标(image,x,y)点绘制图像,图像大小和原始大小一致

drawImage(image,x,y,width,height):表示在坐标(x,y)处绘制图像,图像的宽是width,高是height

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	var image = new Image();
	image.src="biyezhao.jpg";
	image.onload = function(){
		//保持原大小绘制图片
		ctx.drawImage(image,10,10);
	}	
</script>

drawImage(image,x,y,width,height,x1,y2,width2,height2):可以把图像中的某个区域绘制到上下文中

效果

参数分别表示 要绘制的图像, 源图像的x坐标, 源图像的y坐标, 源图像的宽度, 源图像的高度, 目标兔小的x坐标, 目标图像的y坐标, 目标图像的宽度, 目标图像的高度

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	var image = new Image();
	image.src="biyezhao.jpg";
	image.onload = function(){
		//保持原大小绘制图片
		//ctx.drawImage(image,10,10);
		//绘制出来的图像是100X100像素大小
		//ctx.drawImage(image,10,10,100,100);
		//截取图像中的某一部分绘制的画布上
		ctx.drawImage(image,500,360,100,100,50,50,100,100);
	}
</script>

4.7阴影

2D上下文会根据以下几个属性的值,自动为形状或路径绘制出阴影。
shadowColor: 用css颜色格式表示的阴影颜色,默认为黑色。
shadowOffsetX: 形状或路径x轴方向的阴影偏移量,默认为0。
shadowOffsetY: 形状或路径y轴方向的阴影偏移量,默认为0。
shadowBlur: 模糊的像素数,默认0,即不模糊。

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	ctx.shadowOffsetX = 5;
	ctx.shadowOffsetY = 5;
	ctx.shadowBlur = 4;
	ctx.shadowColor = "rgba(2,0,0,0.5)";
	ctx.fillStyle = "yellowgreen"
	ctx.fillRect(100,100,200,200);
</script>

4.8 渐变

渐变由CanvasGradient实例表示,很容易通过2D上下文来创建和修改,要创建一个新的线性渐变,可以调用createLinearGradient()方法。

createLinearGradient(x1,y1,x2,y2) 四个参数分别代表起点x的坐标,起点的y坐标,终点的x坐标,终点的y坐标。调用这个方法后,会创建一个指定大小的渐变,并返回CanvasGradient对象的实例。

创建渐变对象后,使用addColorStop()方法来指定色标。这个方法接收两个参数,css的色标位置和css颜色值。

色标位置是一个0(开始的颜色)到1(结束的颜色)之间的数字。

举个栗子

<script>
	var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	var image = new Image();
	//创建一个线性渐变区域
	var gradient = ctx.createLinearGradient(100,100,300,300);
	//指定色标
	gradient.addColorStop(0,"red");
	gradient.addColorStop(1,"blue");
	//此时gradient表示的是一个从画布上(100,100)到(300,300)
	//的渐变,起点是红色,终点是蓝色,然后就可以fillStyle
	//或strokeStyle设置这个对象
	ctx.fillStyle = gradient;
	ctx.fillRect(100,100,100,100);
</script>

效果

此时渐变只是副高这个矩形的一部分,要想让渐变覆盖整个矩形,矩形和渐变的坐标必须匹配才行。如果没有吧矩形绘制到恰当的位置,那可能就会只显示部分渐变的效果。

4.9 模式

模式其实就是重复的图像,可以用来填充或描边图形。要创建一个新模式,可以调用createPattern()方法,传入两个参数。一个html 的img标签元素,一个是否重复的字符串。repeat,no-repeat,repeatX,repeatY

举个栗子

var canvas = document.querySelector("#canvas");
	var ctx = canvas.getContext("2d");
	var image = new Image();
	image.src="1.PNG";
	image.onload = function(){
		pattern = ctx.createPattern(image,"repeat");
		ctx.fillStyle = pattern;
		ctx.fillRect(0,0,700,400)
	}
</script>

补一个小知识点

lineJoin :当两条线相交时,设置返回所创建边角的类型。
bevel : 创建斜角
round : 创建圆角
miter : 默认,创建尖角