如何使用Javascript+HTML5实现带鼠标交互的3D厚度ID卡片旋转效果
3D旋转ID卡片实现方案
这个需求用原生HTML5+CSS3+JavaScript就能实现,不需要引入重型3D引擎,整体逻辑轻量易维护,以下是可直接运行的完整实现:
核心实现思路
- 利用CSS3的
transform-style: preserve-3d属性构建立体空间,用6个DOM元素模拟带厚度的扁平立方体(正面放前景图、背面放背景图、四个侧边用纯色模拟厚度) - 用CSS
@keyframes实现默认状态的自动缓慢旋转 - 通过JavaScript监听鼠标拖拽事件,实时计算偏移量控制卡片旋转角度,拖拽时暂停自动旋转
完整代码实现
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>3D旋转ID卡片</title> <style> /* 外层容器设置透视视角 */ .card-container { perspective: 1000px; width: 300px; height: 400px; margin: 100px auto; } /* 卡片主体,开启3D空间 */ .id-card { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; /* 默认自动旋转动画 */ animation: autoRotate 10s infinite linear; cursor: grab; } /* 鼠标悬停/拖拽时暂停自动旋转 */ .id-card:hover, .id-card.dragging { animation-play-state: paused; cursor: grabbing; } /* 所有面的公共样式 */ .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; overflow: hidden; border-radius: 12px; box-shadow: 0 0 20px rgba(0,0,0,0.2); } /* 正面(前景图) */ .card-face.front { transform: translateZ(10px); /* 数值为卡片厚度的一半 */ background: url('替换为你的前景图本地路径') center/cover no-repeat; } /* 背面(背景图) */ .card-face.back { transform: rotateY(180deg) translateZ(10px); background: url('替换为你的背景图本地路径') center/cover no-repeat; } /* 侧边样式,模拟厚度 */ .card-face.side { width: 20px; /* 卡片总厚度值 */ background: #2c3e50; left: 50%; margin-left: -10px; } .card-face.side-left { transform: rotateY(-90deg) translateZ(150px); } .card-face.side-right { transform: rotateY(90deg) translateZ(150px); } .card-face.side-top { height: 20px; width: 100%; top: 50%; margin-top: -10px; left: 0; transform: rotateX(90deg) translateZ(200px); } .card-face.side-bottom { height: 20px; width: 100%; top: 50%; margin-top: -10px; left: 0; transform: rotateX(-90deg) translateZ(200px); } /* 自动旋转动画 */ @keyframes autoRotate { from { transform: rotateY(0deg) rotateX(5deg); } to { transform: rotateY(360deg) rotateX(5deg); } } </style> </head> <body> <div class="card-container"> <div class="id-card"> <div class="card-face front"></div> <div class="card-face back"></div> <div class="card-face side side-left"></div> <div class="card-face side side-right"></div> <div class="card-face side side-top"></div> <div class="card-face side side-bottom"></div> </div> </div> <script> const card = document.querySelector('.id-card'); let isDragging = false; let startX, startY; let currentRotateY = 0; let currentRotateX = 5; // 默认X轴倾斜角度 // 鼠标按下开始拖拽 card.addEventListener('mousedown', (e) => { isDragging = true; card.classList.add('dragging'); startX = e.clientX; startY = e.clientY; }); // 鼠标移动控制旋转 document.addEventListener('mousemove', (e) => { if (!isDragging) return; const deltaX = e.clientX - startX; const deltaY = e.clientY - startY; // 调整灵敏度 currentRotateY += deltaX * 0.5; currentRotateX -= deltaY * 0.5; // 限制X轴旋转角度避免翻转过度 currentRotateX = Math.max(-45, Math.min(45, currentRotateX)); card.style.transform = `rotateY(${currentRotateY}deg) rotateX(${currentRotateX}deg)`; startX = e.clientX; startY = e.clientY; }); // 鼠标抬起结束拖拽 document.addEventListener('mouseup', () => { isDragging = false; card.classList.remove('dragging'); }); // 鼠标移出窗口结束拖拽 document.addEventListener('mouseleave', () => { isDragging = false; card.classList.remove('dragging'); }); </script> </body> </html>
参数调整说明
- 调整卡片尺寸:修改
.card-container的width和height即可 - 调整卡片厚度:修改
.card-face.side的width,以及正反两面translateZ的数值(为厚度的一半) - 调整自动旋转速度:修改
autoRotate动画的时长,数值越小旋转越快 - 调整拖拽灵敏度:修改
mousemove事件中deltaX和deltaY的系数即可 - 替换前后背景图:修改
.front和.back的background属性中的图片地址即可
如果需要更复杂的3D交互效果,也可以引入Three.js引擎实现,支持更多材质、光照等定制化效果。
内容的提问来源于stack exchange,提问作者seppzzz
相关产品推荐
相关产品推荐

