如何使用jQuery实现图片旋转时避免鼠标移入导致的跳变问题
问题原因
- 你当前的实现直接使用鼠标绝对坐标
pageX/pageY作为旋转角度值,没有计算鼠标按下位置的相对偏移量 - 没有存储上一次拖动结束后的累计旋转角度,每次鼠标重新进入区域按下时,坐标突变会直接导致角度跳变
修复方案
修改逻辑为基于鼠标拖动的相对偏移量累计计算旋转角度,同时在鼠标抬起/离开区域时保存当前的旋转状态,修改后的完整代码如下:
补充基础CSS样式(原代码缺失交互区域的基础样式):
.espaceRotation { position: relative; width: 400px; height: 400px; } .elemEspace { position: absolute; width: 100%; height: 100%; } .zoneImage { display: flex; align-items: center; justify-content: center; } .zoneImage img { width: 200px; } .zoneSouris { background: #eee; cursor: grab; display: flex; align-items: center; justify-content: center; z-index: 10; } .zoneSouris:active { cursor: grabbing; }
修改后的JS代码:
function init($) { // 存储鼠标按下时的初始坐标 let startX = 0; let startY = 0; // 存储上一次拖动结束后的累计旋转角度 let lastRotateY = 0; let lastRotateX = 0; // 标记是否正在拖动 let isDragging = false; $(".zoneSouris") .mousedown(function(event) { if (event.buttons === 1) { isDragging = true; // 记录按下时的鼠标坐标 startX = event.pageX; startY = event.pageY; } else if (event.buttons === 2) { // 右键重置旋转角度 lastRotateX = 0; lastRotateY = 0; $(".zoneImage").css({ '-webkit-transform': 'rotateX(0deg) rotateY(0deg)', '-moz-transform': 'rotateX(0deg) rotateY(0deg)', }); } }) .mousemove(function(event) { if (!isDragging || event.buttons !== 1) return; // 计算当前鼠标和按下位置的偏移量 const offsetX = event.pageX - startX; const offsetY = event.pageY - startY; // 偏移量叠加到之前的旋转角度上,系数0.5控制旋转灵敏度,可自行调整 const currentRotateY = lastRotateY + offsetX * 0.5; const currentRotateX = lastRotateX + offsetY * 0.5; $(".zoneImage").css({ '-webkit-transform': `rotateX(${currentRotateX}deg) rotateY(${currentRotateY}deg)`, '-moz-transform': `rotateX(${currentRotateX}deg) rotateY(${currentRotateY}deg)`, }); }) .on('mouseup mouseleave', function() { if (!isDragging) return; isDragging = false; // 拖动结束保存当前旋转角度,作为下次拖动的初始值 lastRotateX += (event.pageY - startY) * 0.5; lastRotateY += (event.pageX - startX) * 0.5; }) .bind("contextmenu", function(e) { return false; }); } init($);
HTML部分可保持原有逻辑不变:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <main> <div class="espaceRotation"> <div class="elemEspace zoneImage"> <img src="https://i.imgur.com/eNqPru1.png" /> </div> <div class="elemEspace zoneSouris"> <span>Manipulez avec la souris !</span> </div> </div> </main>
修复点说明
- 新增
isDragging状态标记,只有在区域内按下鼠标后才会触发旋转计算 - 旋转角度基于拖动的相对偏移量计算,和鼠标的绝对位置无关,移出再移回不会出现跳变
- 拖动结束后自动保存当前旋转状态,下次拖动可以无缝衔接上次的旋转角度
- 新增灵敏度控制系数,可以根据需要调整0.5的数值来改变旋转的快慢
内容的提问来源于stack exchange,提问作者Victor Colin
相关产品推荐
相关产品推荐

