深层次讲解CSS3中transform转换实体模型的3D渲染

2021-01-20 18:58 jianzhan

详细介绍

transform是根据1系列引流矩阵转换进行的,scale等transform-function全是对matrix的封裝。

w3里的解释是,transform根据可视性化文件格式实体模型(visual formatting model,这样汉语翻译对不对啊)并为其绘图出1个座标系,并且全部在这个座标系内开展的实际操作,如向右向下,全是在这个座标系内以像素方法表明

元素设定了transform其实不会更改元素所属的文本文档流,其合理布局依然受盒实体模型操纵,因而这里的转换的实际效果是能够与波动、精准定位并存的。

当元素设定了transform后,会为该元素界定1个座标系,而且在该座标系内开展引流矩阵转换,将转换結果投射到客户座标系(也便是具体上的左右文)中。

好几个引流矩阵转换涵数将先后从左到右测算,如transform:translate(80px, 80px) scale(1.5, 1.5),访问器会先测算位移,再放缩1.5倍。下列两种编码实际效果同样:

html

CSS Code拷贝內容到剪贴板
  1. <div style="transform: translate(80px, 80px)">   
  2.   <div style="transform: scale(1.5, 1.5)">   
  3.        <div style="transform: rotate(45deg)"></div>   
  4.   </div>   
  5. </div>  

html

CSS Code拷贝內容到剪贴板
  1. <div style="transform: translate(80px, 80px) scale(1.5, 1.5) rotate(45deg);">   
  2.  </div>  

座标原点的部位受特性 transform-origin的危害。

假如是三d转换,则还会将其添加1个三d3D渲染左右文(三d rendering context)。依据本人了解,不管有是多少个变换为三d的元素,其将自始至终在这个左右文内并将会互相危害,相近1个文本文档中的好几个被肯定精准定位的元素。

任何非none的transform值都会致使1个层叠左右文(stacking context)和包括块(containing block)的建立。

转换3D渲染实体模型
为transform特性特定1个除none的值便会在元素上建立1个新的部分座标系统软件而且运用于这个元素。根据元素的转换实体模型,元素能够绘图3D渲染出自身的座标系统软件。转换是能够累积的。也便是说,元素能够根据父元素的座标的系统软件来创建自身的部分座标系统软件。从客户的视角看,1个元素不仅能够从它的先祖元素上合理的累积transform特性,并且还可以给自身提升transform特性并运用与自身。这些转换的累积为元素勾勒出了当今的转换实体模型。

带有两个轴的座标室内空间:X轴水平向右为正,Y轴竖直向下为正。立体式的转换涵数提升了座标室内空间将其延生至了3维室内空间,提升的Z轴竖直与显示屏,而且朝向观查者的方位为正(也便是电脑上显示屏前的大家)。如图。

转换实体模型根据以下的transform和transform-origin特性开展测算

从实际的实体模型刚开始
根据transfrom-origin的X,Y,Z测算值开展挪动
从左到右复合型运用在transform特性中的transform functions
使以前设定的transform-origin的值失效并开展挪动
EXAMPLE1

CSS Code拷贝內容到剪贴板
  1. div {   
  2.   transform: translate(100px,100px);   
  3. }  

EXAMPLE2

CSS Code拷贝內容到剪贴板
  1. div {   
  2.   height100px;   
  3.   width100px;   
  4.   transform-origin: 50px 50px;   
  5.   transform:rotate(45deg)   
  6. }  

transform-origin根据在X,Y轴方位上各挪动50px来挪动原点。元素沿着原点顺时针转动了45°。当全部的transform functions都运用后,平移后的原点在X,Y轴上又各挪动了⑸0px,返回了原先的部位。如图

了解
上面的话的意思便是,transform-origin的起止点是在原点的部位,转动紧紧围绕着transform-origin在转,挪动transform-origin是从原点刚开始的,而并不是transform-origin的默认设置部位刚开始挪动的(默认设置为元素管理中心,上例正好也不久好挪动到元素的管理中心部位),transform-origin挪动完后,并在元素上早已将transform functions运用完后,平移后的原点便会返回原先的部位,也便是说,下一次更改transform-origin的部位依然是从起止点算起(也便是以前的原点)。

