一个非常漂亮的圆形滑块Round Slider,可修改成圆形进度条!

滑块效果图

改动百分比效果图

思路

首先绘制一个灰色边框的圆

        ctx.translate(150,150);//坐标定位至150,150处
		ctx.beginPath();
		ctx.lineWidth='20';
		ctx.strokeStyle='#EEEEEE';
		ctx.arc(0,0,radius,0,2*Math.PI);//绘制一个完整的圆
		ctx.stroke();

    再绘制一个半径一样、圆心一样蓝色的圆

        ctx.beginPath();
		ctx.rotate(-Math.PI);//逆时针选择一个π
		ctx.lineWidth='20';
		ctx.strokeStyle='#6699FF';
		ctx.arc(0,0,radius,0,move/180*Math.PI);//根据move的大小绘制圆弧
		ctx.stroke();

    在圆弧上绘制一个小圆作为指示器

        //绘制指针小圆
		ctx.save();
		ctx.rotate(move/180*Math.PI);//根据move的大小旋转
		ctx.beginPath();
		ctx.strokeStyle='gray';
		ctx.lineWidth='2';
		ctx.arc(radius,0,11,0,2*Math.PI);
		ctx.fillStyle='white';
		ctx.fill();
		ctx.stroke();
		ctx.restore();

  在圆心出放置一个DIV,可以做为百分比显示器

	<div id='percent'>
			<input type='text' value=50 oninput="doInput(this)" style="display:none;" >
			<p style="text-align: center;color:#66AFFF;">50</p>
		</div>

设置这个百分比的样式

#percent{
	width: 50px;
    height: 50px;
    position: absolute;
    left: 130px;
    top: 130px;
    font-size: 30px;
    cursor: pointer;
}
#percent input{
	width: 50px;
    height: 50px;
    border-radius: 10px;
    border: 1px solid #EEEEEE;
    text-align:center;
    font-size: 30px;
}

如何来做到点击

首先给canvas画布添加一个点击事件,当鼠标点击的时候,我们可以得到一个坐标X,Y,根据勾股定理可以算出这个点到圆心的距离,如果在一定的范围呢,则认为是点击到圆弧上,否则不触发。

		//根据勾股定理计算半径
		var conputedRadius = Math.sqrt((e.clientX-tranX)*(e.clientX-tranX)+(e.clientY-tranY)*(e.clientY-tranY));
		//处于90-110的被认为是有效点击
		if(conputedRadius>90 && conputedRadius<110){//点击的有效性
			//计算角度
	    	var jiaodu=Math.round(Math.asin((e.clientY-tranY)/conputedRadius)/Math.PI*180);//asin
			var jiaodu1=Math.round(Math.acos((e.clientX-tranX)/conputedRadius)/Math.PI*180);//acos
			var jiaodu2 = jiaodu>0?jiaodu1:(360-jiaodu1);	//最终角度
			
			//因为已经逆时针旋转了180度,所以还要处理
			jiaodu2 = jiaodu2<180?(jiaodu2+180):(jiaodu2-180);
		
			end=jiaodu2;//最终计算的鼠标点击位置的正真角度
			
			//显示指数
			percent.children[1].innerText=Math.round(end/360*100);
			percent.children[0].value=Math.round(end/360*100);
			//执行动画
			doAnimate();
		}else{
			return;
		}

完整代码

<!DOCTYPE html>
<html>
	<head lang="en">
		<meta charset="GBK">
		<title></title>
		<style>
