LouieLiu

CSS3与3D轮转(一)

  最近在做IFE的任务,其中一个任务是利用CSS3实现3D轮播图 简单来说就是利用css3中transform属性中的rotateY实现轮播图的角度偏转 利用translateZ()让图片沿Z轴平移 利用transform-style: preserve-3d 实现3D效果 用persepective展现出3D视距 然后利用animation属性实现转动 接下来仔细说说这个过程和其中涉及到的这几个CSS3的属性说之前先看一下最终效果


CSS3 transform

好了那么先来看看MDN中怎么解释这个属性

CSS中transform 属性允许你修改CSS可视化模型的坐标空间。通过transform,可以让元素进行移动(translate)、旋转(rotate)、缩放(scale)、倾斜(skew)如果该属性有一个非none值, 将会产生一个层叠上下文. 在这种情况下 对象将作为它包含的 position: fixed 元素的包含块(a containing block)


(附:三维坐标)

1
transform: none|<transform-function>[<transform-function>]

transform默认值是none 不进行变换 表示一个或者多个变换函数 用空格间隔 下面就几个常用的transform属性值进行介绍

transform-origin

在说其他属性之前先说一下transform-origin属性 transform-origin属性是定义操作元素的基点 所有的transform属性对元素进行操作变换若无定义transform-origin 则默认操作是以元素中心为基点 如果需要改变基点的位置 可以通过设置transform-origin属性来完成 它的值可以为百分比 em px 也可以是left right top bottom center 其中 left,center right是水平方向取值,对应的百分值为left=0%;center=50%;right=100%而top center bottom是垂直方向的取值,其中top=0%;center=50%;bottom=100%;如果只取一个值,表示垂直方向值不变

1
2
transform-origin:0 0;
transform:rotate(30deg);

transform

[若不做特殊说明则以下默认transform-origin:50% 50%]

translate[平移]

translate包含包含三种情况translateX() translateY() translate(x,y)
注:若给定的值是百分比则以自身的width和height作为基准

translate(x,y)

translate(x,y)它表示按照x y的值对元素进行平移操作 当值为负 反向移动 例如:

1
transform:translate(50px,50px);

translateX

translateX()通过给定一个值 使元素只向x轴(水平)方向移动 例如:

1
transform:translateX(50px);

translateY

translateY()通过给定一个值 使元素只向y轴(垂直)方向移动 例如:

1
transform:translateY(50px);

rotate[2D旋转]

rotate() 通过设置一个角度对指定元素进行2D旋转 角度为正则表示为按照顺时针方向旋转 角度为负则逆时针方向 例如:

1
transform:rotate(30deg);

scale[缩放]

通过scale缩放元素与translate很像 其中scale(x,y)使元素水平方向与垂直方向同时缩放 scaleX()元素仅水平方向缩放 scaleY()仅竖直方向缩放 它们的缩放中心就是基点 可以通过改变translate-origin属性改变缩放中心位置 缩放基数为1 如果其值大于1 元素就放大 反之则元素缩小

1
transform:scale(2,1.5);


使用scaleX()进行矢量缩放 scaleX表示元素只在x轴(水平)方向缩放元素

1
transform:scaleX(1.5);


使用scaleY()进行矢量缩放 scaleY表示元素只在y轴(垂直)方向缩放元素

1
transform:scaleY(1.5);

skew[倾斜]

1
transform: skew(ax[, ay]) /* one or two <angle>s, e.g. skew(30deg,20deg) */

元素在x轴和Y轴方向上以指定角度倾斜 如果ay未提供 则在Y轴上没有倾斜 同样元素中心为默认基点 例如:

1
transform: skew(30deg,20deg);

skewX(): 按给定的角度沿X轴指定一个skew transformation(斜切变换)并在水平方向(X轴)倾斜

1
transform: skewX(30deg);


skewY(): 按给定的角度沿Y轴倾斜

1
transform: skewY(20deg);

matrix[矩阵]

transform-style

1
2
3
translate-style:flat|preserve-3d;
transform-style:flat;/*默认值 指定子元素位于此元素所在平面内*/
transform-style:preserve-3d; /* 指定子元素定位在三维空间内 */

transform-style属性指定了,该元素的子元素是(看起来)位于三维空间内,还是在该元素所在的平面内被扁平化。如果被扁平化即所选值为flat,则子元素不会独立的存在于三维空间。因为该属性不会被(自动)继承,所以必须为元素所有非叶后代节点设置该属性 若所选值为preserve-3d则指定子元素将在三维空间内显示