EXAMPLE3
下列所涉照片深翠绿色一部分均是沒有应用转换特性时元素的原本模样。

CSS Code拷贝內容到剪贴板
  1. div {   
  2.   height100px;   
  3.   width100px;   
  4.   transform: translate(80px,80px) scale(1.5,1.5) rotate(45deg);   
  5. }   

最先在X,Y轴上各挪动80px,随后将元素变大150%,接着沿着Z轴方位顺时针转动45°。

留意:放缩和转动,全是根据元素的管理中心开展运行的,由于元素的默认设置transfrom-origin值为50% 50%。

根据嵌套循环元素能够完成与上面同样的实际效果

XML/HTML Code拷贝內容到剪贴板
  1. <div style="transform: translate(80px, 80px)">  
  2.   <div style="transform: scale(1.5, 1.5)">  
  3.       <div style="transform: rotate(45deg)"></div>  
  4.   </div>  
  5. </div>  

三d转换3D渲染
一般,元素全是按照平面开展3D渲染,而且被3D渲染的元素与它们的包括块的平面1致。平面的transform functions能够更改元素的主要表现,可是它依然在与它的包括块同样的平面里开展3D渲染。

3维的转换会致使转换实体模型拥有1个非0的Z组件(Z轴投影在显示屏的外面)。这样能够导致元素能够在不一样的平面开展3D渲染,而并不是在它的包括块的平面内开展3D渲染。这也将会会危害1个元素和与之有联络的另外一个元素从前到后的3D渲染次序,另外和致使与别的元素产生交叉式。这样的主要表现依靠于这个元素是不是为三d rendering context中的1员,正以下所说

上面的叙述其实不会彻底精确的在WebKit中是完成。或许它会被更改来融入如今的是完成?See,Bug 19637
EXAMPLE4

CSS Code拷贝內容到剪贴板
  1. div {   
  2.   height150px;   
  3.   width150px;   
  4. }   
  5. .container {   
  6.   border1px solid black;   
  7.   background-color#ccc;   
  8. }   
  9. .transformed {   
  10.   transform: rotateY(50deg);   
  11.   background-colorblue;   
  12. }  
XML/HTML Code拷贝內容到剪贴板
  1. <div class="container">  
  2.   <div class="transformed"></div>  
  3. </div>  

这次转换是1个紧紧围绕着竖直的Y轴开展的50度转动。可是为何这次转换为何使的盒子便窄了呢?而并不是变得立体式呢?

perspective和perspective-origin特性能够根据使元素在Z轴变得更高而使元素显得更大,以此来提升观者在室内空间深层上的认知,另外还可以根据一样的方式使之显得越小。放缩占比的占比项公式是d/(d-Z),perspective的值便是从绘图平面到假定的观者双眼的部位。

上图用图型解释了放缩占比是怎样依靠于perspective特性和Z的值。在上面的那张图,Z值是d的1半。初始的圆圈(实线圆圈)出現在Z上(虚线圈),以便是它展现在画面中,圆圈根据以上两个要素按占比变大,最终在画面中展现出来了变大的浅蓝色圆圈。下面的图型,圆圈根据占比开展变小出現在初始部位后边的1/3圆圈,最终在画面中展现出了变小的浅蓝色圆圈。

一般假定观查者双眼的部位在画面的中间。可是,假如想的话,这个部位也是能够挪动的-比如,假如1个网页页面包括了许多绘画那末大伙儿根据设定perspective-origin的值来共享同样的视角。

图型主要表现了向上挪动perspective origin对主要表现实际效果的危害

透視实体模型按以下开展测算:

1.从实际的实体模型刚开始
2.根据 设定的perspective-origin的X,Y的测算值开展挪动
3.根据得到perspective特性的值运用在实体模型上
4.使以前设定的perspective- origin的值失效并开展挪动
EXAMPLE5
这个事例主要表现了透視能够被用来表述立体式的转换从而呈现出更多真正的细节

