• 技术文章 >web前端 >css教程

    CSS3景深和三维变换属性及旋转三维立方体的具体实现方法(图文)

    黄舟黄舟2017-05-21 15:54:37原创948

    上周简单写了一下2D变换

    今天来写写3D变换
    三维立体效果我觉得是CSS3中最有意思的地方
    不得不佩服那些开发者大神们
    让我们能够通过几行CSS代码就能得到酷炫的视觉体验

    浏览器坐标系

    在讲正式语法之前,首先需要了解浏览器坐标系
    这需要我们把浏览器界面想象成一个立体的场景

    这是网上流传很广的浏览器坐标系图片
    从左到右的方向是浏览器x轴的正方向
    从上到下的方向是浏览器y轴的正方向
    而z轴正方向是面对于我们的
    了解这个很重要,因为下面我们旋转元素需要借助它来理解

    3D旋转

    我们在平面中使用的旋转只是单纯的让元素在平面旋转一定角度
    在三维旋转中稍微要复杂一下
    属性当然还是用我们的transform
    三维旋转有下面三个函数分别对应三个维度的旋转


    rotateX是让元素绕着x轴旋转,角度越大,元素绕着x轴顺时针旋转
    类似于我们的单杠运动

    transform: rotateX(45deg);


    rotateY是让元素绕着y轴旋转,角度越大,元素绕着y轴顺时针旋转
    类似于钢管舞运动..

    transform: rotateY(45deg);


    rotateZ是让元素绕着z轴旋转,角度越大,元素绕着z轴顺时针旋转
    这就是我们在二维平面的旋转,类似于转盘

    transform: rotateZ(45deg);


    其实3D旋转还有一个合成的函数是rotate3d(num,num,num,deg)
    用的不是很多,我就简单说一下
    参数并不是我们想那样的3个角度值
    而是三个数字一个角度值
    前三个数字分别表示绕x、y、z轴旋转的矢量值
    最后一个表示在空间的旋转角度,等价关系如下

    rotate3d(1,0,0,xxdeg) <==> rotateX(xxdeg) 
    rotate3d(0,1,0,xxdeg) <==> rotateY(xxdeg) 
    rotate3d(0,0,1,xxdeg) <==> rotateZ(xxdeg)

    3D位移与3D缩放

    我们在2D中用到translateX()和translateY()在平面移动
    3D中我们多了translateZ()允许我们沿着z轴平移
    同样可以使用合成函数translate3d(x,y,z)
    注意前两个值可以使用百分比形式,但是沿z轴平移的值只能使用长度值

    同理我们的3D缩放
    scaleX(num)、scaleY(num)、scaleZ(num)、scale3d(num,num,num)
    至于它们的用法下面再通过例子来说
    (3D的倾斜属性是不存在的,换句话说,不存在skew3d函数)

    透视/景深属性perspective

    景深这个名词,维基百科是这样就解释的

    景深(英语:Depth of field, DOF)景深是指相机对焦点前后相对清晰的成像范围。在光学中,尤其是录影或是摄影,是一个描述在空间中,可以清楚成像的距离范围。虽然透镜只能够将光聚到某一固定的距离,远离此点则会逐渐模糊,但是在某一段特定的距离内,影像模糊的程度是肉眼无法察觉的,这段距离称之为景深。当焦点设在超焦距处时,景深会从超焦距的一半延伸到无限远,对一个固定的光圈值来说,这是最大的景深。

    (看到这里,我的手默默的离开了键盘,仰天长叹,心想,这到底要什么样的学历才能看得懂)
    我们可以这样来理解
    景深就是我们的肉眼距离显示器的距离
    景深越大,元素离我们越远,效果就不好
    在我们CSS3中,perspective用于激活一个3D空间
    属性值就是景深大小(默认none无景深)
    有两种用法

    .stage {    perspective: 500px;}

    应用景深的元素称为“舞台元素”
    舞台元素的所有后代元素都会受影响
    (如果后代元素中也添加了perspective属性,效果会叠加而不是覆盖)


    <p class="stage">
        <p class="demo"></p></p>
    .stage 
    {    
    width: 200px;    
    height: 200px;    
    border: 1px solid black;    
    margin: 100px auto;}
    .stage 
    .demo 
    {    
    width: 200px;    
    height: 200px;    
    background-color: orangered;    
    transform: rotateX(45deg);}

    在这个例子中,我们把内部元素绕x轴旋转了45°后
    由于他只是在二次元旋转,所以我们根本看不出来它旋转
    但是我们现在加个景深

    .stage {    
    width: 200px;    
    height: 200px;    
    border: 1px solid black;    
    margin: 100px auto;    
    perspective: 500px; /*增*/}.stage 
    .demo {    
    width: 200px;    
    height: 200px;    
    background-color: orangered;    
    transform: rotateX(45deg);}

    这就相当于我们在舞台元素的中心位置往里看,这个子元素距离我们肉眼有500px
    由于子元素的顺时针旋转,
    元素上半部分离我们远,所以看起来很小
    元素下半部分离我们近,所以看起来稍大
    这样就会产生很强的立体感


    刚才我说道我们的肉眼相当于在舞台元素中心的位置
    其实这个“眼睛”的位置是可以调整的
    这用到了perspective-origin属性
    默认的属性值就是 50% 50%
    也就是舞台元素的中心位置
    我们可以尝试调整视角

    .stage {    
    width: 200px;    
    height: 200px;    
    border: 1px solid black;    
    margin: 100px auto;    
    perspective: 500px;    
    perspective-origin: 10px 10px; /*增*/}.stage 
    .demo {    
    width: 200px;    
    height: 200px;    
    background-color: orangered;    
    transform: rotateX(45deg);}

    这就相当于在舞台元素的距离原点(左上)10px,10px的位置往里看
    理解这个需要我们一定的空间立体感

    注意:景深大小一定要比你的动画元素大(我们不可能看到眼睛后面的东西)


    景深的另一种用法,是应用在动画元素(不是舞台元素)变形的函数中
    和其他变形函数写在一起

    .stage .demo {    ......
        transform: rotateX(45deg) perspective(100px);}

    3D属性transform-style

    这个属性指定了子元素如何在空间中展示
    只有两个属性值:flat(默认)和preserve-3d
    flat 表示所有子元素在2D平面呈现
    preserve-3d 表示所有子元素在3D平面呈现
    (prederve是保护、维持的意思,preserve-3d就是保持三维空间的意思)
    当然如果我们想要3D的效果,就要使用 transform-style: preserve-3d;


    这个属性只是针对设置属性元素的子元素如何展示
    而对子元素的子元素无效
    而且对于设置了overflow: hidden;的元素,设置3D效果会失效
    道理很简单,跳出了父元素平面的子元素无法显示了,结果自然还是2D效果
    应用于这个属性的元素我们称作“容器”
    这个属性我们下面通过一个例子再来体会

    背面可见属性backface-visibility

    通过这个元素我们可以指定当元素背对我们时是否可见
    只有两个属性值visibility(默认)和hidden
    如果我们希望元素背对我们不可见
    就这样设置

    .demo {    ...
        backface-visibility: hidden;
    }

    下面我通过一个例子来把上面讲到的属性全部实践一下

    示例:旋转的三维立方体

    <p class="stage">  <!--舞台元素,视角所在-->
        <ul class="three-d-box">   <!--动画容器,通过它来控制整个立方体-->
            <li>♑</li>  <!--动画元素,立方体的六个面-->
            <li>♍</li>
            <li>♌</li>
            <li>♋</li>
            <li>♎</li>
            <li>♓</li>
        </ul></p>
    ul {  /*调整ul标签的样式,取消内边距、外边距,和“点”样式*/
        padding: 0;    margin: 0;    list-style-type: none;}.stage {  /*设置舞台元素在屏幕居中,设置合适的景深大小*/
        position: relative;    width: 800px;    height: 800px;    margin: 100px auto;    perspective: 800px;}@keyframes move { /*设置动画关键帧*/
        0% {        transform: rotateX(0deg);    }
        25% {        transform: rotateX(180deg);    }
        50% {        transform: rotateX(360deg) rotateY(0deg);    }
        75% {        transform: rotateX(360deg) rotateY(180deg);    }       
        100% {        transform: rotateX(360deg) rotateY(360deg);    }}.stage .three-d-box {  /*动画容器居中在舞台元素中间*/
        width: 200px;    height: 200px;    position: absolute;    left: 50%;    top: 50%;    margin: -100px 0 0 -100px;    transform-style: preserve-3d; /*设置3D属性让子元素三维空间呈现*/
        animation: move 3s linear infinite; /*设置动画*/}.stage .three-d-box>li { /*设置动画子元素公共属性*/
        position: absolute;    width: 200px;    height: 200px;    left: 0;    top: 0;    font-size: 50px;    line-height: 200px;    text-align: center;    opacity: 0.5;}/*为了保证我们对立方体位置的控制,我们需要让动画容器在立方体的中间位置*/.stage .three-d-box>li:nth-child(1) {    background-color: red;    transform: translateZ(-100px);}.stage .three-d-box>li:nth-child(2) {    background-color: greenyellow;    transform: translateZ(100px);}.stage .three-d-box>li:nth-child(3) {    background-color: cornflowerblue;    transform: rotateX(90deg) translateZ(100px);}.stage .three-d-box>li:nth-child(4) {    background-color: orangered;    transform: rotateX(-90deg) translateZ(100px);}.stage .three-d-box>li:nth-child(5) {    background-color: deeppink;    transform: rotateY(90deg) translateZ(100px);}.stage .three-d-box>li:nth-child(6) {    background-color: lightcoral;    transform: rotateY(-90deg) translateZ(100px);}

    大功告成
    这样我们就会得到如下酷炫的三维立方体

    注意在3D变换transform中,旋转与位移函数的顺序不同,元素展现的位置是不同的
    这是因为元素的坐标轴是随着我们变换而变化的

    上面的代码如果有不明白的地方,可以拷贝到浏览器进行调试
    整体的思路就是

    1. 设置舞台元素(perspective:xxxpx)

    2. 设置动画容器(transform-style:preserve-3d)

    3. 通过旋转、位移调整动画子元素的位置

    4. 对动画容器应用动画效果


    最后我们通过这个正方体来加深三维变换相关属性的理解
    backface-visibility
    添加样式前的正方体

    现在我们来添加样式

    .stage .three-d-box>li {    ......
        backface-visibility: hidden;}

    大家来找茬
    可以看到背对我们的元素全部看不见了
    这就是backface-visibility: hidden;的作用

    还有一些旋转、缩放、平移的属性这里我就不再测试了
    大家可以打开控制台自己体会一下,和2D中的用法是类似的

    以上就是CSS3景深和三维变换属性及旋转三维立方体的具体实现方法(图文)的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:CSS3中的盒模型与盒模型属性box-sizing的详细介绍 下一篇:关于CSS3元素中过渡属性transition的详细介绍
    Web大前端开发直播班

    相关文章推荐

    • css3怎么改首字母颜色• 如何利用CSS来美化滑动输入条?自定义样式方法浅析• CSS如何进行性能优化?优化小技巧分享• 聊聊如何用CSS box-shadow创建像素创意动画• web前端笔试题库之CSS篇

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网