教程: 在网页中利用原生CSS实现3D旋转动画

今天讲解下如何实现3D旋转卡片效果。将知识店面,没什么比直接从源码中去了解更好的了,所以我直接提供一个HTML文件供大家去学习,代码附有详细注释解释每个实现步骤

完整的HTML代码

您可以将以下代码保存为3d-rotating-cards.html文件,然后直接在浏览器中打开查看效果:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D旋转卡片效果教程</title>
    <style>
        /* 全局样式重置 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Arial', sans-serif;
            height: 100vh;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            overflow: hidden;
        }

        h1 {
            color: white;
            margin-bottom: 50px;
            font-size: 2.5rem;
            text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
        }

        /* 控制面板样式 */
        .controls {
            position: absolute;
            bottom: 30px;
            display: flex;
            gap: 20px;
            z-index: 100;
        }

        .controls button {
            padding: 12px 24px;
            border: none;
            border-radius: 25px;
            background: rgba(255, 255, 255, 0.2);
            color: white;
            font-size: 16px;
            cursor: pointer;
            backdrop-filter: blur(10px);
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
        }

        .controls button:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: translateY(-3px);
        }

        /* 第一步:创建3D场景环境 */
        .scene {
            width: 100%;
            height: 400px;
            perspective: 1000px; /* 关键:定义3D空间的透视效果 */
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* 第二步:创建旋转轨道 */
        .orbit {
            width: 200px;
            height: 200px;
            position: relative;
            transform-style: preserve-3d; /* 关键:保持子元素的3D变换效果 */
            animation: rotate 20s infinite linear; /* 应用自动旋转动画 */
        }

        /* 第三步:定义旋转动画 */
        @keyframes rotate {
            from {
                transform: rotateY(0deg);
            }
            to {
                transform: rotateY(360deg);
            }
        }

        /* 第四步:设置卡片基础样式 */
        .card {
            width: 175px;
            height: 120px;
            position: absolute; /* 绝对定位,使卡片能够环绕中心点排列 */
            top: 50%;
            left: 50%;
            margin: -60px 0 0 -87.5px; /* 居中定位 */
            transform-style: preserve-3d; /* 关键:保持3D变换效果 */
            transition: transform 0.6s ease; /* 添加过渡动画使翻转更平滑 */
            cursor: pointer;
            border-radius: 10px;
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
        }

        /* 第五步:设置卡片正反面样式 */
        .card-face {
            position: absolute; /* 绝对定位,使正反面重合 */
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border-radius: 10px;
            backface-visibility: hidden; /* 关键:隐藏背面,使翻转时不会看到背面 */
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 20px;
            font-weight: bold;
            color: white;
            transition: all 0.3s ease;
        }

        /* 第六步:设置卡片正面样式 */
        .card-front {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
        }

        /* 第七步:设置卡片背面样式并预先翻转180度 */
        .card-back {
            background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
            transform: rotateY(180deg); /* 关键:背面预先翻转180度 */
        }

        /* 第八步:实现鼠标悬停效果 */
        .card:hover {
            transform: translateZ(220px) rotateY(180deg); /* 增加Z轴距离并翻转卡片 */
            z-index: 10; /* 确保悬停的卡片显示在最上层 */
        }

        /* 第九步:鼠标悬停在轨道上时暂停旋转 */
        .orbit:hover {
            animation-play-state: paused;
        }

        /* 教程步骤说明样式 */
        .tutorial {
            position: absolute;
            left: 30px;
            top: 30px;
            width: 300px;
            background: rgba(255, 255, 255, 0.1);
            padding: 20px;
            border-radius: 10px;
            color: white;
            backdrop-filter: blur(10px);
            max-height: 80vh;
            overflow-y: auto;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
        }

        .tutorial h2 {
            margin-bottom: 15px;
            font-size: 1.5rem;
        }

        .tutorial p {
            margin-bottom: 10px;
            line-height: 1.6;
        }
    </style>
</head>
<body>
    <h1>3D旋转卡片效果</h1>

    <!-- 教程步骤说明 -->
    <div class="tutorial">
        <h2>实现步骤:</h2>
        <p>1. 创建3D场景环境 (perspective 属性)</p>
        <p>2. 创建旋转轨道并设置动画</p>
        <p>3. 设置卡片基础样式和3D变换</p>
        <p>4. 为卡片创建正反面并设置样式</p>
        <p>5. 实现鼠标悬停翻转效果</p>
        <p>6. 添加交互控制功能</p>
    </div>

    <!-- 3D场景容器 -->
    <div class="scene">
        <!-- 旋转轨道容器 -->
        <div id="orbit" class="orbit">
            <!-- 卡片1:通过rotateY和translateZ实现环形排列 -->
            <div class="card" style="transform: rotateY(0deg) translateZ(200px)">
                <div class="card-face card-front">卡片 1</div>
                <div class="card-face card-back">背面 1</div>
            </div>

            <!-- 卡片2:角度间隔72度(360/5) -->
            <div class="card" style="transform: rotateY(72deg) translateZ(200px)">
                <div class="card-face card-front">卡片 2</div>
                <div class="card-face card-back">背面 2</div>
            </div>

            <!-- 卡片3 -->
            <div class="card" style="transform: rotateY(144deg) translateZ(200px)">
                <div class="card-face card-front">卡片 3</div>
                <div class="card-face card-back">背面 3</div>
            </div>

            <!-- 卡片4 -->
            <div class="card" style="transform: rotateY(216deg) translateZ(200px)">
                <div class="card-face card-front">卡片 4</div>
                <div class="card-face card-back">背面 4</div>
            </div>

            <!-- 卡片5 -->
            <div class="card" style="transform: rotateY(288deg) translateZ(200px)">
                <div class="card-face card-front">卡片 5</div>
                <div class="card-face card-back">背面 5</div>
            </div>
        </div>
    </div>

    <!-- 控制面板 -->
    <div class="controls">
        <button id="toggleRotation">暂停/继续</button>
        <button id="speedUp">加速</button>
        <button id="slowDown">减速</button>
    </div>

    <script>
        // 获取DOM元素
        const orbit = document.getElementById('orbit');
        const toggleButton = document.getElementById('toggleRotation');
        const speedUpButton = document.getElementById('speedUp');
        const slowDownButton = document.getElementById('slowDown');
        
        // 控制变量
        let isRotating = true;
        let rotationSpeed = 20; // 初始旋转速度(秒)
        
        // 暂停/继续旋转功能
        toggleButton.addEventListener('click', function() {
            isRotating = !isRotating;
            
            if (isRotating) {
                // 继续旋转
                orbit.style.animationPlayState = 'running';
                toggleButton.textContent = '暂停';
            } else {
                // 暂停旋转
                orbit.style.animationPlayState = 'paused';
                toggleButton.textContent = '继续';
            }
        });
        
        // 加速旋转功能
        speedUpButton.addEventListener('click', function() {
            if (rotationSpeed > 5) { // 最小速度限制
                rotationSpeed -= 2;
                updateRotationSpeed();
            }
        });
        
        // 减速旋转功能
        slowDownButton.addEventListener('click', function() {
            if (rotationSpeed < 40) { // 最大速度限制
                rotationSpeed += 2;
                updateRotationSpeed();
            }
        });
        
        // 更新旋转速度
        function updateRotationSpeed() {
            // 移除现有的动画
            orbit.style.animation = 'none';
            
            // 强制重绘
            void orbit.offsetWidth;
            
            // 应用新的动画速度
            orbit.style.animation = `rotate ${rotationSpeed}s infinite linear`;
            
            // 保持当前的播放状态
            orbit.style.animationPlayState = isRotating ? 'running' : 'paused';
        }
    </script>
</body>
</html>

实现原理详解

这个3D旋转卡片效果主要基于CSS 3D变换和动画实现,以下是核心技术点的详细解释:

1. 3D空间的创建

css 复制代码
.scene {
    perspective: 1000px; /* 定义3D空间的透视效果 */
    transform-style: preserve-3d; /* 保持子元素的3D变换效果 */
}
  • perspective属性定义了3D空间的透视效果,值越小,透视感越强
  • transform-style: preserve-3d确保子元素能够保持其3D变换效果

2. 环形排列的实现

卡片的环形排列通过rotateYtranslateZ变换实现:

html 复制代码
<div class="card" style="transform: rotateY(0deg) translateZ(200px)">...</div>
<div class="card" style="transform: rotateY(72deg) translateZ(200px)">...</div>
<div class="card" style="transform: rotateY(144deg) translateZ(200px)">...</div>
  • 对于5个卡片,每个卡片的角度间隔为72度(360°/5)
  • translateZ(200px)将卡片沿着Z轴向外推移,形成圆环

3. 卡片正反面效果

css 复制代码
.card-face {
    backface-visibility: hidden; /* 隐藏背面 */
}

.card-back {
    transform: rotateY(180deg); /* 预先翻转背面 */
}
  • backface-visibility: hidden确保当元素旋转时,背面不可见
  • .card-back类预先将背面翻转180度,为后续的翻转效果做准备

4. 交互功能的实现

JavaScript部分实现了对3D动画的交互控制:

  • 暂停/继续 :通过改变animationPlayState属性控制动画播放状态
  • 速度调节 :通过动态修改animation属性的值来调整旋转速度
  • 悬停效果:当鼠标悬停在卡片上时,卡片会向前移动并翻转显示背面

使用方法

  1. 将上述代码保存为3d-rotating-cards.html文件
  2. 双击文件在浏览器中打开即可查看效果
  3. 您可以通过底部的按钮控制旋转状态和速度
  4. 将鼠标悬停在单个卡片上可以查看翻转效果

定制建议

  • 您可以调整perspective的值来改变3D透视效果
  • 修改translateZ的值可以调整圆环的大小
  • 调整@keyframes rotate中的animation-duration可以改变默认旋转速度
  • 替换卡片中的内容和样式可以自定义卡片的外观
  • 增加或减少卡片数量时,需要相应调整每个卡片的rotateY角度

这个HTML文件是一个完整的、自包含的教程示例,您可以直接运行它并查看效果,也可以根据自己的需求进行修改和扩展。


以上就是本期的全部内容,有问题欢迎评论区讨论~

相关推荐
struggle20259 小时前
AxonHub 开源程序是一个现代 AI 网关系统,提供统一的 OpenAI、Anthropic 和 AI SDK 兼容 API
css·人工智能·typescript·go·shell·powershell
朝阳3912 小时前
CSS【实战】可编辑元素实现 placeholder -- contenteditable=“true“
css
Ares-Wang13 小时前
CSS3》》 transform、transition、translate、animation 区别
前端·css·css3
fox_16 小时前
CSS3:水平垂直居中的 N 种实现方法
css
超能996要躺平16 小时前
用三行 CSS 实现任意多列等分布局:深入掌握 Grid 的 repeat() 与 gap
前端·css
寒月霜华18 小时前
JavaWeb-html、css-网页正文制作
前端·css·html
*濒危物种*18 小时前
HTML标签语法,基本框架
前端·css·html
软件技术NINI18 小时前
html css js网页制作成品——HTML+CSS+js早餐铺网页设计(4页)附源码
javascript·css·html
WebDesign_Mu1 天前
为了庆祝2025英雄联盟全球总决赛开启,我用HTML+CSS+JS制作了LOL官方网站
javascript·css·html