JavaScript实现前端旋转魔方相册:3D变换与事件处理详解
本文详细讲解如何使用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魔方相册内容,请查阅本站历史文章或继续浏览下方相关文章。感谢大家的支持!
vtk.js 渲染窗口黑屏或无内容显示的常见原因及排查
2026-11-05 17:30:30
js-cookie 安装与基础用法:set、get、remove 详解
2026-11-05 16:35:06
适合JavaScript初学者的实战项目:制作简易待办事项列表
2026-11-05 16:17:07
JS打开新标签页时怎么通过URL传递参数
2026-11-05 12:21:08
sigma.js 自定义节点样式:设置颜色、大小及标签显示的技巧
2026-11-05 09:55:00
