前言
MOOC课程的实践项目,做一个魔方~
效果长这样~魔方在自主转动,且每个面的小方块可以飞走飞回。
代码放在:https://github.com/titibabybaby/FED/tree/main/rubik’s%20Cube
一、HTML
魔方是一个正方体,所以我们首先构造一个正方体。
html体现整个结构,都是div标签来表现的,整个container下有个box,box下有六个div,表示魔方的六个面。
<div class="container">
<div class="box">
<div class="box-page top"></div>
<div class="box-page bottom"></div>
<div class="box-page left"></div>
<div class="box-page right"></div>
<div class="box-page before"></div>
<div class="box-page after"></div>
</div>
</div>
二、CSS
.container
规定整体样式,设置长,宽,margin,这里注意将margin设置为:??px,auto;表示居中。
还有一个很重要的就是设置perspective,可以设为2000px,这表示我们离这个魔方远一点,这样才能看出来效果。
.container{
width: 300px;
height: 300px;
/*border: 1px solid black;*/
margin: 150px auto; /*左右设置为auto居中*/
perspective: 2000000000px;/*视距,隔得远一点看立方体会好一点*/
}
@keyframes ro {
0%{
transform:rotateX(0deg) rotateY(0deg);
}
100%{
transform:rotateX(360deg) rotateY(360deg);
}
}
*.box
.box{
width: 300px;
height: 300px;
/*控制子元素保持3D转换*/
transform-style: preserve-3d;
/*测试代码,让整个盒旋转一下,方便观察 ,不然就只是俯视角度,只能看到一个面*/
/*transform:rotateY(-45deg) rotateX(-45deg);*/
animation: ro 4s linear infinite; /*自动旋转动画*/
}
. box-page
魔方的每个面都有.box-page属性,设置位置初始化。六个面都是以这个初始位置为基准生成的,因为我们是利用了x,y,z三个维度,所以这里设置 transform-style: preserve-3d~
.box-page{
width: 300px;
height: 300px;
/*位置初始化,让他们都叠在一起*/
position: absolute; /*相对于static以外的第一个父元素进行定位,即container。他的定位不会受到其他父元素的影响*/
transform-style: preserve-3d;
}
(1).top
正方体的每个面长宽都是300px,我们将初始位置box-page放在正方体的中心,那么top这个面就应该位于初始位置的z方向往正方向走150px距离。
.top{
/*background-color: coral;*/
transform: translateZ(150px);
}
(2).bottom
与top类似,bottom这个面是初始位置往z的负方向走150px。
.bottom{
/*background-color: cornflowerblue;*/
transform:translateZ(-150px);
}
(3).left
对于左边这个面,我们首先从初始位置向x轴负方向走150px,再要把这个面立起来,沿y轴负方向转90度。
.left{
/*background-color: darkseagreen;*/
transform:translateX(-150px) rotateY(-90deg);
}
(4).right
右边也是类似的。
.right{
/*background-color: goldenrod;*/
transform:translateX(150px) rotateY(90deg);
}
(5).before
.before{
/*background-color: mediumpurple;*/
transform:translateY(150px) rotateX(90deg);
}
(6).after
.after{
/*background-color: darkgrey;*/
transform:translateY(-150px) rotateX(-90deg);
}
三、JavaScript
通过html,css,我们就已经完成了正方体的构建,JS部分是为了完成魔方中的小块儿,也就是每个面被切割成9个小块儿。
(1)定义元素arr(从.page-box获得,arr表示每个面儿)
(2)用两个for循环在每个面儿画9个小方块(3行3列),创建元素 var divs表示小方块。
(3)divs.style.cssText设置divs元素样式属性(可以给魔方的背景设置成自己喜欢的图片),向arr添加这个子节点
(4)平铺小方块
(5)背景图像定位
var arr=document.querySelectorAll(".box-page");
//遍历每个元素
for(var n=0;n<arr.length;n++){
for(var r=0;r<3;r++){
for(var c=0;c<3;c++){
//创建元素
var divs=document.createElement("div");
divs.style.cssText="width:100px;height:100px;border:2px solid white;border-sizing:border-box;background-image:url(../image/a"+n+".jpg);background-size:300px 300px;position:absolute";
arr[n].appendChild(divs);//.appendChild()方法可向节点的子节点列表的末尾添加新的子节点
//平铺小方块
divs.style.left=c*100+"px";
divs.style.top=r*100+"px";
//背景图像定位,如果要显示背景图像上小方块,值是负的
divs.style.backgroundPositionX=-c*100+"px";
divs.style.backgroundPositionY=-r*100+"px";
}
}
}
这样一来魔方就做好啦!
如果想加魔方小块飞出飞入的动画,在css加上:
.box-page div:nth-child(1){
animation: a1 4s ease-in;
}
.box-page div:nth-child(2){
animation: a1 4s ease-in 0.5s;
}
.box-page div:nth-child(3){
animation: a1 4s ease-in 1s;
}
.box-page div:nth-child(4){
animation: a1 4s ease-in 1.5s;
}
.box-page div:nth-child(5){
animation: a1 4s ease-in 2s;
}
.box-page div:nth-child(6){
animation: a1 4s ease-in 2.5s;
}
.box-page div:nth-child(7){
animation: a1 4s ease-in 3s;
}
.box-page div:nth-child(8){
animation: a1 4s ease-in 3.5s;
}
.box-page div:nth-child(9){
animation: a1 4s ease-in 4s;
}
@keyframes a1 {
0%{
transform:translateZ(0) scale(1) rotateZ(0) ;
}
20%{
transform:translateZ(300px) scale(0) rotateZ(220deg);
}
80%{
transform:translateZ(300px) scale(0) rotateZ(220deg);
}
100%{
transform:translateZ(0) scale(2) rotateZ(0) ;
}
}