CSS3 變換

概覽

CSS3 變換也叫 2D/3D轉換,主要包括如下幾種:旋轉(rotate) 、扭曲 (skew) 、縮放(scale) 和 移動(translate) 以及 矩陣變形(matrix) 。transform 屬性常和 transition 一塊兒使用來構造絢麗的過渡動畫效果。css

本文涉及的內容較多,不太好理解,須要耐心認真閱讀。html

小試牛刀

<!DOCTYPE html>
<html>
<head>
<style> 
    body {
        margin:60px;
    }

    div.polaroid {
        width:294px;
        padding:10px 10px 20px 10px;
        border:1px solid #BFBFBF;
        background-color:white;
        box-shadow:2px 2px 3px #aaaaaa;
        
        transition: transform 1s;
        -ms-transition: -ms-transform 1s;
        -moz-transition: -moz-transform 1s;
        -webkit-transition: -webkit-transform 1s;
        -o-transition: -o-transform 1s;
    }
    /* 鼠標滑過圖片歸正 */
    div.polaroid:hover {
        -ms-transform:rotate(0); /* IE 9 */
        -moz-transform:rotate(0); /* Firefox */
        -webkit-transform:rotate(0); /* Safari and Chrome */
        -o-transform:rotate(0); /* Opera */
        transform:rotate(0);
    }

    div.rotate_left {
        float:left;
        -ms-transform:rotate(7deg); /* IE 9 */
        -moz-transform:rotate(7deg); /* Firefox */
        -webkit-transform:rotate(7deg); /* Safari and Chrome */
        -o-transform:rotate(7deg); /* Opera */
        transform:rotate(7deg);
    }

    div.rotate_right {
        float:left;
        -ms-transform:rotate(-8deg); /* IE 9 */
        -moz-transform:rotate(-8deg); /* Firefox */
        -webkit-transform:rotate(-8deg); /* Safari and Chrome */
        -o-transform:rotate(-8deg); /* Opera */
        transform:rotate(-8deg);
    }
</style>
</head>
<body>

<div class="polaroid rotate_left">
    <img src="http://i13.buimg.com/d17ea072b13a1a71.jpg" width="284" height="213" />
    <p class="caption">上海鮮花港的鬱金香,花名:Ballade Dream。</p>
</div>

<div class="polaroid rotate_right">
    <img src="http://i13.buimg.com/755395ac04d54cc6.jpg" width="284" height="213" />
    <p class="caption">2010年上海世博會,中國館。</p>
</div>

</body>
</html>

結合 transitiontransform 實現的絢麗動畫牆效果。css3

2D 變換

所謂的 2D 變換,就是指在二維平面上的變換,中學學的平面幾何。web

2D 變換就是圍繞 x 軸,y 軸及 原點 組成的平面所作的一些變換。app

移動 translate

移動分三種狀況,對應transform的三種值。ide

translate(x, y)

水平方向和垂直方向同時移動(也就是X軸和Y軸同時移動),當值爲負數時,反方向移動物體。wordpress

transform: translate(<x-value>[, <y-value>]) ;

例如:transform: translate(100px, 20px);函數

translateX(x)

水平方向上移動。測試

transform: translateX(100px);

translateY(y)

垂直方向上移動。動畫

transform: translateY(20px);

旋轉 rotate

經過指定的角度對元素進行旋轉。值爲正順時針旋轉,值爲負逆時針旋轉。

transform: rotate(30deg);

縮放 scale

縮放 scale和移動 translate極其類似,他也具備三種狀況,只是參數對應的是縮放的倍數,容許小數、負數。

scale(x, y)

水平和垂直方向上同時進行縮放。

transform: scale(<x-number>[, <y-number>]);

例如: transform: scale(2, 1.5); 寬度是原來的2倍,高度是原來的1.5倍。

接下來咱們來體驗一下負值的效果。

scaleX(x)

水平方向縮放。

transform: scaleX(2);

scaleY(y)

垂直方向縮放。

transform: scaleY(2);

扭曲 skew

扭曲 skewtranslatescale同樣一樣具備三種狀況,只是參數值對應的是扭曲的度數。

