突发奇想用css写一个魔方

3,300 阅读6分钟

魔方

魔方(1).gif

其实这个就是运用3d空间转换来实现, 大概的原理就是上下左右前后六个面分别通过旋转移动到达对应的位置

大概需要的知识

在这里先复习一下xyz轴的正方向

x轴往右为正方向 y轴往上为正方向 z轴往屏幕外为正方向

旋转,顺时针为正值,逆时针为负值 左手法则:左手大拇指指向xyz轴正向,四指的弯曲方向就是旋转正向方向

transform-style: preserve-3d是开启3D空间,父元素加这个属性,子元素进入3D

html简单搭建结构

先搭建结构,先把大盒子构建出来,上面的数字可以后面再加

<div class="box">
  <div class="front">
  </div>
  <div class="last">
  </div>
  <div class="left">
  </div>
  <div class="right">
  </div>
  <div class="up">
  </div>
  <div class="down">
  </div>
</div>

魔方每个面是一个盒子

CSS style

接下来就开始装饰我们的盒子啦~~~

(可以先把每个面做好然后开启3d,当然也可以先做好3d效果再整理各个盒子,我比较喜欢先做好每个面,这样进入3d时效果更明显)

基础样式

给每个盒子规定大小,再加上不同的背景色就很好看啦~

*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
//清除默认内外边距,设置盒子内减

.box div {
      width: 200px;
      height: 200px;
    }

    .front {
      background-color: rgb(224, 188, 119);
     }


    .last {
      background-color: rgb(203, 209, 119);
    }


    .left {
      background-color: rgb(202, 126, 126);
    }

    .right {
      background-color: rgb(162, 235, 162);
    }

    .up {
      background-color: rgb(137, 207, 207);
    }

    .down {
      background-color: rgb(206, 148, 211);
    }

image.png

image.png 因为我个人比较喜欢浅色系的颜色,所以选择的都是这个色区的颜色,莫兰迪色系?我乱猜的

目前就是这样的效果,每个盒子独占一行

然后把盒子全都叠在一起,开启3d空间 就是子绝父相,把盒子都堆在一起,

//把父盒子居中,会稍微好看一点
  .box {
      position: relative;
      width: 200px;
      height: 200px;
      margin: 100px auto;
    }

    .box div {
      position: absolute;
      top: 0;
      left: 0;
      width: 200px;
      height: 200px;
    }

image.png

盒子在页面水平居中,只能看到最后一个盒子

开启3D

接下来给父盒子加transform-style: preserve-3d,让子盒子开启3d空间,这样看上去盒子和之前没有什么区别,但是他们在立体空间里边

接下来就是各个盒子回到自己的位置了

image.png

前后

六个盒子全部在中心原点的位置,盒子的大小是200*200,那前面的盒子往前移动100px,后面的盒子往后移动100px

因为后面我们会在盒子上加数字,所以我们需要让后面的盒子后面也是正向的,所以让后面的盒子向后转,再前进100px,(可以理解成军训的时候,大家都是面朝前面站,然后让第一排的同学向前一步走,第二排的同学向后转然后向前一步走,这样教官站在后面是也可以看到后面同学的正脸)

 .front {
      background-color: rgb(224, 188, 119);
      transform: translateZ(100px);
    }


    .last {
      background-color: rgb(203, 209, 119);
      transform: rotateY(180deg) translateZ(100px);
    }
    //后面的盒子沿y轴旋转180

image.png

我稍微旋转了一下,可以看得清楚一点,中间还没有移动的盒子就是刚开始在原点的盒子,前面的向前一步走,后面的向后转再向前一步走

可能有一个疑问是:往后走明明是沿着Z轴向负方向移动,为什么写的是translateZ(100px),当盒子向后转之后,z轴方向也会随之改变,,z轴正方向是盒子前方的方向,就像在军训中向前一步走,永远是向着自己的z轴正方向前进一步

左右

接下来就是左右的盒子,在图中紫色的那里,还是联想军训,左右两边的同学向左向右转向前一步走,根据左手法则,左边的盒子向左转,就是沿着Y轴旋转-90度,然后向前移动100px(z轴正向100px),右边的盒子右转,就是沿着Y轴旋转90度,同样也是向前移动100px(z轴正向100px)

image.png

 .left {
      transform: rotateY(-90deg) translateZ(100px);
    }

    .right {
      transform: rotateY(90deg) translateZ(100px);
    }

image.png

上下

现在就只剩上下两面了,就是图中紫色的部分,其实和前面一样,都是旋转到对应的方向,然后z轴移动100px

image.png

这次就是沿着x轴旋转了,上的方向为正方向,下的方向为反方向,,(如果不是很好理解,可以想象一下,站在右边,看前这个面,翻上去就是顺时针转,翻下去就是逆时针转)转好了再移动

    .up {
      transform: rotateX(90deg) translateZ(100px);
    }

    .down {
      transform: rotateX(-90deg) translateZ(100px);
    }

初步效果图

这样效果图就出来了

image.png

image.png

完善

这样看着只是简单的一个盒子,接下来我们就在里边加上数字,当然也可以放自己喜欢的图片

每一个面就是一个盒子,我们在里边加上数字的盒子就可以,我用的是p标签包含数字,就是像这样:

 <div class="box">
    <div class="front">
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p>6</p>
      <p>7</p>
      <p>8</p>
      <p>9</p>
    </div>
    <div class="last">
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p>6</p>
      <p>7</p>
      <p>8</p>
      <p>9</p>
    </div>
    <div class="left">
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p>6</p>
      <p>7</p>
      <p>8</p>
      <p>9</p>
    </div>
    <div class="right">
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p>6</p>
      <p>7</p>
      <p>8</p>
      <p>9</p>
    </div>
    <div class="up">
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p>6</p>
      <p>7</p>
      <p>8</p>
      <p>9</p>
    </div>
    <div class="down">
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p>6</p>
      <p>7</p>
      <p>8</p>
      <p>9</p>
    </div>
  </div>

这个时候我们会发现盒子乱了,乱的有点神奇,因为p是块元素,独占一行

image.png

这个时候我们可以使用浮动布局,比较简单一点,宽高分别是父元素的33.33%,刚好撑满父元素,加边框看着更像魔方,每个小块之间有间隔,然后给文字水平垂直居中,改个颜色

P {
      float: left;
      border: 1px solid #fff;
      width: 33.33%;
      height: 33.33%;
      color: #fff;
      text-align: center;
      line-height: 66px;
    }

image.png

这样就完成了 可以给大的box盒子加一个旋转和过渡,这样就可以看到自己漂亮的魔方啦~~~

  .box {
      transition: all 600s linear;//盒子在60s内匀速转动(旋转150圈)
    }

    .box:hover {
      transform: rotate3D(1, 1, 1, 150turn);//鼠标经过的时候盒子转150圈
    }

下次有空的时候可以试着把里边换成自己喜欢的照片哈哈哈哈!!!!