乐趣区

关于前端:几行CSS让你的页面立体起来

先来看一个咱们应用在产品中简略的例子:

这种相似翻扑克牌的动画齐全通过 CSS 实现,而真正外围的局部只波及到三个简略属性 perspective, transform, backface-visibility,在上面的文章局部,我会通过例子并逐渐解说分明。

1. 一般的旋转

大家都晓得,css3 的 transform 属性能够对元素进行视觉层面的形变操作,其中蕴含了旋转操作(Rotate):

@keyframes rotateX {0% { transform: rotateX(0) }
  100% {transform: rotateX(360deg) }
}
@keyframes rotateY {0% { transform: rotateY(0) }
  100% {transform: rotateY(360deg) }
}
@keyframes rotateZ {0% { transform: rotateZ(0) }
  100% {transform: rotateZ(360deg) }
}

.container {
  .z-rotateX {animation: rotateX 10s linear infinite;}
  .z-rotateY {animation: rotateY 10s linear infinite;}
  .z-rotateZ {animation: rotateZ 10s linear infinite;}
}

不掉帧的演示和源码能够看这里: https://codepen.io/mongooseso…

这里别离演示了 RotateX、RotateY、RotateZ 旋转 360° 的动画成果,然而成果只是立体的,可能不太容易了解。在上面咱们联合平面的动效来具体阐明。

2. 平面的旋转

只增加了一行 CSS 之 后的成果:

.container {
  perspective: 800px;
  // ......
}

不掉帧的演示和源码能够看这里: https://codepen.io/mongooseso…

其实,咱们只增加了 perspective:800px 这一行代码。

那么 perspective 是什么意思呢?

官网的解释是:perspective 指定了观察者与 z=0 立体的间隔,使具备三维地位变换的元素产生透视成果。
咱们能够非常简单的了解为,从屏幕的视角登程,与 3D 元素容器的间隔。perspective 设置的越小,你看屏幕里的 3D 感觉越近,设置的越大,离得越远。当这个属性存在时,意味着该元素下所有子元素是平面的了。

默认状况下,是以元素的核心作为落脚点,能够了解为你是站在正视着元素的核心看的,如果你须要扭转视角,能够应用 perspective-origin 这个属性。

3. 浏览器坐标系

有一个不得不提的问题的是,RotateX、Y、Z 到底是怎么旋转的?

浏览器的坐标系,程度向右是 X 轴正方向,竖直向下是 Y 轴正方向,垂直屏幕向外是 Z 轴正方向。

举个例子,transform: rotateX(45deg) 示意旋转核心为 X 轴,顺时针旋转 45 度。如果参数为正数,那就是逆时针旋转。
在辨认的时候,咱们能够应用左手规定,即左手大拇指指向对应轴的正方向,其余手指蜿蜒的方向就是顺时针方向。

为了便于了解,我找了两张图来阐明

咱们左手对着 X 轴正方向,手指蜿蜒的方向是朝向 Y 轴正方向,则能够揣测,旋转 45 度的成果为:

情谊提醒:不要对着你的共事没事比划左手规定,如果比划的话,千万不要用 Y 轴方向的。如果你真的用了,请通知我医院的 Wi-Fi 好不好。
所以下面动效应用的 RotateX,Y,Z 是不是都能了解了,同时 RotateZ 产生不了 3D 成果的起因也能够了解了吧。

4. 翻牌成果

像开篇提到的翻牌成果,又是如何实现的呢?

下面说到 perspective 是对子元素失效的,因而咱们须要一个额定的 cards 容器,两个 div 别离示意侧面和背面。

<div class="container">
  <div class="cards">
    <div class="card frontface" />
    <div class="card backface" />
  </div>
</div>
  • 卡片公共属性

不言而喻,卡片正反面都要指定 position: absolute,这样能力让卡片叠在一起。另外还须要指定,即本文的第二个重要属性 backface-visibility:hidden,这个属性十分好了解。

当一个元素指定 rotateY(180deg) 之后,依据左手规定,元素的侧面朝里,反面对向咱们,如果咱们指定了此属性,即背向咱们的元素咱们不再须要可见。

.card {  
  position: absolute;
  top: 0;
  backface-visibility: hidden;
}
  • 卡片侧面

卡片侧面不须要做任何非凡解决。

  • 卡片反面

指定 transform: rotateY(180deg) 即可。

.backface {transform: rotateY(180deg);
}
  • cards 块

