html+js+css实现一个圆形滑块

9 篇文章 0 订阅
6 篇文章 0 订阅

html+js+css实现一个圆形滑块,可以拖动,可以点击,先看效果再讲原理,最后附上源码:
在这里插入图片描述
产品经理设计了这样一个需求,通过拖动圆形滑块实现时间的设置功能,虽然看着有点复杂,但是确实有点复杂。

实现思路

需求分析:

  • 一个圆盘,一个滑块;

  • 以圆盘为圆心,点击圆盘任意位置或者拖动滑块,滑块会移动到指定位置;

  • 同步保存滑块的值

实现逻辑:
获取鼠标点击或者移动的位置到圆盘圆心水平x和垂直y的距离;

然后使用Math.atan2函数根据x和y计算出这个点到圆心这条线和x轴的角度angle,angle的范围为 -π 到 π;

当点击的位置位于x轴上方时,angle小于零,位于x轴下方时,angle大于零
在这里插入图片描述
最后根据这个angle,就可以获取一个相对于这个圆形360°的百分比,配合设置的最大值和最小值计算出当前滑块的值。

代码实现

这里就不说太多废话了,直接把完整代码放下面,注释很清楚😉

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <style>
    #container{
      width: 200px;
      height: 200px;
      border-radius: 100px;
      background: aqua;
      margin: 50px;
    }
    #bar{
      width: 20px;
      height: 20px;
      background: red;
      border-radius: 10px;
      pointer-events: none;
      text-align: center;
      font-size: 12px;
      line-height: 20px;
      color: white;
    }
  </style>
</head>
<body>
<div id="container">
  <!--    <div class="track"></div>-->
  <div id="bar"></div>
</div>

<script>
  // 滑块容器
  const slider = document.getElementById('container')
  // 滑块
  const bar = document.getElementById('bar')
  // 滑动轨道半径
  const radius = 100

  // 滑块的值,以及最小和最大
  let value = 50, min = 0, max = 100
  // 当前是否正在拖动
  let isDragging = false
  // 鼠标按下事件
  slider.addEventListener('mousedown', (event) => {
    event.preventDefault();
    // 开始拖动
    isDragging = true;
    // 监听鼠标移动事件
    slider.addEventListener('mousemove', handleMouseMove);
    // 鼠标松开事件
    slider.addEventListener('mouseup', endDrag);
    // 鼠标移出区域
    slider.addEventListener('mouseleave', endDrag);
  })

  // 处理鼠标移动事件
  const handleMouseMove = (event) => {

    if (isDragging) {
      updateValue(event)
    }
  }

  // 更新滑块数值
  const updateValue = event => {
    // 获取容器中心点
    const centerX = slider.offsetWidth / 2;
    const centerY = slider.offsetHeight / 2;
    // 鼠标位置到中心x和y方向的距离
    const deltaX = event.offsetX - centerX
    const deltaY = event.offsetY - centerY
    // 根据距离计算鼠标到中心点的角度,Math.atan2返回值为 -π 到 π ,导致滑动的位置时从圆形的最右端开始滑动的,所以用 + Math.PI/2处理一些初始位置
    let angle = Math.atan2(deltaY, deltaX) + Math.PI/2
    // 转换为角度 0-360
    let newValue = ((angle * 180) / Math.PI + 360) % 360;
    // 将360分段
    newValue = Math.round(newValue/3.6)*3.6
    // 根据百分比计算滑块的值
    newValue = (newValue / 360) * (max - min) + min;
    if (newValue <= min) {
      newValue = max;
    } else if (newValue > max) {
      newValue = max;
    }

    value = newValue.toFixed(0)
    bar.innerText = value
    // 更新滑块位置
    updatePosition()
  }

  // 鼠标点击时也更新滑块的值
  slider.addEventListener('click', updateValue);
  // 更新滑块位置
  const updatePosition = () => {
    // 根据值计算角度,然后计算出滑块的位置
    let angle = ((value - min) / (max - min)) * 360 - 90;
    const x = Math.cos((angle * Math.PI) / 180) * radius + 90;
    const y = Math.sin((angle * Math.PI) / 180) * radius + 90;

    bar.style.transform = `translate(${x}px, ${y}px)`
  }
  // 根据默认值更新滑块位置
  bar.innerText = value
  updatePosition()
  // 结束拖动
  const endDrag = () => {
    isDragging = false;
    // 移除相关监听事件
    slider.removeEventListener('mousemove', handleMouseMove);
    slider.removeEventListener('mouseup', endDrag);
    slider.removeEventListener('mouseleave', endDrag);
  }


</script>
</body>
</html>

大家有任何问题都可以在评论区留言交流,相互学习!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bdawn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值