通过计算鼠标位置和旋转元素中心点的角度实现拖拽旋转的效果,遇到角度差的问题。应该怎么补这个差值?

659 阅读1分钟

可以将代码完整的复制到html文件中,用浏览器直接打开。

问题如下: 当N处于正上方的时候,在元素的任何位置拖拽旋转都正常。但是,如果先将N转出一个角度后,再次拖拽,N会先跳到正北的方向.

第39行代码的目的是,在鼠标按下后,记录鼠标初始位置与元素中心的夹角,我最初认为可能是这个初始夹角的差值导致的,所以在第53行鼠标移动过程中动态计算鼠标与元素的夹角中直接减去这个差值,但是发现并没有处理掉这个问题,后面我考虑可能在正负角度的不同,负角度应该加上这个差值,反之减去这个差值,多次尝试也没解决这个问题,我陷入了迷茫。求助各位。

<div class="aaa">
  <div id="transformEle" class="draggable">
    N
  </div>
</div>
<style>
/* .aaa{
  position: absolute;
  bottom: 30px;
  right: 30px;
  width: 84px;
  height: 84px;
} */
.draggable {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  cursor: grab;
  border: 1px solid red;
  width: 85px;
  height: 85px;
  border-radius: 50%;
  text-align: center;
  user-select: none;
}

.dragging {
  cursor: grabbing;
}
</style>

<script>
// 获取元素
const element = document.getElementById("transformEle");

// 鼠标按下事件
element.addEventListener("mousedown", function (downEvent) {
  const dowmAngleDegrees = calculateAngle(element, downEvent)
  // 添加 dragging 鼠标样式
  element.classList.add("dragging");

  // 鼠标移动事件
  document.addEventListener("mousemove", moveElement);

  // 鼠标释放事件
  document.addEventListener("mouseup", releaseElement);

  // 移动元素的函数
  function moveElement(moveEvent) {
    const rect = element.getBoundingClientRect();
    // 元素中心点坐标
    const angleInDegrees = calculateAngle(element, moveEvent) - (360 - dowmAngleDegrees * -1);
    // 设置元素的旋转角度
    element.style.transform = "translate(-50%, -50%) rotate(" + angleInDegrees + "deg)";
  }

  // 释放元素的函数
  function releaseElement() {
    // 移除 dragging 类
    element.classList.remove("dragging");

    // 移除事件监听器
    document.removeEventListener("mousemove", moveElement);
    document.removeEventListener("mouseup", releaseElement);
  }
});


function calculateAngle(transformEle, mouseEvent) {
  const rect = transformEle.getBoundingClientRect();
  // 元素中心点坐标
  const centerX = rect.left + rect.width / 2;
  const centerY = rect.top + rect.height / 2;
  const { clientX: mouseX, clientY: mouseY } = mouseEvent;
  // 计算鼠标相对于元素中心点的位置向量
  const vectorX = mouseX - centerX;
  const vectorY = mouseY - centerY;
  // 计算角度
  const angle = Math.atan2(vectorY, vectorX);
  return (angle) * (180 / Math.PI);
}

</script>