3D圆柱edit icon

创建者:
曾有我的天气
Fork(复制)
下载
嵌入
BUG反馈
index.html
style.css
index.js
index.html
            
            <!DOCTYPE html>
<html>
<head>
  <style>
    body {
      margin: 0;
      padding: 50px;
      background: #f8f8f8;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      font-family: Arial, sans-serif;
    }

    /* 容器:透视空间 */
    .cylinder-container {
      width: 500px;
      height: 500px;
      perspective: 1800px;
    }

    /* 圆柱体主体:3D 容器(所有子元素的定位基准) */
    .cylinder {
      width: 100%;
      height: 100%;
      position: relative;
      transform-style: preserve-3d;
      transform: rotateX(30deg) rotateY(60deg);
      transition: transform 0.2s ease-out;
    }

    /* 1. 圆柱顶部(上表面):直径 300px,厚度方向顶端 */
    .cylinder-top {
      position: absolute;
      width: 300px;
      height: 300px;
      border-radius: 50%;
      top: 50%;
      left: 50%;
      /* 先居中,再沿 Z 轴上移(厚度的一半 = 15px),与侧面顶端对齐 */
      transform: translate(-50%, -50%) translateZ(10px) rotateX(90deg);
      background: #e0e0e0;
      box-shadow: inset 0 2px 10px rgba(0,0,0,0.08);
      z-index: 3;
    }

    /* 2. 圆柱底部(下表面):直径 300px,厚度方向底端 */
    .cylinder-bottom {
      position: absolute;
      width: 300px;
      height: 300px;
      border-radius: 50%;
      top: 50%;
      left: 50%;
      /* 先居中,再沿 Z 轴下移(厚度的一半 = 15px),与侧面底端对齐 */
      transform: translate(-50%, -50%) translateZ(-10px) translateY(-300px) rotateX(90deg);
      background: #d0d0d0;
      box-shadow: 0 10px 30px rgba(0,0,0,0.2);
      z-index: 1;
    }

    /* 3. 圆柱侧面容器:所有矩形单元的父容器,确保统一旋转中心 */
    .cylinder-side {
      position: absolute;
      width: 300px; /* 与上下表面直径一致 */
      height: 300px;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%); /* 先居中到圆柱体中心 */
      transform-style: preserve-3d;
    }

    /* 侧面矩形单元:核心修正!位置精准对齐 */
    .side-segment {
      position: absolute;
      width: 30px; /* 圆柱厚度(Z 轴方向长度) */
      height: 300px; /* 与上下表面直径一致,垂直覆盖整个高度 */
      left: 50%; /* X 轴居中(相对于侧面容器) */
      top: 0; /* Y 轴顶端对齐(配合 transform 居中) */
      /* 旋转中心:左侧边的中点(确保绕圆形轨迹旋转时不偏移) */
      transform-origin: left center;
      /* 渐变模拟曲面光影,左右暗中间亮更真实 */
      background: linear-gradient(90deg, #a6a6a6 0%, #b8b8b8 50%, #c9c9c9 100%);
      backface-visibility: hidden; /* 避免背面穿模 */
      box-shadow: inset 0 0 3px rgba(0,0,0,0.05);
    }

    /* 操作提示 */
    .info {
      position: fixed;
      bottom: 30px;
      left: 50%;
      transform: translateX(-50%);
      color: #555;
      font-size: 14px;
      padding: 8px 16px;
      background: rgba(255,255,255,0.9);
      border-radius: 20px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    }
  </style>
</head>
<body>
  <div class="cylinder-container">
    <div class="cylinder" id="cylinder">
      <div class="cylinder-top"></div>
      <div class="cylinder-bottom"></div>
      <div class="cylinder-side" id="cylinderSide"></div>
    </div>
  </div>

  <div class="info">提示:按住鼠标拖动旋转,侧面与上下表面精准对齐 📦</div>

  <script>
    const cylinderSide = document.getElementById('cylinderSide');
    const cylinder = document.getElementById('cylinder');
    const segmentCount = 180; // 侧面矩形数量(36 个=10°/个,平滑无缺口)
    const radius = 150; // 圆柱半径(= 上下表面直径的一半:300/2)
    const thickness = 30; // 圆柱厚度(与 .side-segment 的 width 一致)

    // 动态生成侧面矩形,精准排列
    for (let i = 0; i < segmentCount; i++) {
      const segment = document.createElement('div');
      segment.classList.add('side-segment');
      
      // 每个矩形的旋转角度:360° / 矩形数量(均匀分布)
      const rotateAngle = (i * 360) / segmentCount;
      
      // 核心修正:3D 变换顺序(先旋转,再平移,确保位置精准)
      segment.style.transform = `
        rotateY(${rotateAngle}deg) /* 1. 绕 Y 轴旋转到对应角度 */
        translateZ(${radius}px)    /* 2. 沿 Z 轴平移到圆柱侧面轨迹(距离=半径) */
        translateY(-50%)           /* 3. 垂直居中(配合 top:0 实现上下对齐) */
      `;
      
      cylinderSide.appendChild(segment);
    }

// 鼠标移动切换视角核心逻辑
    let currentRotateX = 30; // 初始X轴旋转角度(俯视)
    let currentRotateY = 60; // 初始Y轴旋转角度(左右)
    const sensitivity = 0.15; // 视角灵敏度(值越小越慢,越大越快)
    const centerX = window.innerWidth / 2; // 页面水平中心
    const centerY = window.innerHeight / 2; // 页面垂直中心

    // 鼠标移动事件:根据鼠标位置计算旋转角度
    document.addEventListener('mousemove', (e) => {
      // 计算鼠标相对于页面中心的偏移量(正负值对应不同方向)
      const offsetX = e.clientX - centerX;
      const offsetY = e.clientY - centerY;

      // 根据偏移量更新旋转角度:鼠标在中心时无旋转,偏离中心时逐步旋转
      currentRotateY = 60 + (offsetX * sensitivity); // X偏移控制Y轴旋转(左右视角)
      currentRotateX = 30 - (offsetY * sensitivity); // Y偏移控制X轴旋转(上下视角)

      // 限制X轴旋转范围(0°=正视,90°=完全俯视),避免过度翻转
      currentRotateX = Math.max(0, Math.min(90, currentRotateX));

      // 应用3D旋转
      cylinder.style.transform = `rotateX(${currentRotateX}deg) rotateY(${currentRotateY}deg)`;
    });


  </script>
</body>
</html>
        
编辑器加载中
预览
控制台