*{
    margin: 0;
    padding: 0;
}
canvas{
	border:1px solid ;
}
#percent{
	width: 50px;
    height: 50px;
    position: absolute;
    left: 130px;
    top: 130px;
    font-size: 30px;
    cursor: pointer;
}
#percent input{
	width: 50px;
    height: 50px;
    border-radius: 10px;
    border: 1px solid #EEEEEE;
    text-align:center;
    font-size: 30px;
}
</style>
	</head>
	<body>
		<canvas id='canvas'></canvas>
		<div id='percent'>
			<input type='text' value=50 oninput="doInput(this)" style="display:none;" >
			<p style="text-align: center;color:#66AFFF;">50</p>
		</div>
	<script type="text/javascript">
	var percent = document.getElementById('percent');
	var canvas = document.getElementById('canvas');
	    canvas.width='600';
    	canvas.height='400';
	var ctx = canvas.getContext("2d");	

	var raf,
	timmer,//定时函数的计数器
	move=180,//移动的位置,开始默认180度
	end=360,//结束位置,最大360
	radius=100,//半径
	dis=10,//每次动画执行转动的角度
	dir=1, //方向,负1表示逆时针
	tranX=150,//圆心位置X
	tranY=150;//圆心位置Y
	
	draw();
	
	function draw(){
		ctx.clearRect(0,0,canvas.width,canvas.height);//清理画布
		
		ctx.save();
		ctx.translate(tranX,tranY);//坐标定位至150,150处
		ctx.beginPath();
		ctx.lineWidth='20';
		ctx.strokeStyle='#EEEEEE';
		ctx.arc(0,0,radius,0,2*Math.PI);//绘制一个完整的圆
		ctx.stroke();
		
		//绘制可以点击变化的圆
		ctx.beginPath();
		ctx.rotate(-Math.PI);//逆时针选择一个π
		ctx.lineWidth='20';
		ctx.strokeStyle='#6699FF';
		ctx.arc(0,0,radius,0,move/180*Math.PI);//根据move的大小绘制圆弧
		ctx.stroke();
		
		//绘制指针小圆
		ctx.save();
		ctx.rotate(move/180*Math.PI);//根据move的大小旋转
		ctx.beginPath();
		ctx.strokeStyle='gray';
		ctx.lineWidth='2';
		ctx.arc(radius,0,11,0,2*Math.PI);
		ctx.fillStyle='white';
		ctx.fill();
		ctx.stroke();
		ctx.restore();
		
		ctx.restore();
		
		raf = window.requestAnimationFrame(draw);
	}
	

	canvas.addEventListener('click',function(e){
		//根据勾股定理计算半径
		var conputedRadius = Math.sqrt((e.clientX-tranX)*(e.clientX-tranX)+(e.clientY-tranY)*(e.clientY-tranY));
		//处于90-110的被认为是有效点击
		if(conputedRadius>90 && conputedRadius<110){//点击的有效性
			//计算角度
	    	var jiaodu=Math.round(Math.asin((e.clientY-tranY)/conputedRadius)/Math.PI*180);//asin
			var jiaodu1=Math.round(Math.acos((e.clientX-tranX)/conputedRadius)/Math.PI*180);//acos
			var jiaodu2 = jiaodu>0?jiaodu1:(360-jiaodu1);	//最终角度
			
			//因为已经逆时针旋转了180度,所以还要处理
			jiaodu2 = jiaodu2<180?(jiaodu2+180):(jiaodu2-180);
		
			end=jiaodu2;//最终计算的鼠标点击位置的正真角度
			
			//显示指数
			percent.children[1].innerText=Math.round(end/360*100);
			percent.children[0].value=Math.round(end/360*100);
			//执行动画
			doAnimate();
		}else{
			return;
		}
		
	})
	
	var flag=false;//动画执行标示
	function doAnimate(){
		//判断动画方向
		dir=end>move?1:-1;
		//执行动画
		if(flag) return;//如果正在执行动画,不做处理
		flag=true;//设置为执行动画
		timmer=setInterval(function(){
			if(end==move){//当执行到预定位置,则清除定时器
				clearInterval(timmer);
				flag=false;//取消执行状态
				return;
			}
			if(Math.abs(end-move)<dis){//如果距离目标位置的角度不足一次递增了,就直接就move设置为最终位置
				move = end;
				return ;
			}
			move+=dir*dis;//每次定时任务的执行将增加一定的角度
		},10)
		
		raf = window.requestAnimationFrame(draw);
	}
	
	function doClick(e){
		var p=percent.children[1],input=percent.children[0];
		var e=e||window.event;
		var target=e.currentTarget;
			e.stopPropagation();//阻止冒泡
		if(target.tagName&&target.tagName.toUpperCase()==='DIV'){
			if(input.style.display==''){
				return;
			}
			//显示input
			input.style.display='';
			p.style.display='none';
			input.value=p.innerText;
			input.focus();
		}else{
			if(input.style.display==''){
				p.style.display='';
				//隐藏input
				input.style.display='none';
				p.innerText=input.value;
				 //处理百分比
				editPercent();
			}
		}
	}
	function editPercent(){
		var p=percent.children[1],input=percent.children[0];
		//设置动画的end
		end = p.innerText/100*360;
		//执行动画
		doAnimate();
	}
	//控制文本输入
	function doInput(obj){
		obj.value=obj.value.replace(/[^\d]/g,'');
		var value = parseInt(obj.value);
		if(value>100){
			obj.value=100;
		}else if(value<0){
			obj.value=0;
		}
	}
	
	percent.addEventListener('click',doClick);
	
	document.addEventListener('click',doClick);
</script>
	</body>
</html>

给个三连吧兄弟们!

猜你喜欢

转载自blog.csdn.net/dkm123456/article/details/112954313