skew(x, y)

使元素在水平和垂直方向同時扭曲,值爲扭曲的度數。

transform: skew(<x-angle> [, <y-angle>]);

例如:transform:skew(30deg, 10deg);

注意上圖中的度數偏轉,x軸方向的扭曲是拉y軸,y軸方向的扭曲是拉x軸,角度的方向也很古怪,注意記憶。

skewX(x)

在水平方向進行扭曲變行。

transform: skewX(30deg);

skewY(y)

在垂直方向進行扭曲變形。

transform:skewY(10deg);

3D 變換

3D 變換就是在三維環境下的變換,中學時的立體幾何。

3D 變換沒有扭曲操做,有移動,旋轉,縮放。

介紹 3D 變換 以前咱們需先介紹跟3D密切相關的4個屬性。

透視 perspective

perspective 屬性定義 3D 元素距視圖的距離,你能夠形象的理解爲物體距你的距離,以像素計。該屬性的存在與否決定了你看到的是2D仍是3D,沒有透視,不成3D。

透視的使用及是否使用透視的區別會在下面的具體變換中介紹。

透視基點 perspective-origin

透視基點也直接影響透視的結果,形象點說就是透視基點就至關於你站在一個位置看你面前的物體,你能夠蹲着看,能夠站着看,能夠左側斜着身子看,能夠右側斜着身子看,你的眼睛看的位置不一樣,可能看到物體的形狀就不一樣。

透視點有默認值 perspective-origin: 50% 50%;, 當爲元素定義 perspective-origin 屬性時,其子元素會得到相應效果,而不是元素自己。

perspective-origin: x-axis y-axis;

x-axis 可選值:

  • left

  • center

  • right

  • length

  • %

y-axis 可選值:

  • top

  • center

  • bottom

  • length

  • %

理解perspective-origin 這樣描述的:默認就是所看舞臺或元素的中心。有時候,咱們對中心的位置是不感興趣的,但願視線放在其餘一些地方。

呈現樣式 transform-style

transform-style 屬性是3D空間一個重要屬性,指定嵌套元素如何在3D空間中呈現。他主要有兩個屬性值:flatpreserve-3d

transform-style: flat | preserve-3d;

其中flat 值爲默認值,表示全部子元素在2D平面呈現。preserve-3d 表示全部子元素在3D空間中呈現。

也就是說,若是對一個元素設置了transform-style 的值爲flat,則該元素的全部子元素都將被平展到該元素的2D平面中進行呈現而不是它的前面或者後面。若是對一個元素設置了transform-style 的值爲preserve-3d ,它表示不執行平展操做,他的全部子元素位於3D空間中。

transform-style 屬性須要設置在父元素中。

具體的使用看下面的具體變換。

背面可見 backface-visibility

在現實世界中,你在一張白紙上寫下一些字,通常狀況下從白紙後面是看不到寫的啥的。而在CSS3的3D世界裏,默認是能夠從白紙的後面看到前面( visible )的內容的。

backface-visibility: visible | hidden;

下面旋轉的時候有例子。

移動 translate

3D 移動有 translate3d(x, y, z)translateZ(z) 兩個變換函數。固然 2D 移動的那三個也能夠應用到 3D 移動。

translate3d(x, y, z)

分別沿x, y, z 三個軸同時移動。

x, y軸的移動比較好理解,translate3d(x, y, 0) 等價於 translate(x, y), z 軸的移動你能夠理解爲:在你眼前的一個物體向你走來和遠去,離你越近(z值越大)你感受它越大,離你越遠(z值越小)你感受它越小。不過,變大變小是有前提的,就是咱們前面說到的 perspective 屬性須要指定合適的值。

