zoukankan      html  css  js  c++  java
  • Transform-style和Perspective属性

    在《CSS3 Transform——transform-origin》一文中主要介绍了CSS3 Transform属性中的transform-origin属性的使用,其实在transform属性中,transform-origin属性仅是其中之一,要彻底理解transform属性,这是不够的,必须的理解其他属性的应用。今天将和大家一起探讨transformtransform-styleperspective相关属性的使用。

    transform-style属性

    transform-style属性是3D空间一个重要属性,指定嵌套元素如何在3D空间中呈现。他主要有两个属性值:flatpreserve-3d

    transform-style属性的使用语法非常简单:

    transform-style: flat | preserve-3d
    

    其中flat值为默认值,表示所有子元素在2D平面呈现。preserve-3d表示所有子元素在3D空间中呈现。

    也就是说,如果对一个元素设置了transform-style的值为flat,则该元素的所有子元素都将被平展到该元素的2D平面中进行呈现。沿着X轴或Y轴方向旋转该元素将导致位于正或负Z轴位置的子元素显示在该元素的平面上,而不是它的前面或者后面。如果对一个元素设置了transform-style的值为preserve-3d,它表示不执行平展操作,他的所有子元素位于3D空间中。

    transform-style属性需要设置在父元素中,并且高于任何嵌套的变形元素。最后,我们运用一个翻转的例子,来加深一下对transform-style属性的印象:

     

    HTML模板

    <div class="wrap">
        <div class="spin">
            <div class="rotate">
                <img src="images/cardKingClub.png" alt="" width="142" height="200" />
            </div>
        </div>
    </div>
    <div class="wrap">
        <div class="spin">
            <div class="rotate three-d">
                <img src="images/cardKingClub.png" alt="" width="142" height="200" />
            </div>
        </div>
    </div>
    

    CSS

    .wrap {
         500px;
        height: 300px;
        margin: 30px auto;
        position: relative;
        background: url(images/bg-grid.jpg) no-repeat center center;
        background-size: 100% 100%;
    }
    /*设置动画*/
    @keyframes spin{
        0%{
            transform:rotateY(0deg)
        }
        100%{
            transform:rotateY(360deg)
        }
    }
    .spin {
         142px;
        height: 200px;
        position: absolute;
        top: 50%;
        left: 50%;
        margin-left: -72px;
        margin-top: -101px;
        border: 1px dashed orange;
        cursor: pointer;
        transform-style: preserve-3d;
    }
    /*调用动画*/
    .spin:hover{
        animation:spin 5s linear infinite;
    }
    .rotate {
        background: url(images/cardKingClub.png) no-repeat center;
        background-size: 100% 100%;
        border: 5px solid hsla(50,50%,50%,.9);
        transform: perspective(200px) rotateY(45deg);
    }
    .rotate img{
        border: 1px solid green;
        transform: rotateX(15deg) translateZ(10px);
        transform-origin: 0 0 40px;
    }
    /*改变transform-style的默认值*/
    .three-d {
        transform-style: preserve-3d;
    }
    

    特别声明:为了节省篇幅,代码中CSS3属性代码省去了各浏览器的私有前缀,在实际操作中,需要将各浏览器前缀加上,才会有效果。

    其效果如下所示:

    CSS3 Transform——transform-origin

    正如您所看到的,当元素设置.rotate设置了flat值时,其子元素img不会根据translateZ()值摊开,而在同一平面旋转,如上图上部分所示;当元素.rotate设置了preserve-3d值时,其子元素img会根据translateZ()值摊开,不再会堆叠在一起,如上图下部分所示。

    有一点需要特别提醒大家,如果你的元素设置了transform-style值为preserve-3d,就不能为了防止子元素溢出容器而设置overflow值为hidden,如果设置了overflow:hidden同样可以迫死子元素出现在同一平面(和元素设置了transform-styleflat一样的效果),如下图所示:

    CSS3 Transform——transform-origin

    perspective属性

    perspective属性对于3D变形来说至关重要。该属性会设置查看者的位置,并将可视内容映射到一个视锥上,继而投到一个2D视平面上。如果不指定透视,则Z轴空间中的所有点将平铺到同一个2D视平面中,并且变换结果中将不存在景深概念。

    上面的描述可能让人难以理解一些,其实对于perspective属性,我们可以简单的理解为视距,用来设置用户和元素3D空间Z平面之间的距离。而其效应由他的值来决定,值越小,用户与3D空间Z平面距离越近,视觉效果更令人印象深刻;反之,值越大,用户与3D空间Z平面距离越远,视觉效果就很小。

    在3D变形中,对于某些变形,例如下面的示例演示的沿Z轴的变形,perspective属性对于查看变形的效果来说必不可少。

    我们先来看一个简单的实例,制作一个扑克牌3D旋转效果,并且一个在扑克牌的父元素添加了视距perspective,而另一个却没有设置:

    HTML

    <div>
        <img src="images/cardKingClub.png" alt="" width="142" height="200" />
        <img src="images/cardKingClub.png" alt="" width="142" height="200" />
    </div>
    <div>
        <img src="images/cardKingClub.png" alt="" width="142" height="200" />
        <img src="images/cardKingClub.png" alt="" width="142" height="200" />
    </div>
    

    CSS

    div {
         500px;
        height: 300px;
        margin: 30px auto;
        position: relative;
        background: url(images/bg-grid.jpg) no-repeat center center;
        background-size: 100% 100%;
    }
    div img {
        position: absolute;
        top: 50%;
        left: 50%;
        margin-left: -71px;
        margin-top: -100px; 
        transform-origin: bottom;
    }
    div img:nth-child(1){
        opacity: .5;
        z-index: 1;
    }
    div img:nth-child(2){
        z-index: 2;
        transform: rotateX(45deg);
    }
    div:nth-of-type(2){
        perspective: 500px;
    }
    

    其效果如下:

    CSS3 Transform——transform-origin

    上图的效果完全说明了一切。父节点没有设置perspective的情况下,梅花King的3D旋转效果不明显,而在父节点设置perspective后,梅花King才像个3D旋转。

    上例简单的演示了perspective的使用方法,我们回过头来,看看perspective的使用语法:

    perspective:none | <length>

    perspective属性包括两个属性:none和具有单位的长度值。其中perspective属性的默认值为none,表示无限的角度来看3D物体,但看上去是平的。另一个值<length>接受一个长度单位大于0的值。而且其单位不能为百分比值。<length>值越大,角度出现的越远,从而创建一个相当低的强度和非常小的3D空间变化。反之,此值越小,角度出现的越近,从而创建一个高强度的角度和一个大型3D变化。

    比如你站在10英尺和1000英尺的地方看一个10英尺的立方体。在10英尺的地方,你距离立方体是一样的尺寸。因此视角转变远远大于站在1000英尺处的,立体尺寸是你距离立方体距离的百分之一。同样的思维适用于perspective<length>值。我们一起来看一个实例,来加强这方面的理解:

    HTML

    <div class="wrapper w2">
        <div class="cube">
            <div class="side  front">1</div>
            <div class="side   back">6</div>
            <div class="side  right">4</div>
            <div class="side   left">3</div>
            <div class="side    top">5</div>
            <div class="side bottom">2</div>
        </div>
    </div>
    <div class="wrapper w1">
        <div class="cube">
            <div class="side  front">1</div>
            <div class="side   back">6</div>
            <div class="side  right">4</div>
            <div class="side   left">3</div>
            <div class="side    top">5</div>
            <div class="side bottom">2</div>
        </div>
    </div>
    

    CSS

    .wrapper {
         50%;
        float: left;
    }
    .cube {
        font-size: 4em;
         2em;
        margin: 1.5em auto;
        transform-style: preserve-3d;
        transform: rotateX(-40deg) rotateY(32deg);
    }
    .side {
        position: absolute;
         2em;
        height: 2em;
        background: rgba(255, 99, 71, 0.6);
        border: 1px solid rgba(0, 0, 0, 0.5);
        color: white;
        text-align: center;
        line-height: 2em;
    }
    .front {
        transform: translateZ(1em);
    }
    .top {
        transform: rotateX(90deg) translateZ(1em);
    }
    .right {
        transform: rotateY(90deg) translateZ(1em);
    }
    .left {
        transform: rotateY(-90deg) translateZ(1em);
    }
    .bottom {
        transform: rotateX(-90deg) translateZ(1em);
    }
    
    .back {
        transform: rotateY(-180deg) translateZ(1em);
    }
    .w1 {
        perspective: 100px;
    }
    .w2{
        perspective: 1000px;
    }
    

    效果如下图所示:

    CSS3 Transform——transform-origin

    依据上面的介绍,我们可对perspective取值做一个简单的结论:

    • perspective取值为none或不设置,就没有真3D空间。
    • perspective取值越小,3D效果就越明显,也就是你的眼睛越靠近真3D。
    • perspective的值无穷大,或值为0时与取值为none效果一样。

    为了更好的理解perspective属性,我们很有必要把他和translateZ的关系结合起来。其实也可以把perspective的值简单的理解为人的眼睛到显示器的距离,而translate就是3D物体距离源点的距离,下面引用W3C的一张图来解说perspectivetranslateZ的关系。

    CSS3 Transform——transform-origin

    上图显示了perspective属性和translateZ的位置比例。要顶部的图,Z是半个d,为了使用原始圆(轮廓)看起来出现在Z轴上(虚线圆),画布上的实体圆将扩大两部,如浅蓝色的圆。在底部图中显示,圆按比例缩小,致使虚线圆出现在画布后面,并且z的大小是距原始位置三分之一。

    在3D变形中,除了perspective属性可以激活一个3D空间之外,在3D变形的函数中的perspective()也可以激活3D空间。他们不同的地方是:perspective用在舞台元素上(变形元素们的共同父元素);perspective()就是用在当前变形元素上,并且可以与其他的transform函数一起使用。例如,我们可以把:

    .stage {
        perspective: 600px
    }

    写成:

    .stage .box {
        transform: perspective(600px);
    }

    来看一个简单示例:

    HTML

    <div class="stage">
        <div class="container">
            <img src="images/cardKingClub.png" alt="" width="142" height="200" />
        </div>
    </div>
    <div class="stage">
        <div class="container">
            <img src="images/cardKingClub.png" alt="" width="142" height="200" />
        </div>
    </div>
    

    CSS

    .stage {
         500px;
        height: 300px;
        margin: 30px auto;
        position: relative;
        background: url(images/bg-grid.jpg) no-repeat center center;
        background-size: 100% 100%;
    }
    .container {
        position: absolute;
        top: 50%;
        left: 50%;
         142px;
        height: 200px;
        border: 1px dotted orange;
        margin-left: -71px;
        margin-top: -100px; 
    }
    .container img{
        transform: rotateY(45deg);
    }
    .stage:nth-child(1) .container{
        perspective: 600px;
    }
    .stage:nth-child(2) img {
        transform:perspective(600px) rotateY(45deg);
    }
    

    效果如下所示:

    CSS3 Transform——transform-origin

    上图效果可以看出,虽然书写的形式,属性名称不一致,但是效果却一样。

    虽然perspective属性和perspective()函数所起的功能是一样的,但其取值以及以运用的对像有所不同:

    • perspective属性可以取值为none或长度值;而perspective()函数取值只能大于0,如果取值为0或比0小的值,将无法激活3D空间;
    • perspective属性用于变形对像父元素;而perspective()函数用于变形对像自身,并和transform其他函数一起使用。

    perspective-origin属性

    perspective-origin属性是3D变形中另一个重要属性,主要用来决定perspective属性的源点角度。它实际上设置了X轴和Y轴位置,在该位置观看者好像在观看该元素的子元素。

    perspective-origin属性的使用语法也很简单:

    perspective-origin:[<percentage> | <length> | left | center | right | top | bottom] | [[<percentage> | <length> | left | center | right] && [<percentage> | <length> | top | center | bottom]]
    

    该属性的默认值为“50% 50%”(也就是center),其也可以设置为一个值,也可以设置为两个长度值:

    • 第一个长度值指定相对于元素的包含框的X轴上的位置。它可以是长度值(以受支持的长度单位表示)、百分比或以下三个关键词之一:left(表示在包含框的X轴方向长度的0%),center(表示中间点),或right(表示长度的100%)。
    • 第二个长度值指定相对于元素的包含框的Y轴上的位置。它可以是长度值、百分比或以下三个关键词之一:top(表示在包含框的Y轴方向长度的0%),center(表示中间点),或bottom(表示长度的100%)。

    注意,为了指转换子元素变形的深度,perspective-origin属性必须定义父元素上。通常perspective-origin属性本身不做任何事情,它必须被定义在设置了perspective属性的元素上。换句话说,perspective-origin属性需要与perspective属性结合起来使用,以便将视点移至元素的中心以外位置,如下图所示:

    CSS3 Transform——transform-origin

    往往我们看一样东西不可能一直都在中心位置看,想换个角度,换个位置一看究竟,这个时候就离不开perspective-origin这个属性,下面来自于W3C官网的图可以简单阐述这一观点:

    CSS3 Transform——transform-origin

    接下来的示例演示了修改perspective-origin的属性值对立方体的影响:

     

    特别声明: 以上示例来自于http://css-tricks.com/almanac/properties/p/perspective-origin/

    backface-visibility属性

    backface-visibility属性决定元素旋转背面是否可见。对于未旋转的元素,该元素的正面面向观看者。当其Y轴旋转约180度时会导致元素的背面面对观众。

    backface-visibility属性使用语法很简单:

    backface-visibility: visible | hidden
    

    该属性被设置为以下两个关键词之一:

    • visible:为backface-visibility的默认值,表示反面可见
    • hidden:表示反面不可见

    一个元素的可见性与“backface-visibility:hidden”决定如下:

    • 元素在3D环境下渲染上下文,将根据3D变形矩阵来计算,反之元素不在3D环境下渲染上下文,将根据2D变形矩阵来计算。
    • 如果组件的矩阵在第3行、3列是负值,那么元素反面是隐藏,反之是可见的。

    简单点来说,backface-visibility属性可用于隐藏内容的背面。默认情况下,背面可见,这意味着即使在翻转后,旋转的内容仍然可见。但当backface-visibility设置为hidden时,旋转后内容将隐藏,因为旋转后正面将不再可见。该功能可帮助您模拟多面的对象,例如下例中使用的纸牌。通过将backface-visibility设置为hidden,您可以轻松确保只有正面可见。

    HTML

    <div class="stage">
        <div class="container">
            <div class="card front"></div>
            <div class="card back"></div>
        </div>
    </div>
    <div class="stage">
        <div class="container">
            <div class="card front"></div>
            <div class="card back"></div>
        </div>
    </div>
    <div class="stage">
        <div class="container">
            <div class="card front"></div>
            <div class="card back"></div>
        </div>
    </div>
    <div class="stage">
        <div class="container">
            <div class="card front"></div>
            <div class="card back"></div>
        </div>
    </div>
    <div class="stage">
        <div class="container">
            <div class="card front"></div>
            <div class="card back"></div>
        </div>
    </div>
    <div class="stage">
        <div class="container">
            <div class="card front"></div>
            <div class="card back"></div>
        </div>
    </div>
    <div class="stage">
        <div class="container">
            <div class="card front"></div>
            <div class="card back"></div>
        </div>
    </div>
    

    CSS

    *{
        margin: 0;
        padding: 0;
    }
    body {
        background-color: hsla(173,80%,21%,.9); 
    }
    .stage{
        float: left;
        border: 1px dotted orange;
        position: relative;
        margin: 20px;
        border-radius: 8px;
        perspective: 1000;
    }
    .container {
         102px;
        height: 142px;
        position: relative;
        transition: 0.5s;
        transform-style: preserve-3d;
    }
    .card {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        backface-visibility: hidden;
    }
    .front {
        background: url(images/cardjfront.png) no-repeat center/100% 100%;
        z-index: 2;
    }
    .back {
        background: url(images/cardjback.png) no-repeat center/100% 100%;
        transform: rotateY(180deg);
    }
    .stage:nth-child(1) .container{
        transform: rotateY(0deg);
    }
    .stage:nth-child(2) .container{
        transform: rotateY(30deg);
    }
    .stage:nth-child(3) .container{
        transform: rotateY(60deg);
    }
    .stage:nth-child(4) .container{
        transform: rotateY(90deg);
    }
    .stage:nth-child(5) .container{
        transform: rotateY(120deg);
    }
    .stage:nth-child(6) .container{
        transform: rotateY(150deg);
    }
    .stage:nth-child(7) .container{
        transform: rotateY(180deg);
    }
    

    其效果如下:

    CSS3 Transform——transform-origin

    在本例中,未旋转时,您将看到扑克牌正面,也就是红桃J,这是由于其定位于顶部。随着向扑克牌应用的旋转超过90度,第二个divbackface-visibility:hidden属性导致其不可见,因此将显示扑克牌正面。接来来我个可以将第二个divbackface-visibility设置为visible

    .card {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        backface-visibility: visible;
    }

    效果如下:

    CSS3 Transform——transform-origin

    上面的示例,从视觉上不太好理解,我们通过两个3D立方体来做一个实例,让你能从视觉上更能直能的区分backface-visibility取值为hiddenvisible的区别:

    HTML

    <div class="container">
        <h1>backface-visibility:visible</h1>
        <div class="cube backface-visibility-visible">
            <div class="side front">1</div>
            <div class="side back">2</div>
            <div class="side right">3</div>
            <div class="side left">4</div>
            <div class="side top">5</div>
            <div class="side bottom">6</div>
        </div>
    </div>  
    
    <div class="container">
        <h1>backface-visibility:hidden</h1>
        <div class="cube backface-visibility-hidden">
            <div class="side front">1</div>
            <div class="side back">2</div>
            <div class="side right">3</div>
            <div class="side left">4</div>
            <div class="side top">5</div>
            <div class="side bottom">6</div>
        </div>
    </div>
    

    CSS

    .container {
       500px;
      height: 300px;
      float: left;
      position: relative;
      margin: 30px;
      border: 1px solid #CCC;
      perspective: 1200px;
    }
    .cube {
       100%;
      height: 100%;
      position: absolute;
      animation: spinCube 8s infinite ease-in-out;
      transform-style: preserve-3d;
      transform: translateZ( -100px );
    }
    @keyframes spinCube {
      0% { 
        transform: translateZ( -100px ) rotateX(   0deg ) rotateY(   0deg ); 
        }
      100% {
        transform: translateZ( -100px ) rotateX( 360deg ) rotateY( 360deg ); 
      }
    }
    
    .side {
     display: block;
     position: absolute;
      196px;
     height: 196px;
     border: 2px solid black;
     line-height: 196px;
     font-size: 120px;
     font-weight: bold;
     color: white;
     text-align: center;
    }
    
    .cube.backface-visibility-visible .side {
      backface-visibility: visible;
    }
    .cube.backface-visibility-hidden .side {
      backface-visibility: hidden;
    }
    
    .cube .front  { background: hsla(   0, 100%, 50%, 0.7 ); }
    .cube .back   { background: hsla(  60, 100%, 50%, 0.7 ); }
    .cube .right  { background: hsla( 120, 100%, 50%, 0.7 ); }
    .cube .left   { background: hsla( 180, 100%, 50%, 0.7 ); }
    .cube .top    { background: hsla( 240, 100%, 50%, 0.7 ); }
    .cube .bottom { background: hsla( 300, 100%, 50%, 0.7 ); }
    
    .cube .front  {
      transform: translateZ( 100px );
    }
    .cube .back {
      transform: rotateX( -180deg ) translateZ( 100px );
    }
    .cube .right {
      transform: rotateY(   90deg ) translateZ( 100px );
    }
    .cube .left {
      transform: rotateY(  -90deg ) translateZ( 100px );
    }
    .cube .top {
      transform: rotateX(   90deg ) translateZ( 100px );
    }
    .cube .bottom {
      transform: rotateX(  -90deg ) translateZ( 100px );
    }   
    

    效果如下:

    CSS3 Transform——transform-origin

    上例或许让您能更清楚的了解backface-visibilityvisiblehidden的区别,上图中左边立方体每个页我们都能看得到,而右边的立方体我们只能看到视力范围的面。

  • 相关阅读:
    你对线程优先级的理解是什么?
    Java 中 notify 和 notifyAll 有什么区别?
    线程之间是如何通信的?
    多线程同步有哪几种方法?
    CyclicBarrier 和 CountDownLatch 的区别 ?
    int 和 Integer 有什么区别?
    Thread 类中的 yield 方法有什么作用?
    用最有效率的方法计算 2 乘以 8?
    volatile 关键字的作用 ?
    数组有没有 length()方法?String 有没有 length()方法?
  • 原文地址:https://www.cnblogs.com/screw/p/5156778.html
Copyright © 2011-2022 走看看