效果图(可拖动)
样式简易原因:更易于大家个性化修改
完整代码(兼容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>