CSS Code拷贝內容到剪贴板
  1. div {   
  2.   height150px;   
  3.   width150px;   
  4. }   
  5. .container {   
  6.   perspective: 500px;   
  7.   border1px solid black;   
  8.   background-color#ccc;   
  9. }   
  10. .transformed {   
  11.   transform: rotateY(50deg);   
  12.   background-colorblue;   
  13. }   
XML/HTML Code拷贝內容到剪贴板
  1. <div class="container">  
  2.   <div class="transformed"></div>  
  3. </div>  

里边的元素和在前面的事例中拥有同样的转换,可是它的3D渲染被父元素上的perspective特性所危害。透視给予了1个呈现的深层,致使端点有了Z座标(挨近观查者)使其在X,Y轴被变大,而且更进1步的(在负的Z轴上)也会被变小。
1个其实不包括在三d3D渲染左右文中的立体式转换元素拥有适合的transform值开展3D渲染,可是也不容易与别的任何元素产生交叉。在这个EXAMPLE4中的立体式转换能够被考虑到为1种美术绘画实际效果,就像平面中的转换。类似的,转换不容易危害3D渲染指令。举个事例,在transform中设定Z的值使元素开展挪动将会使元素变得更大,可是其实不会致使元素去3D渲染它前面沒有设定Z值的元素

1个包括在三d3D渲染左右文的立体式转换元素在一样的三d3D渲染左右文中能够与别的元素交叉;参加同样三d3D渲染左右文的元素,依据它们的转换結果,将会会相互之间掩藏或交叉。在一样的三d座标室内空间放置,使它们仿佛所有全是弟兄姐妹。1个元素在立体式室内空间中放置的部位决策于从创建三d3D渲染左右文的包括块中累积的转换实体模型所决策。
EXAMPLE6

CSS Code拷贝內容到剪贴板
  1. div {   
  2.   height150px;   
  3.   width150px;   
  4. }   
  5. .container {   
  6.   perspective: 500px;   
  7.   border1px solid black;   
  8.   background#ccc;   
  9. }   
  10. .transformed {   
  11.   transform: rotateY(50deg);   
  12.   background-colorblue;   
  13. }   
  14. .child {   
  15.   transform-origin: top left;   
  16.   transform: rotateX(40deg);   
  17.   background-colorlime;   
  18. }  
JavaScript Code拷贝內容到剪贴板
  1. <div class="container">   
  2.   <div class="transformed">   
  3.     <div class="child"></div>   
  4.   </div>   
  5. </div>  

这个事例主要表现了嵌套循环的三d转换元素在缺乏transform-style: preserve⑶d时是怎样3D渲染的。蓝色的div和以前的事例转换結果是1样的,全是被父元素的perspective特性所危害。绿黄色的元素一样有绕着X轴开展转动的三d转换。但是,绿黄色元素在它的父元素所属平面开展3D渲染由于他并不是三d3D渲染左右文中的1员;父元素是2维的。
依照以下标准,元素可创建并参加在三d3D渲染左右文中:

三d3D渲染左右文根据拥有transform-style: preserved⑶d值的转换元素建立而且它自身其实不是三d3D渲染左右文中的1员。这样的元素一般全是1个包括块。1个元素创建三d3D渲染左右文一样也参加在其中。
1个拥有transform-style: preserved⑶d值的元素,参加在它自身建立的三d3D渲染左右文中,扩张了三d3D渲染左右文,而并不是创建了1个新的三d3D渲染左右文。
1个元素参加三d3D渲染左右文,除非它的包括块创建了三d3D渲染左右文或拓展了三d3D渲染左右文
最终的转换結果一般是在三d3D渲染左右文中3D渲染的元素三d转换实体模型的累积,以下:

从实际的实体模型刚开始
针对每个在三d转换根元素和元素之间的包括块,考虑到下列几点:
1.在元素的包括块上累积perspective matrix(假如能够的话)。包括块其实不1定要变成三d3D渲染左右文中的1员
2.元素的offset-parent是相对它的包括块的,元素运用测算后的挪动值等同于于竖直水平挪动。
3.累加转换实际效果
EXAMPLE7

