js实现按住旋转
实现按住旋转的 JavaScript 方法
监听鼠标事件
通过 mousedown、mousemove 和 mouseup 事件实现按住旋转的逻辑。在 mousedown 时记录初始角度和鼠标位置,mousemove 时计算旋转角度,mouseup 时移除事件监听。
let isDragging = false;
let startAngle = 0;
let startX, startY;
element.addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.clientX;
startY = e.clientY;
startAngle = getCurrentRotation(element);
document.addEventListener('mousemove', rotate);
document.addEventListener('mouseup', stopRotate);
});
function rotate(e) {
if (!isDragging) return;
const centerX = element.offsetLeft + element.offsetWidth / 2;
const centerY = element.offsetTop + element.offsetHeight / 2;
const angle = Math.atan2(e.clientY - centerY, e.clientX - centerX) * 180 / Math.PI;
element.style.transform = `rotate(${angle}deg)`;
}
function stopRotate() {
isDragging = false;
document.removeEventListener('mousemove', rotate);
document.removeEventListener('mouseup', stopRotate);
}
function getCurrentRotation(el) {
const transform = window.getComputedStyle(el).getPropertyValue('transform');
if (transform === 'none') return 0;
const values = transform.split('(')[1].split(')')[0].split(',');
const a = values[0];
const b = values[1];
return Math.round(Math.atan2(b, a) * (180 / Math.PI));
}
使用 CSS 变换
通过 transform: rotate() 实现旋转效果。计算鼠标移动的角度差,动态更新旋转角度。
element.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const rect = element.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const angle = Math.atan2(e.clientY - centerY, e.clientX - centerX) * 180 / Math.PI;
element.style.transform = `rotate(${angle - startAngle}deg)`;
});
支持触摸事件
为移动端设备添加触摸事件支持,逻辑与鼠标事件类似。
element.addEventListener('touchstart', (e) => {
isDragging = true;
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
startAngle = getCurrentRotation(element);
document.addEventListener('touchmove', rotateTouch);
document.addEventListener('touchend', stopRotateTouch);
});
function rotateTouch(e) {
if (!isDragging) return;
const centerX = element.offsetLeft + element.offsetWidth / 2;
const centerY = element.offsetTop + element.offsetHeight / 2;
const angle = Math.atan2(e.touches[0].clientY - centerY, e.touches[0].clientX - centerX) * 180 / Math.PI;
element.style.transform = `rotate(${angle}deg)`;
}
function stopRotateTouch() {
isDragging = false;
document.removeEventListener('touchmove', rotateTouch);
document.removeEventListener('touchend', stopRotateTouch);
}
优化性能
使用 requestAnimationFrame 优化旋转动画的流畅度,避免频繁重绘导致的性能问题。

function rotateOptimized(e) {
if (!isDragging) return;
requestAnimationFrame(() => {
const centerX = element.offsetLeft + element.offsetWidth / 2;
const centerY = element.offsetTop + element.offsetHeight / 2;
const angle = Math.atan2(e.clientY - centerY, e.clientX - centerX) * 180 / Math.PI;
element.style.transform = `rotate(${angle}deg)`;
});
}






