canvas学习(一):线条,图像变换和状态保存

canvas学习(一):线条,图像变换和状态保存

一:绘制一条线段:

var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')

//状态设置
ctx.moveTo(0,300)
ctx.lineTo(400,300)
ctx.lineWidth = 20
ctx.strokeStyle = '#ddd'

ctx.stroke() //执行绘制

二:绘制三条不同颜色的线段:

var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')

ctx.lineWidth = 20
//状态设置
ctx.beginPath()
ctx.moveTo(0,200)
ctx.lineTo(400,300)
ctx.strokeStyle = '#ddd'
ctx.stroke() //执行绘制

ctx.beginPath()
ctx.moveTo(100,300)
ctx.lineTo(500,300)
ctx.strokeStyle = '#333'
ctx.stroke() //执行绘制

ctx.beginPath()
ctx.moveTo(200,400)
ctx.lineTo(600,300)
ctx.strokeStyle = '#red'
ctx.stroke() //执行绘制

beginPath()表示进行一次新的路径绘制。

三:多边形的绘制和closePath

1:封闭箭头

var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')

//状态设置
ctx.moveTo(20,300)
ctx.lineTo(400,300)
ctx.lineTo(400,200)
ctx.lineTo(700,350)
ctx.lineTo(400,500)
ctx.lineTo(400,400)

ctx.lineTo(20,400)
ctx.lineTo(20,300)
ctx.lineWidth = 20
ctx.strokeStyle = '#ddd'
ctx.stroke() //执行绘制

  canvas学习(一):线条,图像变换和状态保存

注意:当我们使用上述方法时,线段在封闭时会出现一点点缺口。所以我们需要baginPath和closePath结合使用:

//状态设置
ctx.beginPath()
ctx.moveTo(20,300)
ctx.lineTo(400,300)
ctx.lineTo(400,200)
ctx.lineTo(700,350)
ctx.lineTo(400,500)
ctx.lineTo(400,400)

ctx.lineTo(20,400)
//ctx.lineTo(20,300)  //这一段可以省略。closePath会自动连接
ctx.closePath()
ctx.lineWidth = 20
ctx.strokeStyle = '#ddd'
ctx.stroke() //执行绘制

  

2:填充箭头:在上述代码后面添加

ctx.fillStyle="red"
ctx.fill()

  canvas学习(一):线条,图像变换和状态保存

注意:从这张图我们可以发现,边框的宽度变细了。那是因为填充色在边框色后面执行了,会覆盖掉边框的部分颜色。所以我们要记住:

          在绘制一个需要填充的描边图案时,需要先填充,后描边

ctx.fillStyle="red" 
ctx.fill()   //填充
ctx.strokeStyle = '#ddd'  
ctx.stroke() //描边

  

因为canvas是基于状态绘制的,所以我们可以将设置状态的代码放一起,将绘制的代码放一起:

ctx.beginPath()
ctx.moveTo(20,300)
ctx.lineTo(400,300)
ctx.lineTo(400,200)
ctx.lineTo(700,350)
ctx.lineTo(400,500)
ctx.lineTo(400,400)

ctx.lineTo(20,400)
ctx.lineTo(20,300)
ctx.closePath()

//状态设置
ctx.lineWidth = 20
ctx.fillStyle="red"
ctx.strokeStyle = '#ddd'

//执行绘制
ctx.fill()
ctx.stroke() 

  

3:定义一个绘制填充描边矩形的函数:

function draw(ele,startX,startY,width,height,lineW,fillColor,strokeColor) {
	var canvas = document.getElementById(ele)
	    ctx    = canvas.getContext('2d')

	ctx.beginPath();
	ctx.moveTo(startX, startY);
	ctx.lineTo(startX+width,startY);
	ctx.lineTo(startX+width,startY+height);
	ctx.lineTo(startX,startY+height);
	ctx.closePath();

	ctx.lineWidth = lineW;
	ctx.fillStyle = fillColor ? fillColor: 'black'  //默认颜色
	ctx.strokeStyle = strokeColor ? strokeColor: '#ddd'   //默认颜色

	ctx.fill();
	ctx.stroke();
}

draw("myCanvas", 100, 100, 200, 300, 20)

  

  

四:矩形,覆盖和透明色

1:绘制矩形的方法:rect()

canvas学习(一):线条,图像变换和状态保存

2:绘制填充矩形的方法:fillRect()

canvas学习(一):线条,图像变换和状态保存

3:绘制描边矩形的方法:strokeRect()

canvas学习(一):线条,图像变换和状态保存

4:设置颜色值:

颜色名,rgb, rgba,hsl, hsla,渐变色等

例如使用渐变色:

var g = ctx.createLinearGradient(0,0,180,0);  //创建渐变对象  渐变开始点和渐变结束点
g.addColorStop(0, '#A9D25B'); //添加颜色点 
g.addColorStop(1, '#FA5A2D'); //添加颜色点 
ctx.strokeStyle = g;     //使用渐变对象

  

五:线段的其他属性

1:lineCap:设置线段两端的形状 ( butt[default],round【圆头】,square【方头】)

canvas学习(一):线条,图像变换和状态保存

注意:只能用于线段的开头出和结尾处

2:lineJoin:设置线段和线段相交时的形态 ( miter[default],bevel【斜切】,round【圆头】)

canvas学习(一):线条,图像变换和状态保存            canvas学习(一):线条,图像变换和状态保存

3:miterLimit:需要一个非常尖锐的角时:

ctx.lineJoin = "miter"
ctx.miterLimit = 10  //这个数字10为默认值

  

六:画一个星星

canvas的坐标轴,X轴向右,Y轴向下!

canvas学习(一):线条,图像变换和状态保存

var canvas = document.getElementById("canvas")
var ctx = canvas.getContext('2d')
			

function drawStar(ctx,R,r,x,y,rot) {
	ctx.beginPath();

	for (var i = 0; i <=5; i++) {
		ctx.lineTo(
			Math.cos((18+i*72 - rot)/180*Math.PI) * R +x,
			-Math.sin((18+i*72 - rot)/180*Math.PI) * R +y
		)
		ctx.lineTo(
			Math.cos((54+i*72 - rot)/180*Math.PI) * r +x,
			-Math.sin((54+i*72 - rot)/180*Math.PI)* r +y
		)
	}
	ctx.closePath();
	ctx.lineWidth = 10;
	ctx.stroke()
}

drawStar(ctx,300,150,400,400,20)

 

七:画一片星空

var canvas = document.getElementById("canvas")
var ctx = canvas.getContext('2d')
			
ctx.fillStyle = "black"
ctx.fillRect(0,0,canvas.width,canvas.height)

function drawStar(ctx,R,r,x,y,rot) {
		ctx.beginPath();

		for (var i = 0; i <=5; i++) {
			ctx.lineTo(
			      Math.cos((18+i*72 - rot)/180*Math.PI) * R +x,
				-Math.sin((18+i*72 - rot)/180*Math.PI) * R +y
			)
			ctx.lineTo(
				Math.cos((54+i*72 - rot)/180*Math.PI) * r +x,
				-Math.sin((54+i*72 - rot)/180*Math.PI)* r +y
			)
		}
		ctx.closePath();
		ctx.lineWidth = 3;
		ctx.lineJoin = "round"
		ctx.fillStyle="#fb3"
		ctx.strokeStyle="#fd5"
		ctx.fill()
		ctx.stroke()

}

for(var i=0;i<=100;i++){
	var r = Math.random() *10 +10;
	//var x = Math.random()*canvas.width
	//var y = Math.random()*canvas.height
	var x=Math.abs(Math.random()*canvas.width- 2*r)+r;
	var y=Math.abs(Math.random()*canvas.height- 2*r)+r;

	var a = Math.random()*360
	drawStar(ctx,r,r/2,x,y,a)
}

  

八:图像变换和状态保存:

translate() 方法:移动画布到相应位置

rotate() 方法:旋转当前的绘图

scale() 方法:缩放当前绘图,更大或更小 (副作用:对位置,边框大小等都会进行改变)

注意:我们在多次使用图像变化的方法时,后续的使用会在之前使用的基础上。例如:

ctx.fillStyle = "red"
ctx.translate(100,100)  // 先执行操作
ctx.fillRect(0,0,400,400) // 后执行绘制

ctx.fillStyle = "green"
ctx.translate(300,300)
ctx.fillRect(0,0,400,400)

此时第二个点的左边会基于第一个点移动,所以变成了 400,,40 。此时我们需要用到状态保存save和restore

ctx.save()
ctx.fillStyle = "red"
ctx.translate(100,100)
ctx.fillRect(0,0,400,400)
ctx.restore()

ctx.save()
ctx.fillStyle = "green"
ctx.translate(300,300)
ctx.fillRect(0,0,400,400)
ctx.restore()

  

  

八:深入理解图形变换:

利用transform()替换 translate(),rotate(),scale():
canvas学习(一):线条,图像变换和状态保存canvas学习(一):线条,图像变换和状态保存

注意:当我们在多次使用transform()时,每次的transform()都是基于上次效果之上的。所以我们可以使用setTransform()来回到特定的效果:

ctx.save()
ctx.transform(1,0,0,1,50,100)
ctx.transform(2,0,0,1.5,50,100)
ctx.setTransform(1,0,0,1,50,100)  //回到某个状态
ctx.restore()

  

原文地址:https://www.cnblogs.com/momozjm/p/7654713.html