CSS Code拷贝內容到剪贴板
  1. div {   
  2.   height150px;   
  3.   width150px;   
  4. }   
  5. .container {   
  6.   perspective: 500px;   
  7.   border1px solid black;   
  8.   background#ccc;   
  9. }   
  10. .transformed {   
  11.   transform-style: preserve⑶d;   
  12.   transform: rotateY(50deg);   
  13.   backgroundblue;   
  14. }   
  15. .child {   
  16.   transfom-origin: top left;   
  17.   transform: rotateX(40deg);   
  18.   background-colorlime;   
  19. }  

这个事例和前面的事例是同样的,除加了1个transform-style: preserve⑶d值在蓝色的元素上。蓝色的元素创建的三d3D渲染左右文,绿黄色元素是在其中1员。如今蓝色和绿黄色元素都被器皿中的perspective所危害,而且另外共享了1个同样的立体式室内空间,因此淡绿色的元素在它的父元素上晃动。

元素在一样的三d3D渲染左右文中将会会相互交叉。

在三d3D渲染左右文中不会改变换的元素在Z=0的平面上也是有将会与转换元素交叉。

在三d3D渲染左右文里,在运用完累积的转换后,沒有交叉的元素的3D渲染次序根据在Z轴上的部位。元素在Z轴的部位同样则3D渲染次序由堆叠左右文决策。
EXAMPLE8

CSS Code拷贝內容到剪贴板
  1. div {   
  2.  width150px;   
  3. }   
  4. .container {   
  5.  height145px;   
  6.  background-color: rgba(0,0,0,0.3);   
  7.  border1px solid black;   
  8.  transform-style: preserve⑶d;   
  9.  perspective: 500px;   
  10. }   
  11. .container>div {   
  12.  positionabsolute;   
  13.  left: 0;   
  14. }   
  15. .container> :first-child {   
  16.  transform: rotateY(45deg);   
  17.  background-color: orange;   
  18.  top10px;   
  19.  height135px;   
  20. }   
  21. .container> :last-child {   
  22.  transform: translateZ(40px);   
  23.  background-color: rgba(0,0,255,0.75);   
  24.  top50px;   
  25.  height100px;   
  26. }  
XML/HTML Code拷贝內容到剪贴板
  1. <div class="container">  
  2.   <div></div>  
  3.   <div></div>  
  4. </div>  

这个事例展现了,在三d3D渲染左右文中元素是能够交叉的。器皿元素为自身建立了三d3D渲染左右文而且他有两个子元素。子元素相互之间交叉,另外橘黄色的元素也与器皿交叉。

应用立体式转换,让1个元素的反面朝着观者是彻底有将会的。三d转换元素在双面展现同样的內容,因此背面看起来就像镜子中的正面(就像元素投射在1片镜子上1样)。一般,元素的背面朝着观者都会掩藏。但是,backface-visiblity:hidden特性容许作者使其不能见当元素的背面朝着观者时。假如1个带有backface-visiblity:hidden特性的元素是合理的,那末他的前面和反面便会更替的掩藏,随后,仅有当今面房屋朝向观者时元素才是可见的。

了解backface-visibility特性

CSS Code拷贝內容到剪贴板
  1. .wrap {   
  2.   width200px;   
  3.   height200px;   
  4.   border1px solid black;   
  5.   perspective: 200px;   
  6.   color#fff;   
  7.   text-aligncenter;   
  8.   font-size50px;   
  9. }   
  10. .inner {   
  11.   width50px;   
  12.   height50px;   
  13.   margin20px auto;   
  14.   background: orange;   
  15.   line-height50px;   
  16.   transform: rotateY(180deg);//转动180   
  17. }  
XML/HTML Code拷贝內容到剪贴板
  1. <div class="wrap">  
  2.   <div class="inner">2</div>  
  3. </div>  

图左为转动前,图右为转动后。

能够看出图右就像平常大家照镜子在镜子中的投射1样。这个便是元素的反面。
接下来当大家在元素inner上加backface-visibility:hidden特性则元素便会被掩藏,看起来消退了1样。如图