JS——canvas基础及其应用

JS——canvas及其应用

一、canvas基础

1、canvas——画布:
  • canvas本身没有外观,只是一个画板

  • IE9以前不支持

  • canvas不要使用css来定义大小,要直接使用自身的属性width、height来设置并且不带单位

  • 可用getContext()方法来返回一个画笔

  • 可用于可视化数据、游戏等的制作

2、let pen = canvas.getContext()——画笔:
  • pen.moveTo(x,y):设置一个新的起点,用于画一些不连续的线条

  • pen.lineTo(x,y):轨迹,上一次的终点是下一次轨迹的起点,通常与moveTo方法配合使用

  • pen.closePath():闭合轨迹,将终点和起点连接起来,灵活使用可以在画闭合图形时不必画最后一条线

  • pen.strokStyle:轨迹颜色,默认是黑色,可以识别多种颜色表示方法

  • pen.lineWidth:轨迹宽度,设置后在该位置上内外各一半

  • pen.fillStyle:填充颜色,可以识别多种颜色表示方法

  • pen.fill():填充,不写默认不填充,写了默认黑色,仅封闭图形才可以使用填充方法

  • pen.strok():沿轨迹绘制,不写无法显示,写了默认关闭路径,下一次使用要重新打开路径

  • pen.beginPath():打开新的路径

  • pen.arc(x,y,r,start,end,bool):画圆弧,x,y为圆心坐标,r是圆半径,start是起始弧度,end是结束弧度,bool指是否逆时针;设置起始弧度为0,结束弧度为2PI,可以画圆,再设置lineWidth可以画出小圆点

  • pen.font:设置字体样式的符合属性,可以像css那样用

  • pen.fillText(text,x,y):填充文字,text指要填充的文字,x,y指填充开始位置

  • pen.textAlign:设置文字垂直和水平位置

  • pen.textBaseline:设置基线,即文字中间位置线

使用画笔画出一个矩形的四种方法:

方法 描述
pen.rect(x,y,width,height) x,y为矩形左上角坐标,可以用fill填充颜色并且有边框不透明
pen.fillRect(x,y,width,height) x,y为矩形左上角坐标,无边框只有填充不透明
pen.fillRect(x,y,width,height) x,y为矩形左上角坐标,只有边框没有填充色,无法使用fill填充颜色,并且透明重合在其他颜色上面时可以看到下面的颜色
lineTo(x,y) 通过计算坐标值画出矩形

二、canvas应用实例

1、使用LineTo()或moveTo()画个小红旗:
        <canvas width="500" height="500"></canvas>
		<script type="text/javascript">
			let canvas = document.querySelector('canvas');
			let pen = canvas.getContext('2d');
			pen.lineTo(100,50);
			//绘制时会将上一个点当做起点
			pen.lineTo(150,100);
			pen.lineTo(100,100);
			pen.lineTo(100,50);
			pen.lineTo(100,300);
			pen.lineTo(80,300);
			pen.lineTo(50,330);
			pen.lineTo(150,330);
			pen.lineTo(120,300);
			pen.lineTo(100,300);
			pen.strokeStyle = 'red';
			pen.stroke();
		</script>
2、使用canvas画个简单的折线图:
 <canvas width="500" height="500" style="border: 1px solid black;"></canvas>
		
		<script type="text/javascript">
			let canvas = document.querySelector('canvas');
			let pen = canvas.getContext('2d');
			
			let data = [
				{x: 20, y: 80},
				{x: 60, y: 20},
				{x: 100, y: 40},
				{x: 140, y: 200},
				{x: 180, y: 90},
				{x: 220, y: 130},
				{x: 260, y: 50},
				{x: 300, y: 70}
			]
			
			let step1 = 10;
			//画出表格,每个小格子宽度10
			for(let i = 0; i <= canvas.width/step1; i++){
				
				pen.moveTo(0,i*step1);
				pen.lineTo(canvas.width,i*step1);
				
				pen.moveTo(i*step1,0);
				pen.lineTo(i*step1,canvas.width);
				
			}
			pen.strokeStyle = 'lightgray';
			pen.stroke();
			
			pen.beginPath();
			let step2 = 50;
		    //隔50画出表格标重线
			for(let i = 0; i <= canvas.width/step2; i++){
				
				pen.moveTo(0,i*step2);
				pen.lineTo(canvas.width,i*step2);
				
				pen.moveTo(i*step2,0);
				pen.lineTo(i*step2,canvas.width);
				
			}
			pen.strokeStyle = 'grey';
			pen.stroke();
			
			pen.beginPath();
			//画出折线
			for(let i = 0; i < data.length; i++){
				pen.lineTo(data[i].x,data[i].y);
			}
			
			pen.strokeStyle = 'burlywood';
			pen.lineWidth = 5;
			pen.stroke();
			
			let deg = Math.PI/180;
			//画出每个转折点圆圈
			for(let i = 0; i  < data.length; i++){
				pen.beginPath();
				pen.arc(data[i].x,data[i].y,5,0,360*deg);
				pen.closePath();
				pen.fillStyle = 'burlywood';
				pen.fill();
				pen.stroke();
			}
			
		</script>