当为一个容器设定了transform-style的属性值为preserve-3d 则容器的后代元素将以3D效果呈现 也就是说相对于容器本身可以对其子元素做3D变形操作 3D变形与2D类似 多出来对空间坐标Z的操作

translate[3D位移]

可以使用translate3d(x,y,z)进行3D位移操作也可以分为translateX() translateY() translateZ()

rotate[3D旋转]

1
2
3
4
rotate3d(<X-angle>,<Y-angle>,<Z-angle>);
rotateX(<angle>);
rotateY(<angle>);
rotateZ(<angle>);

rotateX()旋转方式如图:

rotateY()旋转方式如图:

rotateZ() 旋转方式如图:

scale

分别为scaleX() scaleY() scaleZ() 或者scale3d(x,y,z) 与2D操作没什么太大区别

persepective

perspective 属性指定了观察者与z=0平面的距离,使具有三维位置变换的元素产生透视效果。z>0的三维元素比正常大,而z<0时则比正常小,大小程度由该属性的值决定

1
prespective:number|none; /* 指定观察者距离z=0平面的距离,为元素及其内容应用透视变换。当值为0或负值时,无透视变换 */

当未设置prespective时[即值为none/0]元素的所以子元素被压缩在同一个二维平面内 将不会呈现出3D透视效果 同时透视元素的基点默认为元素中点[即默认值 prespective-orgin:50% 50%] 可以通过prespective-origin属性设置不同的基点 persepective-orgin属性的取值用法与transform-orgin类似 需要特别注意的是 三维元素在观察者后面的部分不会绘出来,即z轴坐标值大于perspective属性值的部分 CSS3 3D变换中的透视的透视点是在浏览器的前方 所以在关于轮播图中要特别注意 设置perspective的值一定要大于z 否则无法观测完全

实现3D效果

首先要完成一个3D轮转需要给其提供一个用于展示的平台姑且叫它“舞台”我们还需要容器来承载这个轮转的任务 接下来就把图片放入到这个容器中就行了 所以整体HTML框架是这样的
-舞台
– 容器
—– 图片
—– 图片
—– 图片
—– …

1
2
3
4
5
6
7
8
9
<div id="stage">
<div id="container">
<img class="img item1" src="...">
<img class="img item2" src="...">
...
<img class="img item9" src="...">
</div>
</div>
</div>

我们给容器(container)添加transform-style属性给舞台一个perspective距离 使其子元素可以以3D形式展示同时设置基点为其中心

1
2
3
4
5
6
7
#stage{
persepective:900px;
}
#container{
transform-style: preserve-3d;
perspective-origin: 50% 50%;
}

然后给所有的img一个绝对定位 因为3D旋转主要是绕Y轴运动 所以设置rotateYd的大小就好 根据个人添加image的数量 平分整个圆周角 设置每个img的rotateY所旋转的角度 即让所以照片旋转一定的角度依次散开 可以围成一圈 现在是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.img {
position:absolate;
}
.item1{
-moz-transition:rotateY(0deg);
-webkit-transform:rotateY(0deg);
-o-transform:rotateY(0deg);
transform: rotateY(0deg);
}
.item2{
-moz-transition:rotateY(40deg);
-webkit-transform:rotateY(40deg);
-o-transform:rotateY(40deg);
transform: rotateY(40deg);
}
...
.item9{
-moz-transition:rotateY(320deg);
-webkit-transform:rotateY(320deg);
-o-transform:rotateY(320deg);
transform: rotateY(320deg);
}


这些照片已经按照指定的角度偏转了 接下来要做的就是让它们以基点(也就是中点)为中心分散开 现在就到translateZ()大显身手的时候了 给每个image设定translateZ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.item1{
-moz-transition:rotateY(0deg) translateZ(350px);
-webkit-transform:rotateY(0deg) translateZ(350px);
-o-transform:rotateY(0deg) translateZ(350px);
transform: rotateY(0deg) translateZ(350px);
}
.item2{
-moz-transition:rotateY(40deg) translateZ(350px);
-webkit-transform:rotateY(40deg) translateZ(350px);
-o-transform:rotateY(40deg) translateZ(350px);
transform: rotateY(40deg) translateZ(350px);
}
...
.item9{
-moz-transition:rotateY(320deg) translateZ(350px);
-webkit-transform:rotateY(320deg) translateZ(350px);
-o-transform:rotateY(320deg) translateZ(350px);
transform: rotateY(320deg) translateZ(350px);
}


现在就差让它动起来了 当然animation属性可以完成这个任务 给包裹image的容器设置animation属性就可以了

参考链接:
【CSS3进阶】酷炫的3D旋转透视
transform
CSS3 Transform