You need to enable JavaScript to run this app. 如何使用Javascript+HTML5实现带鼠标交互的3D厚度ID卡片旋转效果
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 22:06:07