3、使用canvas画出扇形图:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
<canvas width="500" height="500" style="border: 1px solid black;"></canvas>
        
		<script>
			let consume = [
				{
					name: "电子产品",
					money: 5003
				},
				{
					name: "美妆",
					money: 1500
				},
				{
					name: "日用品",
					money: 2050
				},
				{
					name: "蔬菜水果",
					money: 4300
				},
				{
					name: "服装",
					money: 6700
				}
			]
			
			let canvas = document.querySelector('canvas');
            let pen = canvas.getContext('2d');
			
			let deg = Math.PI/180;
			
			consume.sort(function(a, b){return b.money - a.money});
			let sumMoney = consume.reduce((pre,next) => {
				return {
					money: pre.money + next.money
				};
			})
			
			function  showRotate(pointX, pointY, r){
				
				let start = 30*deg;
				
				for(let i = 0; i < consume.length; i++){
					let end = consume[i].money/sumMoney.money*360*deg + start;
					console.log(end)
					
					let x = Math.cos(start)*r + pointX;
					let y = Math.sin(start)*r + pointY;
					
					pen.beginPath();
					pen.moveTo(pointX,pointY);
					pen.lineTo(x,y);
					pen.arc(pointX,pointY,r,start,end);
					let random = Math.random().toString(16).substr(-6);
					pen.fillStyle = '#' + random;
					pen.fill();
					pen.stroke();
					
					// 画矩形框表示每一个扇形所代表的含义
					pen.fillRect(400, 100+i*30, 20, 20);
					// 绘制文本表示含义
					pen.beginPath();
					pen.font = "14px 楷体";
					pen.textAlign = "left";
					pen.textBaseline = "middle";
					pen.fillStyle = "#333";
					pen.fillText(consume[i].name, 430, 110+i*30)
					
					// 在扇形内部绘制文本表示百分比
					let mid = (end - start)/2 + start; //获取扇形中间那个弧度
					let midX = Math.cos(mid)*r/2 + pointX;
					let midY = Math.sin(mid)*r/2 + pointY;
					pen.beginPath();
					let text = (consume[i].money/sumMoney.money * 100).toFixed(2) + "%";
					pen.fillStyle = "red";
					pen.font = "16px 楷体";
					pen.textAlign = "center";
					pen.textBaseline = "middle";
					pen.fillText(text, midX, midY);
					start = end;
				}
			}
			showRotate(200,200,100);
			// showRotate(100,400,100);
			
		</script>
	</body>
</html>

4、画一个评分五角星:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			canvas {
				border: 1px solid red;
			}
		</style>
	</head>
	<body>
		
		<canvas id="canvas" width="200" height="40"></canvas>
		
		<script type="text/javascript">
			let canvas = document.getElementById("canvas");
			let ctx = canvas.getContext("2d");
			let deg = Math.PI/180;
			let r = 20;
			paintstar(r, 0);
			canvas.onclick = function(e) {
				paintstar(r, Math.ceil(e.pageX/(2*r)));
			}
			function paintstar(r, rank) {
				for(let i =0; i < canvas.width/(2*r); i++) {
					if(i < rank) {
						strokestar(i*2*r+r, r, "yellow");
					} else {
						strokestar(i*2*r+r, r, "grey");
					}
				}
			}
			function strokestar(x, r, color="grey") {
				let angle = 72*deg; //以五角星上面的点为起点,每个角之间的角度是72°
				let orgin = {x, y: canvas.height/2}; //表示五角星所在圆心点的坐标,y轴位置不变
				let absx = (num) => orgin.x + Math.cos(-90*deg + angle*num)*r;
				let absy = (num) => orgin.y + Math.sin(-90*deg + angle*num)*r
				let p1 = {x: absx(0), y: absy(0)};
				let p2 = {x: absx(1), y: absy(1)};
				let p3 = {x: absx(2), y: absy(2)};
				let p4 = {x: absx(3), y: absy(3)};
				let p5 = {x: absx(4), y: absy(4)};
				// 绘制五角星
				ctx.beginPath();
				ctx.lineTo(p1.x, p1.y);
				ctx.lineTo(p3.x, p3.y);
				ctx.lineTo(p5.x, p5.y);
				ctx.lineTo(p2.x, p2.y);
				ctx.lineTo(p4.x, p4.y);
				ctx.closePath();
				ctx.fillStyle = color; //设置填充颜色
				ctx.fill();
				ctx.strokeStyle = color; //设置线条颜色
				ctx.stroke()
			}
		</script>
	</body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_42602282/article/details/107197540