可以将代码完整的复制到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>