360° 拖动旋转的角度计算原理

发布于:2025-09-06 ⋅ 阅读:(18) ⋅ 点赞:(0)

360° 拖动旋转的角度计算原理

简化的 正方形 div demo
专注讲清楚「点击 / 拖动如何计算角度」这个原理,没有精美 UI哦

  • 中间标注中心点
  • 鼠标点击或拖动时,计算当前位置相对于中心的角度
  • 在页面上实时显示角度

代码示例(原生 HTML + JS)

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>角度计算原理 Demo</title>
<style>
  body { display:flex;align-items:center;justify-content:center;height:100vh;margin:0;font-family:sans-serif; }
  .box {
    width:300px; height:300px;
    border:2px dashed #888;
    position:relative;
    background:#f9f9f9;
  }
  .center {
    position:absolute;
    left:50%; top:50%;
    transform:translate(-50%,-50%);
    width:8px; height:8px;
    background:red; border-radius:50%;
  }
  .dot {
    position:absolute;
    width:10px; height:10px;
    background:blue; border-radius:50%;
    transform:translate(-50%,-50%);
    pointer-events:none;
  }
  .info {
    margin-top:20px; font-size:16px; text-align:center;
  }
</style>
</head>
<body>
  <div class="wrap">
    <div class="box" id="box">
      <div class="center"></div>
      <div class="dot" id="dot"></div>
    </div>
    <div class="info" id="info">点击或拖动蓝点,显示角度</div>
  </div>

<script>
(function(){
  const box = document.getElementById('box');
  const dot = document.getElementById('dot');
  const info = document.getElementById('info');
  let dragging = false;

  function computeAngle(evt){
    const rect = box.getBoundingClientRect();
    const cx = rect.left + rect.width/2;
    const cy = rect.top + rect.height/2;

    const dx = evt.clientX - cx;
    const dy = evt.clientY - cy;

    // atan2: 右方为0°,逆时针为正。我们希望0°在正上方,顺时针为正。
    let raw = Math.atan2(dy, dx) * 180 / Math.PI;
    let angle = (raw + 450) % 360; 
    return {angle, x:evt.clientX, y:evt.clientY};
  }

  box.addEventListener('mousedown', e=>{
    dragging = true;
    update(e);
  });
  window.addEventListener('mousemove', e=>{
    if(dragging) update(e);
  });
  window.addEventListener('mouseup', ()=> dragging=false);

  box.addEventListener('click', e=>{
    update(e);
  });

  function update(e){
    const {angle, x, y} = computeAngle(e);
    dot.style.left = (x - box.getBoundingClientRect().left) + 'px';
    dot.style.top = (y - box.getBoundingClientRect().top) + 'px';
    info.textContent = "角度: " + angle.toFixed(1) + "°";
  }
})();
</script>
</body>
</html>

工作原理

  1. 取中心点坐标

    const cx = rect.left + rect.width/2;
    const cy = rect.top + rect.height/2;
    
  2. 求向量 (dx, dy)

    const dx = evt.clientX - cx;
    const dy = evt.clientY - cy;
    
  3. 用 atan2 计算角度

    • Math.atan2(dy, dx) → 返回弧度,范围 -π ~ π,0° 在右侧,逆时针为正

    • 转换到度数并修正到「0° 在正上方,顺时针递增」:

      let raw = Math.atan2(dy, dx) * 180 / Math.PI;
      let angle = (raw + 450) % 360;
      
  4. 实时显示角度,同时让蓝点跟随鼠标。


网站公告

今日签到

点亮在社区的每一天
去签到