写在前面:最近写了个3d轮播效果图,在此将思路和过程中遇到的问题都记录下来。
首先,我们下来了解一下perspective和transform都是做什么的。
transform -- css3属性,可以对元素进行变换(2d/3d),包括平移translate,旋转rotate,缩放scale,等等(完整取值参考 W3C)。
perspective -- css3属性,当元素涉及3d变换时,perspective可以定义我们眼睛看到的3d立体效果,即空间感。通俗地解释就比如你去电影院看电影,你距离大荧幕的距离就相当于perspective的值啦,离得越远则perspective值越大,看到空间效果也就会不一样!
接下来,我们就进入正题了。
先上3d轮播图效果图:
图一
图二
图三
***图一为前一张轮播图,图二是轮播图前后切换时的3d效果图,图三为后一张轮播图***
实现上面的效果,需要三层页面结构:
1. 最外面的容器.swiper-wrapper,即图中天蓝色边框这个部分。为这部分设置关键css如下:
transform-style: preserve-3d; //3d旋转效果
perspective: 1000px; //3d立体空间感
perspective-origin: 50% 50%; //观察视角, 50% 50%代表从中间观察
2. 用ul包裹的li多边体。参考图二可知,我们的每张图片实际上是由n个片段拼接而成,这是怎么实现的呢?很简单,多个li + background-position定位轻松实现啦;
3. li里的div数组,数组的长度等于轮播图的总张数。这个div数组将所有的图片围绕x轴形成了一个多边体。完整多边体效果如图四:
图四
那么怎么实现这个多边体呢?这就要用到今天的transform属性了。假设一个多边体有m条边,每个div平面代表一条边(即每张图片的1/n),我们先将每个div平面绝对定位到li的左上角(left:0;top:0;),此时的每个div平面都在x轴与y轴形成的平面上,也就是电脑屏幕平面上。接下来我们将每个div平面依次进行变换transform: rotateX((360/m)*i deg) translateZ(z轴位移量),先围绕x轴依次旋转(默认旋转点是平面中心,可以通过transform-origin设置,我们就是用默认值)(360/m)*0、 (360/m)*1 、(360/m)*2 、... 、直到(360/m)*(m-1),这样形成的下面的效果,图五:
图五
咦?不是多边体么?别急,接下里translateZ(z轴位移量)登场了,这个值是多少自己拿小本本算去... 反正是每个边到中心点的垂直距离... ok, 看一下每个边平移后的效果吧,图六:
图六
怎么超前的几个面变这么大了?都超出粉色的框框了... 没错,这就是平移translateZ产生的效果,立体地看,就是前面的几个面都跑到电脑屏幕外面了,后面的几个面跑到电脑屏幕后面了。还不明白?就是说电脑屏幕沿着这个多边形的中点,并且从多边形的垂直方向穿透过去了。还不明白的话我也没辙了...闭眼想像去吧...
(tips: 以面对电脑屏幕的视角看,假设一个平面在屏幕上,则向右为其x轴正向,向下为其y轴正向,向屏幕外为其z轴正向。且当这个平面旋转时,他的3个轴也跟着旋转。)
那怎么让最外面的图片放到电脑屏幕的平面上呢?聪明的人都知道了,把li代表的多边形整体translateZ(z轴位移量)不就行啦!来看下效果图,往上看,再往上看,再往上看,对了,就是图四的效果了...
接下来给ul整体设置overflow:hidden;隐藏多出粉色边框的部分,就看到图一的效果了~
下方轮播图切换点的控制:
这个就很简单了,有m张图,就放m个点。点击第一个点(也是默认情况),将每个li绕x轴旋转(360/m)*0度;点击第二个点,将每个li绕x轴旋转(360/m)*1度;... 直到点击第m个点,将每个li绕x轴旋转(360/m)*(m-1)度。接下来,我们再给每个li多边体加上过渡transition:1s;transition-delay:
erspecitve到底什么鬼?
说了这么多,效果都实现了,我咋还不讲perspective呢?别急,这不是来了嘛... 如文章一开始所说,perspective会让你看到一种3d立体空间感,而非二位平面的体验了。本例中的perspective用在了class=‘swiper-wrapper’的蓝色边框元素上,赋值perspective:1000px; 它的取值越小,你在电影院的座位越靠前,视觉效果越近;反之,取值越大,你在电影院座位约靠后,视角越远。实际应用中,800-1000px效果较好,相当于电影院四五排的座位,got it?聪明的人一定get了... 下面上对比效果图:
完整代码如下:
HTML:
1 <div class="swiper-wrapper"> 2 <ul ></ul> 3 <div ></div> 4 </div>
CSS:
1 .swiper-wrapper{
2 width: 600px;
3 height: 350px;
4 margin-top: 100px;
5 padding: 10px;
6 box-shadow: 0px 0px 10px 5px skyblue;
7 transform-style: preserve-3d;
8 perspective: 1000px;
9 perspective-origin: 50% 50%;
10 }
11 .swiper-wrapper ul{
12 position: relative;
13 width: 600px;
14 height: 300px;
15 box-shadow: 0px 0px 10px 2px pink;
16 overflow: hidden;
17 /*transform:translate/rotate(0px/deg); 若加这个属性,则3d效果消失。*/
18 }
19 .swiper-wrapper ul li{
20 position: absolute;
21 height: 300px;
22 transform-style: preserve-3d;
23 transform-origin:0px 50% 0px;
24 transform: rotateX(0deg);
25 transition: transform 1s;
26 }
27 .swiper-wrapper ul li div{
28 position: absolute;
29 left: 0;
30 top: 0;
31 width: 100%;
32 height: 100%;
33 background-repeat: no-repeat;
34 }
35 .swiper-wrapper .dots{
36 height: 46px;
37 box-shadow: 0px 0px 10px 2px pink;
38 text-align: center;
39 }
40 .dots span{
41 display: inline-block;
42 width: 10px;
43 height: 10px;
44 margin: 10px;
45 background-color: pink;
46 border-radius: 10px;
47 transition: all .5s;
48 }
49 .dots span.selected{
50 background-color: red;
51 }