JavaScript实现前端旋转魔方相册:3D变换与事件处理详解

作者:像素猫时间:2026-10-26 02:23:44浏览:196

本文详细讲解如何使用HTML、CSS3和JavaScript构建一个交互式3D旋转魔方相册。通过设置transform-style、rotate和translateZ实现立方体结构,利用CSS transition添加旋转抖动特效,并结合JS事件监听实现点击图片切换视角的功能,提供完整代码示例。

效果展示

效果展示

功能目标:

点击底部缩略图可切换至对应视角的图片

开发逻辑:

  • 搭建HTML结构,完成基础代码编写
  • 配置CSS样式,运用transform3D构建立方体结构
  • 编写JavaScript交互逻辑

1. HTML结构构建

魔方内部使用<li>标签包裹图片,并嵌套于<ul>容器中,随后为ul启用3D渲染模式以实现翻折效果

此部分较为简单,此处省略详细讲解,参考代码如下:

效果展示

2. CSS样式设计

2.1 全局基础重置

清除浏览器默认边距,直接参考代码:

效果展示

2.2 立方体外观样式

核心在于为父容器设置transform-style: preserver-3d;,并对所有li子元素应用3D变换,便于后续通过transform进行折叠操作。此处采用子绝父相的定位策略,确保ul下的所有li均位于父元素ul边界内

即为每个li元素添加定位属性——top: 0 ; 和 left: 0;

若图片原始尺寸不一致,需强制指定img的宽高属性,迫使图片调整自身尺寸以适配容器

transition过渡属性配置:

  • 首个参数指定作用对象类型,all代表作用于所有子元素
  • 第二个参数定义动画持续时间
  • 第三个参数指定速度变化曲线,此处采用贝塞尔曲线,具体数值无需深究,可直接复用。值得注意的是,第四个参数控制最终距离,此处设为1.275意味着魔方旋转至目标位置后继续多转0.275,再回弹至目标点,此即实现旋转抖动效果的原理

具体代码实现如下:

效果展示

2.3 图片折叠布局

  • 前文已做铺垫,接下来只需设定每张图片在XY轴的翻转角度及Z轴位移,即可组合成立方体
  • 若对此存疑,可复习transform中的rotate属性。简要说明rotateX表示以X轴为对称轴进行翻转,朝上为正方向,朝下为负方向,Y轴同理
  • 此处设置translateZ,通俗理解是将页面文档流视为地面,设定图片高度。统一设为100px旨在使所有图片处于同一高度平面,从而构成封闭的立方体

代码实现如下:

效果展示

2.4 底部导航按钮样式

即实现下述视觉效果

效果展示

该部分逻辑简单,不再赘述。重点介绍前文提及的知识点——background-size: contain; 此属性保持图像纵横比,并将图像缩放至适合背景定位区域的最大尺寸。

效果展示

2.5 配合JS的翻转样式配置

此处需结合后续JS代码理解,建议同步阅读

具体逻辑解析:

  • 当触发底部图片点击事件时,JS动态为魔方ul添加对应类名。因类名已预设transform样式,故点击即可触发相应立方体旋转
  • 下方代码原理与上一节相同,但需注意:本节旋转主体为整个立方体,而上一节仅针对单张图片进行旋转

效果展示

3. JavaScript交互实现

核心逻辑部分

  • 首先明确,该JS代码服务于事件处理,遵循三步流程:获取变量、绑定事件、定义回调函数
  • 变量定义较为直观,根据事件需求获取页面相应DOM对象即可
  • 接下来需实现点击底部图片时的识别逻辑。观察HTML部分可知,底部图片的类名与2.5节预设类名一一对应
  • 因此直接创建onclick事件,在回调函数中将点击图片的类名赋值给立方体ul容器。点击哪张图片,即执行对应的旋转逻辑
  • 小练习: 创建事件时是否感到代码冗余?实际上可将回调函数封装,通过传入序号调用即可实现。感兴趣者可尝试封装,如需相关代码可在评论区留言,后续将更新此部分

效果展示

4. 完整源码展示

