JS实现圆形进度条拖拽滑动

效果图(可拖动)

样式简易原因:更易于大家个性化修改
在这里插入图片描述

完整代码(兼容PC端、移动端)

实现原理:创建n个li元素(点)根据鼠标(手指触摸)位置判断出最近的点并进行展示,其余点隐藏。所有的点围绕基点进行排列,设置基点通过transform-origin。每个点的倾斜度及横向的位置,在创建时通过left和transform: rotate() 实现

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#wrap{
				height:200px;
				width: 400px;
				border: 1px solid;
				border-bottom: none;
				border-radius: 200px 200px 0 0;/*圆角半径为高度的值*/
				position: relative;
			}
			ul{
				list-style:none;
				margin: 0;
				padding: 0;
				height: 200px;
			}
			#wrap ul li{
				width: 3px ;
				height: 6px;
				border-radius: 10px;
				background-color:#666 ;
				position: absolute;
				left: 199px;
				top: 0;
				visibility: hidden;
				/*设置刻度以表盘的中心为基点进行旋转*/
				-webkit-transform-origin:center 200px;
			}
		</style>
	</head>
	<body>
		<div id="wrap">
			<!-- ul中存储js生成的li -->
			<ul></ul>
		</div>
	</body>

	<script type="text/javascript">
			// 判断哪一端
			var browserRedirect = function () {
				var sUserAgent = navigator.userAgent.toLowerCase();
				return /ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(sUserAgent)   
			}
	        // 找出鼠标最近距离的刻度的下标
			var findNearestNumber = function(arr,target){
				let mid;
				let l = 0;
				let r = arr.length - 1;
				// 保证指针最终停留在相邻的两个数,所以这里是判断是否大于1
				while (r - l > 1) {
					mid = Math.floor((l + r) / 2);
					// 如果目标数比中间小,所以范围在左边
					if (target < arr[mid]) {
						r = mid;
					} else {
						l = mid;
					};
				};
				// 最后比较这两个数字的绝对差大小即可。
				return Math.abs(target - arr[l]) <= Math.abs(target - arr[r]) ? l: r;
			}
			// duan
			var duan = browserRedirect()
			// 获取ul元素
			var oUl =  document.getElementsByTagName('ul')[0];
			// 获取style元素
			var oStyle = document.getElementsByTagName('style')[0];
			// 定义一个变量保存循环生成的li
			var strLi = '';
			// 定义一个变量保存li的样式
			var strCss = '';
			// 循环生成li并添加rotate样式
			for(var i=0;i<28;i++){
				strLi +='<li></li>';
				strCss +="#wrap ul li:nth-of-type("+(i+1)+"){-webkit-transform: rotate("+(i*6-81)+"deg);}";
			}
			// 将生成的元素及样式添加至对应标签中
			oUl.innerHTML = strLi;
			oStyle.innerHTML += strCss;
			// 将所有刻度在页面中的X坐标存入数组中
			let leftArr = []
			for(var i=0;i<28;i++){
				leftArr.push(document.getElementsByTagName('li')[i].getBoundingClientRect().left.toFixed(2))
			}
			document.getElementsByTagName('li')[0].style.visibility = 'visible'
			// 监听鼠标移动,对刻度进行显示及隐藏控制
			document.addEventListener(`${duan?'touchmove':'mousemove'}`, (e)=> {
					//获取鼠标最新的坐标
					let pageX = duan? e.touches[0].pageX : e.pageX
					console.log('移动位置:',pageX,'最接近的:',this.findNearestNumber(leftArr,pageX))
					let index = this.findNearestNumber(leftArr,pageX)
					// 距离鼠标最近的刻度显示
					document.getElementsByTagName('li')[index].style.visibility = 'visible'
					// 其余显示隐藏
					for(var i=0;i<28;i++){
						if(i !== index){
							document.getElementsByTagName('li')[i].style.visibility = 'hidden'
						}
					}
				})
	</script>
</html>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DefuseAll

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

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

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

打赏作者

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

抵扣说明:

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

余额充值