显然,咱们须要给 cards 块增加 transition:transform 属性以减少动画成果,另外咱们还须要用上本文的第三个属性 transform-style: preserve-3d。

这个属性值示意,这个元素下的所有的子元素处于 3D 空间中,存在着平面的层级和笼罩关系,如果你的容器元素外部有多个元素波及到重叠的 3D 变换时,这个属性值是必须的。

.cards {
  transition: transform 1s;
  transform-style: preserve-3d;
}
  • container 块
    最初,作为最外围容器,只须要设置 perspective 让子元素变为平面旋转,另外还须要设置 position: relative 让外部的 absolute 元素产生参照定位。

    .container {
    perspective: 800px;
    position: relative;
    } 

一个简略的示例

具体的源码和 Demo 在这里: https://codepen.io/mongooseso…

5. 三维魔方

你可能发现过,webpack 官网的 logo 其实就是用 CSS 手写的,所以咱们最初聊一下,怎么联合已有的属性,实现一个立方体的旋转。

先上残缺代码和 Demo: https://codepen.io/mongooseso…

  • HTML 格局
    同卡片成果相似,咱们的 HTML 模式大抵如下

    <div class="container">
    <div class="cubes">
      <div class="cube front" />
      <div class="cube back" />
      <div class="cube top" />
      <div class="cube bottom" />
      <div class="cube left" />
      <div class="cube right" />
    </div> 
    </div>
  • 父组件款式
    和卡片一样,咱们须要为外层的 cubes 容器和最外层的 container 容器设置 3D 视角属性

    .cubes {
    transform-style: preserve-3d;
    transition: transform 1s;
    width: 100%;
    height: 100%;
    }
    .container {
    position: relative;
    perspective: 400px;
    width: 200px;
    height: 200px;
    }

    这里咱们设置了正方体的边长为 200px,以 400px 的视距来察看

  • 绘制六个面

如果玩过魔方的同学可能晓得,为了便于记录魔方的旋转,咱们通常会给正方体六个面别离命名为前、后、左、右、上、下:

除了向前的那一面毋庸批改以外,其余面都能够认为是向前的一面做了各种旋转得出的后果

后:沿着 Y 轴顺时针旋转 180deg

.back {transform: rotateY(180deg)
}

左:沿着 Y 轴逆时针旋转 90deg(能够好好思考下为什么是逆时针)

.left {transform: rotateY(-90deg)
}

右:沿着 Y 轴顺时针旋转 90deg

.right {transform: rotateY(90deg)
}

上:沿着 X 轴顺时针旋转 90deg

.top {transform: rotateX(90deg)
}

下:沿着 X 轴逆时针旋转 90deg

.bottom {transform: rotateX(-90deg)
}

咱们能够给不同的面标上背景色和花纹用来辨别,此时这六个面还是相互穿插在一起的,咱们还须要进行“地位”的调整

  • 组合六个面

在 Demo 中,咱们设置正方体的边长为 200px,而这六个面穿插重叠的核心还是位于正方体的核心,因而咱们须要通过给每个面设置 translateZ(100px) 即可让正方体地位调整正确,例如反面加上当前成为这样的款式

.back {transform: rotateY(180deg) translateZ(100px);
}
  • 绘制动效

接下来就简略了,咱们能够给正方体绘制任何动效,感兴趣的甚至能够进一步绘制出如魔方的打乱和还原过程。

6. 实用场景

应用 CSS 来实现 3D 成果早就不是浏览器的新技术了,然而在理论产品中的利用依然寥寥可数,适当的动效能够晋升产品体验,相同简单的动效会带来审美疲劳和开发累赘。
WebGL 和 D3.js 等等的确是个好货色,然而他们的学习老本和开发成本都很高,须要付出不少的精力能力看到理论的回报,并且利用场景较少。
所以如果你想解脱 2B 场景下干燥的增删改查,2C 场景下 H5 的干燥交互,无妨大胆的应用下应用老本极低的 CSS 3D

The End

如果你感觉这篇文章对你有帮忙,有启发,我想请你帮我 2 个小忙:
1、点个「」,让更多的人也能看到这篇文章内容;
2、关注公众号「 豆皮范儿 」,公众号后盾回复「 加群」退出咱们一起学习;

关注公众号的福利继续更新,公众号后盾送学习材料:
1、公众号后盾回复「vis」,还能够获取更多可视化收费学习材料。
2、公众号后盾回复「webgl」,还能够获取 webgl 收费学习材料。
3、公众号后盾回复「算法」,还能够获取算法的学习材料。

退出移动版