CSS 3D Transform鼠标拖拽实现X/Y轴旋转及3D翻转显示问题求助
拖拽旋转逻辑优化
原拖拽逻辑存在3个核心问题:
- 位移计算逻辑错误,每次mousemove会覆盖位移基准值,导致旋转角度跳变、跟随不跟手
- 没有累计历史旋转角度,每次拖拽都会从0度开始计算,不会继承之前的旋转状态
- 事件绑定范围过小,鼠标拖出容器区域后会丢失mousemove、mouseup事件,出现拖拽粘滞
优化后的JS代码如下:
"use strict"; let elContainer = $('#container'); let elBox = $('#box'); // 新增变量:存储当前累计旋转角度、拖拽起始时的旋转角度、拖拽灵敏度 let currentRotateX = 0, currentRotateY = 0; let startRotateX = 0, startRotateY = 0; const rotateSensitivity = 0.5; // 可自行调整数值控制拖拽旋转速度 let dragging = false; let startMouse = {}; $(document).ready(function() { $('.slider-rotate').on('input', function() { sliderRotate(); // 滑块修改时同步更新累计旋转角度变量,保持状态一致 currentRotateX = parseInt($('[data-rotate-type="X"]').val()); currentRotateY = parseInt($('[data-rotate-type="Y"]').val()); }); elContainer.mousedown(function(e) { initDragRotate(e); }); // 事件绑定到document,避免拖出容器丢失事件 $(document).mousemove(function(e) { dragRotate(e); }); $(document).mouseup(function(e) { endDragRotate(); }); }); function initDragRotate(e) { dragging = true; // 记录拖拽起始时的鼠标坐标、当前已有的旋转角度 startMouse = { x: e.pageX, y: e.pageY, }; startRotateX = currentRotateX; startRotateY = currentRotateY; } function dragRotate(e) { if (!dragging) { return; } // 计算本次拖拽的鼠标位移,叠加起始角度得到最新角度 const deltaX = e.pageX - startMouse.x; const deltaY = e.pageY - startMouse.y; currentRotateY = startRotateY + deltaX * rotateSensitivity; currentRotateX = startRotateX + deltaY * rotateSensitivity; // 角度范围限制在0~360度,和滑块范围保持一致 currentRotateX = (currentRotateX + 360) % 360; currentRotateY = (currentRotateY + 360) % 360; // 同步更新滑块数值 $('[data-rotate-type="X"]').val(currentRotateX); $('[data-rotate-type="Y"]').val(currentRotateY); // 应用变换 const rotateParam = `rotateY(${currentRotateY}deg) rotateX(${currentRotateX}deg)`; elBox.css('transform', rotateParam); } function endDragRotate() { dragging = false; } function sliderRotate() { let rotateParam = ''; $('.slider-rotate').each(function() { rotateParam += ' ' + getRotateParamString($(this)); }); elBox.css('transform', rotateParam); } function getRotateParamString(elClass) { let val = elClass.val(); let rotateType = elClass.data('rotate-type'); let rotateParam = 'rotate' + rotateType + '(' + val + 'deg)'; return rotateParam; }
3D翻转显示背面颜色方案
原3D效果不生效存在3个问题:
- 父容器没有设置透视属性,无法呈现3D空间效果
- 两个子div都位于Z轴0平面,没有预先翻转背面元素
- 没有设置背面可见性属性,翻转后正面元素不会隐藏
修改后的CSS代码如下:
#container { background: #ccc; padding: 10vh; display: flex; align-items: center; justify-content: center; /* 新增:添加透视属性,开启3D空间 */ perspective: 1000px; } #box { width: 30vh; height: 30vh; border: 5px solid #000; position: relative; transform-style: preserve-3d; } #box>div { position: absolute; left: 0; right: 0; top: 0; bottom: 0; /* 新增:背面不可见 */ backface-visibility: hidden; } /* 新增:将第二个div预先沿Y轴翻转180度,作为背面元素 */ #box>div:nth-child(2) { transform: rotateY(180deg); }
修改后旋转到180度时就会显示绿色的背面,其余角度显示红色正面。
内容的提问来源于stack exchange,提问作者Nishu Ali
相关产品推荐
相关产品推荐

