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>
工作原理
取中心点坐标
const cx = rect.left + rect.width/2; const cy = rect.top + rect.height/2;
求向量 (dx, dy)
const dx = evt.clientX - cx; const dy = evt.clientY - cy;
用 atan2 计算角度
Math.atan2(dy, dx)
→ 返回弧度,范围-π ~ π
,0° 在右侧,逆时针为正转换到度数并修正到「0° 在正上方,顺时针递增」:
let raw = Math.atan2(dy, dx) * 180 / Math.PI; let angle = (raw + 450) % 360;
实时显示角度,同时让蓝点跟随鼠标。