一個非常漂亮的圓形滑塊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>

給個三連吧兄弟們!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章