css3 2d/3d变换——实现超炫的特效

来源:互联网 发布:小阴唇肥大 知乎 编辑:程序博客网 时间:2024/05/20 05:54

声明:所有结论都是经过实际代码运行的效果证实的,如果有不同的情况发生,请核对浏览器版本以及内核(360浏览器,webkit内核)是否与本人试验的时候一致,同时非常感觉读者阅读本文,如有错误之处,欢迎大家留言指出。

css3的2d/3d变换是一个很强大的功能,以前想要做到图片的倾斜或者旋转某个角度,都无法简单的做到,更别说3d效果的实现,这里的3d效果其实也是一种2d变换之后给人的一种视觉欺骗达到的,浏览器这个“平面”客户端确实无法做到真正的3d效果,现在css3就给我们提供了一种简单的方法来做到2d/3d效果。下面我给大家分享一下我的学习心得。

一、坐标轴和参考点(旋转基点)

1、参考点(旋转基点)

相信大家对于参考点这个概念并不会陌生,见名知意的一个词语,css的参考点就是元素所围绕其旋转的点,在css中用一个属性设置旋转基点,如下所示:

transform-origin: left top; // 设置该元素的旋转基点为该元素的左上角

transform-origin属性是css变换的一个重要的属性,一般需要设置2个值:

第一个值为偏移x轴方向的距离,可以用关键字left|right|center或者百分比以及具体的距离值描述。

第二个值为偏移y轴方向的距离,可以用关键字top|bottom|center或者百分比以及具体的距离值描述。

第三个值为偏移z轴方向的距离,只能使用具体的距离值描述,这个值是使用在开启了3d模式下使用的,并且不怎么常用,第三个值默认值为0。

Tips:当只设置一个值的时候,那就意味着第二个值默认为center,第三个值默认为0

2、坐标轴

要想理解变换,那么必须要有一个参考点和参考坐标系,想必大家已经对html元素的x和y轴已经有了一定的认知,没错:x轴的正方法是水平向右,y轴正方形是垂直向下的。那么3d坐标轴又是什么样的呢?

我从网上扣了一张图下来:

我们可以将黑色网看做我们的屏幕平面,x、y轴的方向跟上面所讲的是一致的,z轴正方形是垂直屏幕面向我们的。

当我们旋转一个元素的时候,怎么确定其正方向和负方向呢?就那绕着z轴做旋转的元素来说,旋转10deg (deg是css的角度单位)和旋转-10deg应该是什么样子的呢?如下图所示:

对于一些新手来说,很难记住其旋转的正负方向,这里教给大家一个技巧:

css旋转的左手定律:拿出你们的左手,用大拇指指向旋转所围绕的坐标轴的正方向,4指弯曲所围绕的方向就为旋转的正方向——Hu渣渣

读者可以拿上面一张图片的俩个元素来比对试验一下。上面那张图是以中心为旋转基点的,可能不太容易观察,下面贴出一张以左上角为旋转基点围绕着z轴旋转的图,读者可以再使用左手定律再试一下:

二、2d变换

说完了坐标轴和参考点之后,我们就进入正题,说说2d变换。

2d变换一共有2个属性、4个方法,这是什么意思呢?意思其实很简单,意思是:能够控制元素做2d变换的style样式属性只有2个,一个是transform-origin(前面说的旋转基点)、transform(变换方法)。旋转基点在上面已经说过了,在这里就不做重复了,接下来就聊一聊4种变换方法。

1、2d变换中的4中变换方法

a. translate(位移,单位px等)

translate(x,y) 沿着x轴正方向移动x距离 y轴正方向移动y距离translateX(n) 沿着x轴正方向移动n距离translateY(n) 沿着y轴正方向移动n距离

b. scale(缩放,无单位)

scale(x,y) 更改元素的宽度和高度,将元素的宽度变为原来的x倍,将高度变为原来的yscaleX(n) 更改元素的宽度scaleY(n) 更改元素的高度

当取值为负数的时候,得到的效果如下:

首先将元素绕着x、y(取决于你的缩放方向)旋转180deg,然后再进行缩放。

如果是scaleX参数为负,则将元素绕y轴翻个面。如下图所示:

如果是scaleY参数为负,则将元素绕x轴翻个面。如下图所示:

c. rotate(旋转,单位为deg)

rotate(x) 围绕z轴旋转,只接受一个参数,并且这个是2d方面的旋转,但是和后面的3d旋转中的围绕z轴旋转有着本质区别rotateX(n)  围绕x轴旋转rotateY(n) 围绕y轴旋转

可以用左手定律来判断正负方向。

d. skew(斜切,单位deg)

skew(x-angle,y-angle) 定义2d倾斜旋转 沿着x轴和y轴skewX(angle) 如果angle是正值,则沿着x轴正方向偏移斜切,负值则相反skewY(angle) 如果angle是正值,则沿着y轴正方向偏移斜切,负值则相反网上大家都把skew叫做斜切,这么喊可能不容易理解,我习惯把它叫做拉伸。skewX(angel) 就是将元素以旋转基点为坐标原点沿着x轴方向拉伸一定角度skewY(angel) 就是将元素以旋转基点为坐标原点沿着y轴方向拉伸一定角度

