canvas环形进度条

利用canvas绘制环形进度条

组件对canvas绘制模糊问题进行了处理。
根据dpr,扩大canvas画布的像素,使1个canvas像素和1个物理像素相
由于画布扩大,canvas的坐标系也跟着扩大,如果按照原先的坐标系绘图内容会缩小
所以需要将绘制比例放大

  • 使用
progressRing({
	el: document.getElementById("canvas"), //绘制对象
	width: 130,
	height: 130,
	lineWidth: 6,
	lineCap: 'round',
	forecolor: ['#FF0034', '#F97777'],
	bgcolor: "#FFF",
	direction: true,
	tip: {text: '总进度', fontSize: 10, color: '#FF5555'},
	percent: {text: 50, fontSize: 20, color: '#FF5555'}
});
  • 环形进度条封装
/* ===============================
	 * progress圆环进度条
	 * versions 1.0.0
	 * cl15095344637@163.com
	 * @example:
	    progressRing({
			el: document.getElementById("canvas"), //绘制对象
			width: 130,
			height: 130,
			lineWidth: 6,
			lineCap: 'round',
			forecolor: ['#FF0034', '#F97777'],
			bgcolor: "#FFF",
			direction: true,
			tip: {text: '总进度', fontSize: 10, color: '#FF5555'},
			percent: {text: 50, fontSize: 20, color: '#FF5555'}
		});
 * ===============================
 */
function progressRing(
	{
		el,                 	//绘制对象
		width = 150, 			//宽度
		height = 150, 			//高度
		lineWidth = 3, 			//线款
		lineCap = 'round',		//运动圆环两头圆角
		direction = false, 		//绘制圆环方向 true-逆时针 | false-顺时针
		forecolor, 				//前景色(运动圆环颜色)
		bgcolor, 				//背景色
		tip = {
			text: '',			//提示文字
			fontSize: 10,		//提示文字大小
			color: '#FF5555', 	//提示文字颜色
		},
		percent = {
			type: 'number',
			text: 0, 			//百分比, 范围[0, 100]
			fontSize: 20,		//百分比文字大小
			color: '#FF5555',	//百分比文字颜色
		}		
	}
) {
	el.innerHTML = '<canvas class="canvas" width="200" height="200"></canvas>';
	var context, center_x,center_y,rad = -Math.PI*2/100,speed=0;	
	var ringTimer = setTimeout(function(){
		clearTimeout(ringTimer);
		canvas = el.querySelector('.canvas');
		context = canvas.getContext("2d");
		center_x = canvas.width / 2;
		center_y = canvas.height / 2;	
		context.width = width;
		context.height = height;
		let dpr = window.devicePixelRatio; // 假设dpr为2	
		// 获取css的宽高
		let { width: cssWidth, height: cssHeight } = canvas.getBoundingClientRect();
		// 根据dpr,扩大canvas画布的像素,使1个canvas像素和1个物理像素相等
		canvas.style.width = width + 'px';
		canvas.style.height = height + 'px';
		canvas.width = dpr * cssWidth;
		canvas.height = dpr * cssHeight;
		// 由于画布扩大,canvas的坐标系也跟着扩大,如果按照原先的坐标系绘图内容会缩小
		// 所以需要将绘制比例放大
		context.scale(dpr, dpr);
		rad = -Math.PI*2/100; 
		speed = 0; 
		var ringRunTimer = setInterval(function(){
			context.clearRect(0, 0, canvas.width, canvas.height);
			backgroundCircle();
			_tip();
			if(percent.text > 0){
				foregroundCircle(speed);				
			}
			_percent(speed);
			if(speed >= percent.text) {
				clearInterval(ringRunTimer)
				return;
			};
			speed += 1;
		},1000/60);
		//执行动画
		/* (function drawFrame(){
			window.requestAnimationFrame(drawFrame);
			context.clearRect(0, 0, canvas.width, canvas.height);
			backgroundCircle();
			_tip();
			if(percent.text > 0){
				foregroundCircle(speed);				
			}
			_percent(speed);
			if(speed >= percent.text) return;
			speed += 1;
		}()); */
	},150)
	// 绘制背景圆圈
	function backgroundCircle(){
		context.save();
		context.beginPath();
		context.lineWidth = lineWidth; //设置线宽
		var radius = center_x - context.lineWidth;
		context.lineCap = lineCap;
		context.strokeStyle = bgcolor;
		context.arc(center_x, center_y, radius, 0, Math.PI*2, true);
		context.stroke();
		context.closePath();
		context.restore();
	} 
	//绘制运动圆环
	function foregroundCircle(n){
		context.save();
		if(typeof forecolor === 'string')
		{
			context.strokeStyle = forecolor;				
		}
		else
		{
			var g = context.createLinearGradient(center_x, 0,center_x, center_y); //创建渐变对象  渐变开始点和渐变结束点
			forecolor.map(function(item, index){	
				g.addColorStop(index / forecolor.length, item); //添加颜色点	
			});
			context.strokeStyle = g; //使用渐变对象作为圆环的颜色
		}
		context.lineWidth = lineWidth;
		context.lineCap = lineCap;
		var radius = center_x - context.lineWidth;
		context.beginPath();
		context.arc(center_x, center_y, radius , -Math.PI/2, -Math.PI/2 +n*rad, true); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
		context.stroke();
		context.closePath();
		context.restore();
	}
	function _tip(){
		context.save(); //save和restore可以保证样式属性只运用于该段canvas元素
		context.fillStyle = tip.color;
		context.font = tip.fontSize + "px Helvetica";
		var tip_width = context.measureText(tip.text).width;
		var tip_height = tip.text ? 20 : '';
		context.fillText(tip.text, center_x - tip_width/2, center_y + tip.fontSize/2 - tip_height);
		context.restore();
	}
	//绘制文字
	function _percent(n){
		context.save(); //save和restore可以保证样式属性只运用于该段canvas元素
		context.fillStyle = percent.color;		
		if(n==0 && percent.type != 'number'){
			var text = '暂未开启';
			context.font = percent.fontSize - 10 + "px Helvetica";				
		}else{
			var text = n.toFixed(0)+"%";
			context.font = percent.fontSize + "px Helvetica";
		}
		var percent_width = context.measureText(text).width;
		var tip_height = tip.text ? 20 : '';
		context.fillText(text, center_x - percent_width/2, center_y + percent.fontSize/2 + tip_height/2);
		context.restore();
	} 
	//执行动画
	/* (function drawFrame(){
		window.requestAnimationFrame(drawFrame);
		context.clearRect(0, 0, canvas.width, canvas.height);
		backgroundCircle();
		_tip();
		_percent(speed);
		foregroundCircle(speed);
		if(speed >= percent.text) return;
		speed += 1;
	}()); */
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风如白话

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值