對好比下實例:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style type="text/css">
    .s {
        width: 300px;
        height: 300px;
        float: left;
        margin: 15px;
        position: relative;
        background: url(http://i13.buimg.com/42a31a7ad86db39b.jpg) repeat center center;
        
        -webkit-perspective: 1200px;
        -moz-perspective: 1200px;
        -ms-perspective: 1200px;
        -o-perspective: 1200px;
        perspective: 1200px;
    }
    .s3 {
        -webkit-perspective: none;
        -moz-perspective: none;
        -ms-perspective: none;
        -o-perspective: none;
        perspective: none;
    }
    .container {
        position: absolute;
        top: 50%;
        left: 50%;
        
        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
        -ms-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        transform-style: preserve-3d;
    }
    .container img {
        position: absolute;
        margin-left: -35px;
        margin-top: -50px; 
    }
    .container img:nth-child(1){
        z-index: 1;
        opacity: .6;
    }
    .s1 img:nth-child(2){
        z-index: 2;    
        -webkit-transform: translate3d(30px,30px,200px);
        -moz-transform: translate3d(30px,30px,200px);
        -ms-transform: translate3d(30px,30px,200px);
        -o-transform: translate3d(30px,30px,200px);
        transform: translate3d(30px,30px,200px);
    }
    .s2 img:nth-child(2){
        z-index: 2;    
        -webkit-transform: translate3d(30px,30px,-200px);
        -moz-transform: translate3d(30px,30px,-200px);
        -ms-transform: translate3d(30px,30px,-200px);
        -o-transform: translate3d(30px,30px,-200px);
        transform: translate3d(30px,30px,-200px);
    }
    .s3 img:nth-child(2){
        z-index: 2;    
        -webkit-transform: translate3d(30px,30px,200px);
        -moz-transform: translate3d(30px,30px,200px);
        -ms-transform: translate3d(30px,30px,200px);
        -o-transform: translate3d(30px,30px,200px);
        transform: translate3d(30px,30px,200px);
    }
    .c1 {
        -webkit-transform-style: flat;
        -moz-transform-style: flat;
        -ms-transform-style: flat;
        -o-transform-style: flat;
        transform-style: flat;
    }
    .s4 img:nth-child(2){
        z-index: 2;    
        -webkit-transform: translate3d(30px,30px,-200px);
        -moz-transform: translate3d(30px,30px,-200px);
        -ms-transform: translate3d(30px,30px,-200px);
        -o-transform: translate3d(30px,30px,-200px);
        transform: translate3d(30px,30px,-200px);
    }
  </style>
</head>
<body>

<div class="s s1">
    <div class="container">
        <img src="http://i13.buimg.com/ac99ad6b3a13d255.png" alt="" width="70" height="100" />
        <img src="http://i13.buimg.com/ac99ad6b3a13d255.png" alt="" width="70" height="100" />
    </div>
</div>
  
<div class="s s2">
    <div class="container">
        <img src="http://i13.buimg.com/ac99ad6b3a13d255.png" alt="" width="70" height="100" />
        <img src="http://i13.buimg.com/ac99ad6b3a13d255.png" alt="" width="70" height="100" />
    </div>
</div>
<div class="s s3">
    <div class="container">
        <img src="http://i13.buimg.com/ac99ad6b3a13d255.png" alt="" width="70" height="100" />
        <img src="http://i13.buimg.com/ac99ad6b3a13d255.png" alt="" width="70" height="100" />
    </div>
</div>
<div class="s s4">
    <div class="container c1">
        <img src="http://i13.buimg.com/ac99ad6b3a13d255.png" alt="" width="70" height="100" />
        <img src="http://i13.buimg.com/ac99ad6b3a13d255.png" alt="" width="70" height="100" />
    </div>
</div>

</body>
</html>

這個例子包含很多內容,請認真品讀。

例子裏有四個場景,s3 沒有加透視( perspective: none; ),往z 軸移動了,圖片沒有任何大小變化,s4 的呈現樣式爲 transform-style: flat; ,圖片堆疊在一個平面內。s1 和 s2 既加了透視又設置樣式爲3D,因此s1 向視點靠近,圖片變大,s2向視點遠離,圖片變小,同時呈現出遮隱效果。

通過這個例子相信你能大概明白 perspectivetransform-style 的做用了。

translateZ(z)

沿z軸方向移動。

若是你理解了上面的例子,這個天然就明白了。

藉此屬性,再來講說 perspective. translateZ 的功能就是讓元素在本身的眼前或近或遠,元素或大或小。不過須要注意的是:當translateZ值很是接近perspective,但不超過的時候,該元素的大小就會撐滿整個屏幕(若是父輩元素沒有相似overflow:hidden的限制的話)。由於這個時候,子元素正好移到了你的眼睛前面,所謂「一葉蔽目,不見泰山」,就是這麼回事。當translateZ值再變大的時候,就看不見了——咱們是看不見眼睛後面的東西的!

下圖的效果是從 transform: translateZ(-150px); -> transform: translateZ(200px); 的效果。視距爲150px

旋轉 rotate

2D 旋轉比較簡單,只有一個函數,圍繞一點旋轉多少度便可,而3D 旋轉要複雜的多,畢竟在三維空間了。

rotateX(angle)

x爲旋轉軸旋轉指定的度數。

基本相似下圖的旋轉。

transform: translate(30px) rotateX(30deg);

rotateY(angle)

y爲旋轉軸旋轉指定的度數。

基本相似下圖的旋轉。

transform: translate(0, 30px) rotateY(45deg);

rotateZ(angle)

z爲旋轉軸旋轉指定的度數。從效果上來看,其實它和2D 變換的 rotate(angle) 徹底一致。

transform: rotateZ(45deg);
transform: rotate(45deg);

rotate3d(x, y, z, angle)

除了上面的三個外,還有一個 rotate3d.

咱們知道 rotateX 是以x軸爲旋轉軸, rotateY是以y軸爲旋轉軸, rotateZ 是以z軸爲旋轉軸,若是我不想以這三個軸爲旋轉軸呢?這時咱們的 rotate3d 就派上用場了。

中學咱們學過向量(空間向量),[x, y, z] 三個向量能夠肯定一個空間向量,向量是有方向和大小的,三個值的範圍均是 [-1 1], 例如:x=1 表示x軸正方向,x=-1 表示x軸反方向。

  • rotateX(a)函數功能等同於 rotate3d(1,0,0,a)

  • rotateY(a)函數功能等同於 rotate3d(0,1,0,a)

  • rotateZ(a)函數功能等同於 rotate3d(0,0,1,a)

下面的測試能夠看出正負值的區別。

再看一下 rotate3d(1, 1, 1, 45deg)rotate3d(-1, -1, -1, 45deg) 的。

你只要有必定的空間想象能力,能肯定旋轉軸位置,就能差很少想通它的變換,實在不行,拿一張撲克用手轉轉。

注: 本屬性的效果中我沒有添加transform-style: preserve-3d; 你實踐的時候記得添上,並再次體會 flatpreserve-3d 的區別。

學完了旋轉,咱們繼續來探討上面提到的幾個相關屬性。

backface-visibility

此屬性用來設置元素是否透明,默認是透明的。下面舉例對比。

backface-visibility: visible;
transform: translate3d(30px,30px,200px) rotateY(0deg);/*從0不斷增長*/

backface-visibility: hidden;
transform: translate3d(30px,30px,200px) rotateY(0deg);/*從0不斷增長*/

perspective

perspective屬性有兩種書寫形式,一種用在舞臺元素上(動畫元素們的共同父輩元素);第二種就是用在當前動畫元素上,與transform的其餘屬性值寫在一塊兒。

.stage {
    perspective: 300px;
}
.stage .box {
    transform: perspective(300px) rotateY(45deg);
}

關於二者的區別,能夠用下面的示例來區分。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style type="text/css">
    .stage {
        width: 900px;
        height: 100px;
        margin-left: auto;
        margin-right: auto;
        padding: 100px 50px;
        background-color: #f0f0f0;
        position: relative;
        transform-style: preserve-3d;
    }
    .s1 {
        perspective: 300px;
    }
    .box {
        width:100px;
        height:100px;
        float: left;
        padding:10px;
        box-sizing: border-box;
    }
    .s2 .box {
        transform: perspective(300px) rotateY(45deg);
    }
    .s1 .box {
        transform: rotateY(45deg);
    }
    .b1{background-color: rgba(51, 204, 117, 0.74902);}
    .b2{background-color: rgba(204, 81, 51, 0.74902);}
    .b3{background-color: rgba(51, 81, 204, 0.74902);}
    .b4{background-color: rgba(81, 51, 117, 0.74902);}
    .b5{background-color: rgba(51, 81, 117, 0.74902);}
    .b6{background-color: rgba(117, 204, 81, 0.74902);}
    .b7{background-color: rgba(51, 108, 81, 0.74902);}
    .b8{background-color: rgba(204, 51, 117, 0.74902);}
    .b9{background-color: rgba(81, 117, 51, 0.74902);}
    
  </style>
</head>
<body>

<div class="stage s1">
    <div class="box b1"></div>
    <div class="box b2"></div>
    <div class="box b3"></div>
    <div class="box b4"></div>
    <div class="box b5"></div>
    <div class="box b6"></div>
    <div class="box b7"></div>
    <div class="box b8"></div>
    <div class="box b9"></div>
</div>
<hr>
<div class="stage s2">
    <div class="box b1"></div>
    <div class="box b2"></div>
    <div class="box b3"></div>
    <div class="box b4"></div>
    <div class="box b5"></div>
    <div class="box b6"></div>
    <div class="box b7"></div>
    <div class="box b8"></div>
    <div class="box b9"></div>
</div>


</body>
</html>

上面是設置在舞臺元素上,下面是設置在每一個元素上。圖中的效果其實不難理解。上面舞臺整個做爲透視元素,所以,顯然,咱們看到的每一個子元素的形體都是不同的;而下面,每一個元素都有一個本身的視點,所以,顯然,由於rotateY的角度是同樣的,所以,看上去的效果也就如出一轍了!

上面的第8個元素不見了,這不難理解,前面一排門,每一個門都是1米寬,你距離門3米,顯示,當全部門都開了45°角的時候,此時,距離中間門右側的第三個門正好與你的視線平行,這個門的門面顯然就什麼也看不到。

縮放 scale

3D變形中的縮放主要有 scaleZ(z)scale3d(x,y,z) 兩種函數。

scaleZ(z)

2D 環境下的縮放比較好理解,元素進行相應的放大縮小便可,而3D 環境下涉及到z 軸的縮放,z 軸的縮放很奇怪,至今沒有想太透徹,只是簡單的實踐實踐。有曉得的留言告知,後期想透徹了再更新此處。

我進行了若干種狀況的實踐。

一,單獨使用 scaleZ ,發現不管如何改變縮放值,都沒有任何變化。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style type="text/css">
    .wrapper {
        float: left;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .cube {
        font-size: 4em;
        width: 2em;
        margin: 1.5em auto;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .c2 {
        margin-left: 50px;
        // 不斷調整此處的值,看不出任何變化。
        transform: scaleZ(2);
    }
    .side {
        position: relative;
        width: 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);
    }
  </style>
</head>
<body>

<div class="wrapper w1" style="margin-left:150px;">
    <div class="cube">
        <div class="side front">1</div>
    </div>
</div>
<div class="wrapper w2">
    <div class="cube c2">
        <div class="side front">2</div>
    </div>
</div>

</body>
</html>

二,讓子元素.front進行3D變換,這時調整值,能夠看出縮放效果。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style type="text/css">
    .wrapper {
        float: left;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .cube {
        font-size: 4em;
        width: 2em;
        margin: 1.5em auto;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .c2 {
        margin-left: 50px;
        transform: scaleZ(2);
    }
    .side {
        position: relative;
        width: 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);
    }
  </style>
</head>
<body>

<div class="wrapper w1" style="margin-left:150px;">
    <div class="cube">
        <div class="side front">1</div>
    </div>
</div>
<div class="wrapper w2">
    <div class="cube c2">
        <div class="side front">2</div>
    </div>
</div>

</body>
</html>

三,取消.front的變換,將變換應用到.c2上並置於縮放前,改變縮放值,沒有任何變化。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style type="text/css">
    .wrapper {
        float: left;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .cube {
        font-size: 4em;
        width: 2em;
        margin: 1.5em auto;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .c2 {
        margin-left: 50px;
        transform: translateZ(1em) scaleZ(2);
    }
    .side {
        position: relative;
        width: 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);
    }
  </style>
</head>
<body>

<div class="wrapper w1" style="margin-left:150px;">
    <div class="cube">
        <div class="side front">1</div>
    </div>
</div>
<div class="wrapper w2">
    <div class="cube c2">
        <div class="side front">2</div>
    </div>
</div>

</body>
</html>

四,調換移動和縮放的位置,再改變縮放的值,能夠看出變化。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style type="text/css">
    .wrapper {
        float: left;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .cube {
        font-size: 4em;
        width: 2em;
        margin: 1.5em auto;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .c2 {
        margin-left: 50px;
        transform: scaleZ(2) translateZ(1em);
    }
    .side {
        position: relative;
        width: 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);
    }
  </style>
</head>
<body>

<div class="wrapper w1" style="margin-left:150px;">
    <div class="cube">
        <div class="side front">1</div>
    </div>
</div>
<div class="wrapper w2">
    <div class="cube c2">
        <div class="side front">2</div>
    </div>
</div>

</body>
</html>

五,改變transform-origin(下面會介紹此屬性)的默認值,再改變縮放值也能夠看出變化。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style type="text/css">
    .wrapper {
        float: left;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .cube {
        font-size: 4em;
        width: 2em;
        margin: 1.5em auto;
        perspective: 300px;
        transform-style: preserve-3d;
    }
    .c2 {
        margin-left: 50px;
        transform-origin: 0 0 100px;
        transform: scaleZ(2);
    }
    .side {
        position: relative;
        width: 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);
    }
  </style>
</head>
<body>

<div class="wrapper w1" style="margin-left:150px;">
    <div class="cube">
        <div class="side front">1</div>
    </div>
</div>
<div class="wrapper w2">
    <div class="cube c2">
        <div class="side front">2</div>
    </div>
</div>

</body>
</html>

你看懂3D 縮放了嗎?

scale3d(x,y,z)

此屬性值再也不多介紹,x, y, z 同scaleX(x), scaleY(y), scaleZ(z)

transform-origin

transform-origin 是用來設置變換基點的屬性,所謂變換基點即變換的參照點,上面之因此沒有說,是由於其有默認值是元素的中心點,而且能夠用來設置2D變換和3D變換的基點。

平移操做不受基點位置的影響,旋轉,縮放,扭曲都跟基點有關聯。

例如:按元素中心旋轉45度和按左上角旋轉45度。

更改基點很好掌握,其屬性值能夠是百分比、em、px等具體的值,也能夠是toprightbottomleftcenter這樣的關鍵詞。

具體語法以下:

/*只設置一個值的語法*/
transform-origin: x-offset
transform-origin:offset-keyword
/*設置兩個值的語法*/
transform-origin:x-offset  y-offset
transform-origin:y-offset  x-offset-keyword
transform-origin:x-offset-keyword  y-offset
transform-origin:x-offset-keyword  y-offset-keyword
transform-origin:y-offset-keyword  x-offset-keyword
/*設置三個值的語法*/
transform-origin:x-offset  y-offset  z-offset
transform-origin:y-offset  x-offset-keyword  z-offset
transform-origin:x-offset-keyword  y-offset  z-offset
transform-origin:x-offset-keyword  y-offset-keyword  z-offset
transform-origin:y-offset-keyword  x-offset-keyword  z-offset

對上述的值簡述以下:

  • x-offset:用來設置transform-origin水平方向X軸的偏移量,可使用<length><percentage>值,同時也能夠是正值(從中心點沿水平方向X軸向右偏移量),也能夠是負值(從中心點沿水平方向X軸向左偏移量)。

  • offset-keyword:是toprightbottomleftcenter中的一個關鍵詞。

  • y-offset:用來設置transform-origin屬性在垂直方向Y軸的偏移量,可使用<length><percentage>值,同時能夠是正值(從中心點沿垂直方向Y軸向下的偏移量),也能夠是負值(從中心點沿垂直方向Y軸向上的偏移量)。

  • x-offset-keyword:是leftrightcenter中的一個關鍵詞,能夠用來設置transform-origin屬性值在水平X軸的偏移量。

  • y-offset-keyword:是topbottomcenter中的一個關鍵詞,能夠用來設置transform-origin屬性值在垂直方向Y軸的偏移量。

  • z-offset:用來設置3D變形中transform-origin遠離用戶眼睛視點的距離,默認值z=0,其取值能夠<length>,不過<percentage>在這裏將無效。

看上去transform-origin取值與background-position取值相似。

  • top = top center = center top = 50% 0

  • right = right center = center right = 100%或(100% 50%)

  • bottom = bottom center = center bottom = 50% 100%

  • left = left center = center left = 0或(0 50%)

  • center = center center = 50%或(50% 50%)

  • top left = left top = 0 0

  • right top = top right = 100% 0

  • bottom right = right bottom = 100% 100%

  • bottom left = left bottom = 0 100%

變換基點做用在當前元素上。

矩陣變換 matrix

矩陣變換既能夠進行2D變換,又能夠進行3D變換,上面全部的變換均可以經過矩陣變換來實現,換句話說,上面介紹的變換都是矩陣變換的某個特例。

下面的內容是考驗你幾何數學的時候了。

CSS 中使用 4x4 矩陣表示變換。

矩陣中全是數(整數或小數,或者正數、負數和零),數字對於咱們的顯示器來講,你能夠理解爲像素值。

變換是創建在平面或空間上的,數字天然而然的能夠對應座標值。

既然引入了座標系,你天然而然的想到座標原點,沒錯,就是transform-origin這廝。

2D 變換的矩陣函數是:matrix(a, b, c, d, e, f),對應的矩陣以下圖。

3D 變換的矩陣函數是:matrix3d(m11,m12,m13,m14,m21,m22,m23,m24,m31,m32,m33,m34,m41,m42,m43,m44)

下面羅列上述變換對應的矩陣原型:

移動 translate

3D 移動的矩陣原型爲:

matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,x,y,z,1)

2D 移動的原型就是上面的 tz=0 的狀況。

matrix(1, 0, 0, 1, x, y)

縮放 scale

3D 縮放的矩陣原型爲:

matrix3d(sx,0,0,0,0,sy,0,0,0,0,sz,0,0,0,0,1)

2D 移動的原型就是上面的 sz=1 的狀況。

matrix(sx, 0, 0, sy, 0, 0)

旋轉 rotate

3D 旋轉的矩陣原型爲:

旋轉軸由向量 [x, y, z] 定義。在上面的 rotate3d 中介紹了。

α 爲旋轉的角度。

2D 旋轉其實就是繞着 z 軸轉,即向量 [0, 0, 1].

對應的 matrix 本身寫去吧。

扭曲 skew

扭曲只有2D 扭曲。

skew(αdeg, βdeg)

只沿x軸扭曲,β=0,只沿y軸扭曲,α=0.

視距 perspective

視距也有對應的矩陣。

矩陣的運算

全部的變換都是創建在2D或3D空間中,其實也能夠徹底理解成3D空間(3D包含2D嘛,z軸爲0不就是2D嘛)。

全部的變換理解成座標運算就容易理解多了。

看一下矩陣乘法的定義吧:

下面以3D 移動爲例演示矩陣的運算。

原座標從 (a,b,c) 變到 (a+x,b+y,c+z).

總結

咱們從直觀和精確計算深刻探討了CSS3 變換的各類狀況,相信你對變換已經有了必定的瞭解。

2D 變換除了扭曲稍微繞點,其餘的都比較好理解。3D變換沒有扭曲,3D旋轉稍微複雜點,不過也好理解,3D縮放沒有透徹理順,誰知道請明示一下。

變換涉及到的四個屬性。

perspective 設置舞臺元素(變換元素的父元素),理解爲人到舞臺的距離。

transform-style 也是設置在父元素,控制子元素是在二維平面仍是三維空間。

transform-origin 做用在變換元素上,控制變換的基點(座標原點)。

backface-visibility 做用在變換元素上,指示變換元素旋轉180度背面是否可見。

這篇文章耽擱的過久了,先這樣發吧。有關於3D 縮放的記得留言討論。

參考資料

相關文章
相關標籤/搜索