You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 07:15:07