4.1 HTML文件内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>旋转魔方相册</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        body{
            background-color: rgba(0, 0, 0, 0.8);
        }
        /* 魔方样式设置部分 */
        .square{
            width: 200px;
            height: 200px;
            margin: 200px auto;
            margin-bottom: 100px;
        }
        ul{
            position: relative;
            transform-style: preserve-3d;
            transition: all .7s cubic-bezier(0.175, 0.885, 0.32, 1.275);
            width: 100%;
            height: 100%;
        }
        li{
            /* display: inline-block; */
            position: absolute;
            top: 0;
            left: 0;
            list-style: none;
            width: 100%;
            height: 100%;
            border: 1px solid pink;
        }
        img{
            width: 200px;
            height: 200px;
        }
        /* 初始位置 */
        /* ul{
            transform: translateZ(-100px) rotateX(-15deg) rotateY(15deg);
        } */
        /* 折叠图片,构成魔方 */
        ul li:nth-child(1) {
            transform: translateZ(100px);
        }
        ul li:nth-child(2) {
            transform: rotateY(180deg)  translateZ(100px);
        }
        ul li:nth-child(3) {
            transform: rotateY(90deg) translateZ(100px);
        }
        ul li:nth-child(4) {
            transform: rotateY(-90deg) translateZ(100px);
        }
        ul li:nth-child(5) {
            transform: rotateX(90deg) translateZ(100px);
        }
        ul li:nth-child(6) {
            transform: rotateX(-90deg) translateZ(100px);
        }
        
        /* 下方是点击目录 */
        .img_1{
            background-image: url(2.jpeg);
        }
        .img_2{
            background-image: url(1.jpeg);
        }
        .img_3{
            background-image: url(3.jpeg);
        }
        .img_4{
            background-image: url(4.jpeg);
        }
        .img_5{
            background-image: url(5.jpeg);
        }
        .img_6{
            background-image: url(6.jpeg);
        }
        span{
            display: inline-block;
            width: 50px;
            height: 25px;
            background-size: contain;
            border: 1px solid white;
        }
        .toc{
            width: 350px;
            margin: 0 auto;
        }
        /* 辅助JS块样式设置 */
        .square .img_1 {
            transform: translateZ(-100px);
        }
        .square .img_2 {
            transform: translateZ(-100px) rotateX(-180deg) ;
        }
        .square .img_3 {
            transform: translateZ(-100px) rotateY(-90deg) ;
        }
        .square .img_4 {
            transform: translateZ(-100px) rotateY(90deg) ;
        }
        .square .img_5 {
            transform: translateZ(-100px) rotateX(-90deg) ;
        }
        .square .img_6 {
            transform: translateZ(-100px) rotateX(90deg) ;
        }
    </style>
</head>
<body>
    <!-- 魔方 -->
    <div class="square">
        <ul class="s-img">
            <li><img src="2.jpeg"></li>
            <li><img src="1.jpeg"></li>
            <li><img src="3.jpeg"></li>
            <li><img src="4.jpeg"></li>
            <li><img src="5.jpeg"></li>
            <li><img src="6.jpeg"></li>
        </ul>
    </div>
    <!-- 手动点击旋转 -->
    <div class="toc">
        <span class="img_1"></span>
        <span class="img_2"></span>
        <span class="img_3"></span>
        <span class="img_4"></span>
        <span class="img_5"></span>
        <span class="img_6"></span>
    </div>
    <!-- JS -->
    <script src="cube.js">
    </script>
</body>
</html>

4.2 JavaScript文件内容

window.onload = function(){
    //toc目录设置
    var toc_img = document.querySelector('.toc');
    var square = document.querySelector('ul');
    var p_img = square.classList;
    var img_button = toc_img.querySelectorAll('span');
    var flage = '';
    img_button[0].onclick = function(e) {
        flage = img_button[0].className;
        square.setAttribute('class', flage);
    }
    img_button[1].onclick = function(e) {
        flage = img_button[1].className;
        square.setAttribute('class', flage);
    }
    img_button[2].onclick = function(e) {
        flage = img_button[2].className;
        square.setAttribute('class', flage);
    }
    img_button[3].onclick = function(e) {
        flage = img_button[3].className;
        square.setAttribute('class', flage);
    }
    img_button[4].onclick = function(e) {
        flage = img_button[4].className;
        square.setAttribute('class', flage);
    }
    img_button[5].onclick = function(e) {
        flage = img_button[5].className;
        square.setAttribute('class',flage);
    }
}

至此,关于JavaScript实现前端旋转魔方相册的教程结束。更多相关JavaScript魔方相册内容,请查阅本站历史文章或继续浏览下方相关文章。感谢大家的支持!

作者最新文章