好久没写教程了,这几年忙着上课备课,学习新的框架,忙着新公司的事情,一点空余的时间都榨不出来,结果新公司还是干倒闭了,万事皆空……!
趁着现在没工作,把教程案例整理一下,算是做个总结。也不知道自己前端开发这个方向的职业生涯是否已经结束,毕竟这个就业市场对我们老人太不友好了。
如果我真的转行了,这个网站就是我十多年职业生涯的坟墓,欢迎大家来盗墓,哈哈……
一、3D变换
首先理解我们生活的环境就是三维空间的,有平面,有纵向的高度。
而通过拍照片就是把三维的空间变成了二维的。
1、三维空间的特点
1、近大远小
2、近高远低
3、近疏远密
4、近实远虚
5、被遮挡的背面不可见
1.2 三维坐标系
三维坐标系就是表现立体空间的三个轴向,由x、y、z构成。
x轴:水平向右为正,向左为负值
y轴:垂直向下为正,向上为负值
z轴:垂直屏幕,往外面为正,往里面为负值
1.3 3D旋转
rotateX()
rotateY()
rotateZ()
rotate3d(x,y,z,deg) 了解即可
https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform-function/rotate3d
可以把沿着x轴旋转看成是体操单杠
沿着y轴旋转看成是蔡依林的钢管舞
旋转飞刀的特技表演是沿着z轴旋转
1.4 3D移动
translateX() 沿着x轴移动
translateY() 沿着y轴移动
translateZ() 沿着z轴移动 ,不能是百分比的值。
translate3d(x,y,z) 不能省略x、y、z的值,可以设置为0
发现普通的2D变换写法,translateZ没有效果,这是为什么呢?
我们需要了解透视的原理。
1.4 透视perspective
perspective
属性的存在与否决定了你所看到的是2次元的还是3次元的,也就是是2D transform还是3D transform. 这不难理解,没有透视,不成3D.
学过一点点美术的人应该都听过一点透视:
两条平行线在透视里也有相交的那一天!
CSS3 3D transform的透视点默认是在浏览器的前方!
显示器中3D效果元素的透视点在显示器的前方(不是后面),近似就是我们眼睛所在方位!
perspective透视能给舞台(scene,变换元素所处的空间)添加纵深感,结果就是元素距离观看者越近就表现得越大,越远就表现得越小(通过变换可以改变元素在Z轴上的位置)。
perspective属性指定观看者的眼睛(假设的)与屏幕 (drawing plane)之间的距离。如果将perspective属性的值设为d,则元素的缩放比例就等于d/(d − z),z是元素在Z轴上的位置,更准确的说是变换前元素所在的与Z轴垂直的平面在Z轴上的坐标位置。
把物体通过translateZ移动到距离眼睛越近,在屏幕上形成的成像面积越大。
d:是视距的大小,也就是perspective的值,需要在被观察的物体的父元素上设置
z:是物体移动的translateZ的值
元素的缩放比例: d / (d - z)
perspective属性
可取值:none | <length>
<length>只能为正值,是观看者与z=0平面的距离,使具有3D变换的元素产生透视效果(当值为0或负值时,无透视效果,变换元素表现为扁平化)。
值为none时,无透视效果,元素在画布上扁平化呈现。
perspective属性值不为none的元素,创建一个层叠上下文和一个包含块(规范上说和相对定位有点类似,和transform很像)。
1.5 perspective-origin
该属性设置了观看者的眼睛在舞台元素上的投影位置.
可取值:<percentage> | <length> | 关键字
默认值为:50% 50%
第一个值表示与border box左边界的距离,第二个值表示与border box上边界的距离。当只指定一个值时,第二个值作为50%处理。
<percentage>相对于舞台元素的border box的尺寸计算。
x-position
<percentage> 百分比,相对于元素宽度,可为负值。
<length> 长度值,可为负值。
left,关键字,0值的简记。
center,关键字,50%的简记。
right,关键字,100%的简记。
y-position
<percentage> 百分比,相对于元素的高度,可为负值。
<length> 长度值,可为负值。
top,关键字,0值得简记。
center,关键字,50%的简记。
bottom,关键字,100%的简记。
1.6 3D渲染上下文
一个3D渲染上下文本质上是一个三维坐标系,这个三维坐标系由一组具有共同祖先(舞台元素)并且进行3D变换的元素共享。
在3D渲染上下文中的元素在渲染时层次关系由他们在Z轴上的位置决定。如果3D变换使他们相互交叉,那么在渲染时就让他们交叉着渲染。
首先transform-style属性值为flat的元素创建一个3D渲染上下文,把这个元素称为祖先元素(舞台元素)。
默认情况下,perspective属性值不为none的元素是扁平的(flattening),因此它创建一个3D渲染上下文。
其次,如果后代元素的transform-style属性值为auto或preserve-3d,则该后代元素将其所处的3D渲染上下文(enclosing 3D rendering context)共享给它包含的后代元素。
把transform-style属性的值设置为preserve-3d可以让这个透视元素(perspective element)扩展包含他的3D渲染上下文的范围至他的后代元素。
再次,如果一个后代元素的transform-style属性值为flat,它虽然参与到包含他的父3D渲染上下文(containing 3D rendering context)中,但是同时对于它包含的后代元素,它也创建一个新的3D渲染上下文。不过,对于这个新创建的3D渲染上下文,在渲染时不是作为一个三维空间渲染,而是作为一个平面渲染。
注意:3D渲染上下文的概念类似于层叠上下文的概念。一个有明确z-index值的定位元素自身创建一个层叠上下文,但是他还是参与到他所处的祖先元素创建的层叠上下文中。相似地,一个元素能为他的后代元素创建一个3D渲染上下文,但是他自身还是参与到他的祖先元素创建的3D渲染上下文中。就像元素在层叠上下文中按照z-index属性决定的层次渲染一样,元素在3D渲染上下文中按照z-depth顺序渲染而且可以互相交叉。
一些CSS属性值使一个元素及其后代元素在渲染时作为一个整体渲染。本质上这些CSS属性值强制将元素的transform-style属性的值重设为flat,这些元素被称为扁平元素(flattening elements)。所以这些元素都会创建一个新的3D渲染上下文。根元素的transform-style属性的值为flat。
1.7 transform-style
该属性要在父元素上设置,对该父元素的子元素(或者说后代元素)起作用。
transform-style:flat ; 子元素不开启3d立体空间,默认值
transform-style:preserve-3d ; 子元素开启立体空间,看起来和父元素处于同一个立体空间中。
transform-style的可取值为:auto | flat | preserve-3d
默认值为 auto,不可继承。
当transform-style的值为“flat”时,元素创建一个层叠上下文(stacking context)和一个3D渲染上下文(3D rendering context)。
transform-style属性值为“auto”的元素在计算3D渲染上下文时会被忽略。
transform-style属性值为“preserve-3d”的元素会扩大其所处的3D渲染上下文的范围,即使transform 或 preserve属性的值会导致扁平化。同时,transform-style属性值为“preserve-3d”的元素会创建一个层叠上下文和一个包含块。
以下CSS属性值会导致后代元素(descendant elements)扁平化显示,也就是说强制父元素transform-style属性的值转变为“flat”:
overflow: 除了 visible的其它值.
opacity: 小于1的值.
filter: 除了none的值.
以下CSS属性值会使transform-style的默认值重设为flat:
transform: 除了none的值.
perspective: 除了none的值
总结:perspective属性可以为3D变换上下文中的后代变换元素提供一个共同的透视变换矩阵,从而被用来确保这些3D变换元素好像处在同一个有深度的三维空间中。把transform-style属性的值设置为preserve-3d,可以让这个透视元素扩展包含他的3D渲染上下文的范围至他的后代元素。
1.8 Backface Visibility 背面可见性
backface-visibility属性
可取值:visible | hidden
默认值:visible
该属性对2D变换无效。
visible 表示背面可见,允许显示正面的镜像。
hidden 表示背面不可见。
利用三维变换,使看到变换元素的背面成为可能。在背面可见的情况下,不管是哪一面,3D变换元素都显示同样的内容,背面内容是前面内容的镜像(就好像元素被投影到一面镜子上)。默认情况下,当元素的背面朝向观看者时,观看者可以看到这个背面的内容。事实上,当元素的背面朝向观看者时,开发者可以通过backface-visibility属性,让该元素的内容不可见。
如果一个动画元素的backface-visibility属性的值为hidden,那么他的内容是交替可见的。只有当他的前面朝向观看者时,他的内容才是可见的。
我们可以自己设置前面和背面的内容。
比如经典的翻转案例,点击图片看效果,通过拖动进度条可以看到图片被翻转成另一张图片了。
1.9 transform-origin
改变元素的中心点的位置。
默认是以元素的中心点进行缩放,可以利用transform-origin
属性修改中心点,定位和background-position
的用法一样。
left center right
top center bottom
%
length
总结
要实现3D变换,要用到下面几个属性:
属性 | 描述 | CSS版本 |
transform | 向元素应用 2D 或 3D 转换。 | 3 |
transform-origin | 设置变换基点(局部坐标系原点)的位置。 | 3 |
transform-style | 规定被嵌套元素如何在 3D 空间中显示。 | 3 |
perspective | 规定 3D 元素的透视效果。 | 3 |
perspective-origin | 规定观看者眼睛的投影位置。 | 3 |
backface-visibility | 定义元素内容在不面对屏幕时是否可见。 | 3 |
2、案例
举一个旋转木马的例子吧,这个比较常见。
点击图片看效果。
核心代码如下:
.banner{ width: 200px; height: 200px; margin: 300px auto; perspective: 500px; perspective-origin: bottom center; } .list{ transition: 10s; transform-style: preserve-3d; position: relative; height: 200px; animation: rotate 10s linear infinite; } .list:hover { animation-play-state: paused; } .item{ position: absolute; } .item:nth-child(2){ transform:rotateY(0deg) translateZ(200px); } .item:nth-child(3){ transform:rotateY(60deg) translateZ(200px); } .item:nth-child(4){ transform:rotateY(120deg) translateZ(200px); } .item:nth-child(5){ transform:rotateY(180deg) translateZ(200px); } .item:nth-child(6){ transform:rotateY(240deg) translateZ(200px); } .item:nth-child(7){ transform:rotateY(300deg) translateZ(200px); } /* .list:hover{ transform: rotateY(-360deg); } */ @keyframes rotate { to { transform: rotateY(-360deg); } }
当然这种常见的转圈圈的图片效果也没问题了。点击看看吧。
还有经典的正方体也举一反三了。
发表评论:
◎请发表你卖萌撒娇或一针见血的评论,严禁小广告。