<!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>
index.html
style.css
index.js
index.html