给大家上图解释一下:

按照图解思路,大家可以将旋转基点设置为其他值试一试,上图的旋转基点是默认值。

3d变换

3d属性

  1. 一个物体看起来如果要有3d效果,那么就需要给它加上一个属性

    transform-style: preserve-3d  /*开启3d空间*/
  2. 视距(perspective)和translateZ

    在这里为什么要将translateZ和视距一起说呢?因为他们的联系很大。视距就是眼睛距离物体原本位置的距离,而translateZ()就是用来改变 物体当前位置 离 物体原本所在位置距离的方法。可以用一张图来描述一下:

    图解:从上面这个图可以了解到,当视距为0的时候,你是看不到这个物体的,因为你的眼睛和物体平行,你是看不到的,当视距小于0的时候,那你更看不到了,因为它都跑到你的脑门后面了。当translateZ的值大于或者很接近视距的时候,就跟一个成语描述的那样,一叶障目,那整个屏幕都被这个元素占满了。

  3. 景深基点(perspective-origin)

    perspective-origin属性定义3D元素所基于的X轴和Y轴。该属性允许您改变3D元素的底部位置。s说白了就是你移动到不同的地方看这个元素,默认值是正对着元素看,即 perspective-origin: 50% 50% 0;

    第一个值可以为left|right|center|百分比|length,表示向x轴方向移动视角(眼睛所在的位置)的距离。

    第二个值可以为top|bottom|center|百分比|length,表示向y轴方向移动视角(眼睛所在的位置)的距离。

    第三个值只能是具体的length,表示视角向z轴方向移动的距离。

  4. 背面隐藏(backface-visibility)

    属性定义当元素不面向屏幕时是否可见。如果在旋转元素不希望看到其背面时,该属性很有用。默认值是visible,背面可见。

    当设置了backface-visibility:hidden;的时候,当一个元素旋转知道完全翻了一个面的时候,那么这个元素将会不可见。

3d方法

3d方法有三个,分别为位移、缩放、旋转。

1、translate3d(位移)

translate3d(x位移,y位移,z位移)

或者分开写:translateX()、translateY()、translateZ(),注意translate后面不跟3d

2、scale3d(缩放)

scale3d(x 宽缩放的倍数,y 高缩放的倍数,z 元素在z轴的缩放倍数[注意:缩放的是translateZ的值])

当然也可以分开写,如位移的写法一致。

tip:当scaleZ() 或者scale3d单独使用的时候,没有任何的效果。需要和其他的属性搭配使用

3、rotate3d(旋转)

rotate3d(x,y,z,angle)中,x,y,z值分别为矢量值,分别用来描述元素围绕x/y/z轴旋转, 取值范围在0-1之间。 angle代表元素在3D空间旋转的角度,正值的话为顺时针,负值的话为逆时针。一般不建议合起来写。

如何通过rotate3d转换成rotateX() rotateY() rotateZ() ?

rotateX(a)函数功能等同于rotate3d(1,0,0,a)
rotateY(a)函数功能等同于rotate3d(0,1,0,a)
rotateZ(a)函数功能等同于rotate3d(0,0,1,a)

总结

前面已经说过了,其实css3里面没有真正的3d,只有通过一些平面元素做一些3d的转换得到伪3d效果,然后将各个元素拼一块,这样就得到了一个看起来是3d物体的元素。

下面展示一下正方体的效果:

接下来上代码:

<!DOCTYPE html><html lang="zh"><head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <meta http-equiv="X-UA-Compatible" content="ie=edge" />    <title>正方体</title>        <style>                body {            position: relative;            width: 1000px;            margin: 100px auto;            background-color: #00CCFF;            perspective: 1300px;        }                #cube {                 left: 50%;            margin-left: -150px;            margin-top: 150px;            width: 200px;            height: 200px;            position: absolute;            transform-style:preserve-3d;            transform: rotateX(52deg) rotateY(42deg) rotateZ(68deg);        }                #cube div {            width: 100%;            height: 100%;            position: absolute;            /*left: 0;            top: 0;*/            text-align: center;            line-height: 200px;            font-size: 40px;            color: #000;            border: 1px #000 solid;            opacity: 0.5;            transform-origin: top left;        }                .top {            background-color: red;            transform: rotateX(90deg);        }                .bottom {            background-color: blue;            transform: translateY(200px) rotateX(90deg);        }                .left {            background-color: teal;            transform: rotateY(-90deg);        }                .right {            background-color: yellow;            transform: translateX(200px) rotateY(-90deg);        }                .front {            background-color: green;            transform: translateZ(200px);        }                .back {            background-color: brown;        }            </style></head><body>        <div id="cube">        <div class="top">top</div>        <div class="bottom">bottom</div>        <div class="left">left</div>        <div class="right">right</div>        <div class="front">front</div>        <div class="back">back</div>    </div></body></html>