基于html5 canvas的进度显示图表

文章出处:http://blog.csdn.net/huoer_12/article/details/38960955


Canvas的基本用法请参考这里,有对canvas的具体说明和浏览器版本的支持情况。

效果图:

chart_111

1.Canvas的坐标系

Canvas中的坐标如图所示:
坐标系
左上角为坐标原点,水平向右为X轴递增,垂直向下为Y轴递增。明白坐标系,就可以清晰的认识到如何计算坐标值。

但是,这个坐标系和我们平时的不一样,为了适合我们平时的习惯,就需要进行坐标系的转换,在这里不用提供的一些函数,如translate、scale等等,自己进行坐标的转换。
我们以坐标系中的某一点为中心(x‘ ,y’),我们假设画布的大小为100,100,中心点为(50,50),则转换坐标的函数为:
x坐标转化: x = x‘ + 50,其中x’为我们转化后的坐标系的值,x为Canvas坐标系的值
y坐标的转化: y = 50 - y’,同上;

坐标


转换之后,我们就可以按照习惯来使用了。

2.Canvas的画图API

var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
这两句就是先拿到Canvas的元素,载使用getContext拿到画布的画笔对象,也就是CanvasRenderingContext2D,多次取值都会拿到同一个对象。
g.beginPath();//开始一条新的路径
g.moveTo(0,0);//移动画笔到(0,0)点
g.lineTo(100,0);//从(0,0)点到(100,0)点画线,当前点为(100,0)
g.lineTo(100,100);//从当前点(100,0)到(100,100)点画线,当前点为(100,100)
g.lineTo(0,100);//从当前点(100,100)到(0,100)点画线,当前点为(0,100)
g.closePath();//关闭路径,将终点与起点进行闭合
g.lineWidth = 2;//线的宽度为2
g.stroke();//描边画线
从上面就可以看出来,到最后调用stroke的时候,才会把线条画出来,之前的都不止过是路径,没有真真的画上去。

g.arc(50,50,45,0,1,false);//画圆弧,(50,50)为圆心坐标,45为圆的半径,0为其实角度(弧度),1为终止角度(弧度),false为顺时针画弧

//角度转化为弧度
//角度转化为弧度制
		function rad(angle){
			return angle * Math.PI / 180;
		}

3.图表制作

效果图:

HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>绘制进度图表</title>
<script type="text/javascript" src="draw-chart.js"></script>
</head>
<body>

<div style="width: 100px;height: 100px; float: left; position: relative;">
	<canvas id="mycanvas" width=100 height=100></canvas>
	<label id="mytitle"></label>
	
	<button οnclick='paint()'>绘制</button>
</div>

<script type="text/javascript">
function paint(){
		showChart("mycanvas","mytitle",50);
		
	}
	
	
</script>
</body>
</html>

js代码:
	/**
	 * 绘制进度图表
	 * @param cs 	画布的ID
	 * @param lb 	显示进度的标签ID
	 * @param value 需要显示的进度值[0,100]
	 */
	function showChart(cs,lb,value){
		//如果不符合取值范围,则返回
		if(value > 100 || value < 0) return;
		//拿到画布和标签元素
		var canva = document.getElementById(cs);
		var title = document.getElementById(lb);
		canva.width = canva.width;
		title.textContent = "";
		
		//设置标签样式
		title.style.cssText = "display: block; position: absolute; top: 32px; left: 33px; font-size: 25px;font-family: Fantasy;";
		//拿到画布的上下文对象
		var g = canva.getContext('2d');
		g.beginPath();
		g.moveTo(0,0);
		g.lineTo(100,0);
		g.lineTo(100,100);
		g.lineTo(0,100);
		g.closePath();
		g.lineWidth = 2;
		g.stroke();
		//画出图像
		//先画出底盘,再画出进度值
		draw(500,100,"#CCCCCC",false,function(){
			draw(500,value,"green",true);
		});
		
		title.textContent = formatTitle(0);
		//角度转化为弧度制
		function rad(angle){
			return angle * Math.PI / 180;
		}
		//横坐标转化
		function tx(x){
			return x + 50;
		}
		//纵坐标转化
		function ty(y){
			return 50 - y;
		}
		//格式化标签的显示值,当为以为数字时,前面自动补个0
		function formatTitle(value){
			value += "%";
			return value.length == 1 ? 0 + value : value;
		}
		
		/**
		 * 画出圆环
		 * @param time 		绘制需要的时间,也就是动画的时间
		 * @param value 	画圆环的百分比值【0,100】
		 * @param color 	圆环的颜色值
		 * @param show 		是否显示进度值
		 * @param callback 	回调函数
		 */
		function draw(time,value,color,show,callback){
			//计算循环次数
			var count = Math.floor(time / 50);
			//总共需要画出圆环的角度
			var angle = value / 100 * 360;
			//每次需要画出的圆环角度
			var per = Math.floor(angle / count);
			var cur = -90;
			var pass = 0;
			var c = color || "green";
			//设置画笔的样式等
			g.fillStyle= c;
			g.strokeStyle = c;
			g.lineWidth = 1;
			if(!angle) return;
			
			var perValue = Math.floor(value / count);
			var curValue = 0;
			var timer = setInterval(function(){
				//debugger
				if(pass < angle && pass + per > angle){
					per = angle - pass;
					perValue = value - curValue;
				}
				//画出部分圆环
				g.beginPath();
				g.arc(tx(0),ty(0),45,rad(cur),rad(cur + per),false);
				//g.lineTo(tx(30 * Math.cos(rad(cur + per))),ty(30 * Math.sin(rad(cur + per))));
				g.arc(tx(0),ty(0),35,rad(cur + per),rad(cur),true);
				//g.lineTo(tx(40 * Math.cos(rad(cur))),ty(40 * Math.sin(rad(cur))));
				g.closePath();
				g.fill();
				g.stroke();
				if(show){
					curValue += perValue;
					if(curValue == 100) title.style.left = "25px";
					title.textContent = formatTitle(curValue);
				}
				
				pass += per;
				cur += per;
				//圆环完成后,清除timer,并执行回调函数
				if(pass >= angle){
					clearInterval(timer);
					if(callback) callback();
				}
			},50);
		}
	}

先画出底盘圆环,最后画出进度圆环,上面就是所有的代码。运行效果如图:

点击绘制可重新绘图。
chart_111
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值