成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

3d transform的坐標(biāo)空間及位置

fasss / 3230人閱讀

摘要:控制攝像機(jī)畫面網(wǎng)頁里的攝像機(jī)一般是這樣用的在網(wǎng)頁里,無論你搭建了怎樣的三維場景,只要你希望它顯示出來,就應(yīng)該像這樣把構(gòu)成場景的三維物體都放在一個(gè)容器元素里,然后為容器元素添加攝像機(jī)屬性和。

css里的3d理念

使用css3的3d transform,就可以在平面的網(wǎng)頁里添加炫酷的三維視覺效果,這很令人愉悅。

需要注意的是,3d transform只是css的一部分,它并不是一個(gè)三維引擎(3d engine)。三維引擎一般是這樣的(游戲引擎Unity3D):

包括JavaScript 3D庫three.js在內(nèi),簡單來說,它們這些可以稱為三維引擎的,都會(huì)包括:

獨(dú)立的三維坐標(biāo)系統(tǒng)。

幾何圖形和材質(zhì)貼圖。

光照和攝像機(jī)。

3d transform和它們相比起來,是缺少這些內(nèi)容的。畢竟,css的關(guān)注點(diǎn)是網(wǎng)頁樣式,而不是創(chuàng)建虛擬空間。

盡管3d transform的三維空間能力有所不足,但它仍然可以創(chuàng)建出很棒的三維效果。這就需要我們開發(fā)者來用心了。

在下面的內(nèi)容開始之前,如果你還對(duì)perspective等3d transform相關(guān)的css屬性完全不了解,可以閱讀我以前寫的css三維變換的文章。

3d transform的坐標(biāo)系統(tǒng)

我們很熟悉的網(wǎng)頁是平面的,一個(gè)DOM元素,比如一個(gè)

,它會(huì)有一個(gè)初始坐標(biāo)系initial coordinate system):

每一個(gè)DOM元素都有一個(gè)這樣的初始坐標(biāo)系。其中,原點(diǎn)位于元素的左上角,z軸指向觀察者(也就是屏幕外的我們)。初始坐標(biāo)系的z軸并不算是三維空間,而是像z-index那樣作為參照,決定網(wǎng)頁元素的繪制順序,繪制順序靠后的元素將覆蓋繪制順序靠前的。

在使用transform的時(shí)候,情況則有所不同。transform所參照的并不是初始坐標(biāo)系,而是一個(gè)新的坐標(biāo)系:

transform所用的這個(gè)坐標(biāo)系,相比初始坐標(biāo)系,x、y、z軸的指向都不變,只是原點(diǎn)位置移動(dòng)到了元素的正中心。如果想要改變這個(gè)坐標(biāo)系的原點(diǎn)位置,使用transform-origin。transform-origin的默認(rèn)值是50% 50%,因此,默認(rèn)情況下,transform坐標(biāo)系的原點(diǎn)位于元素中心。

transform的順序

我們都可能像transform: rotateY(45deg) translateX(100px);這樣使用多個(gè)變換函數(shù)。這種時(shí)候,需要意識(shí)到變換函數(shù)的順序。這是因?yàn)椋?strong>每一個(gè)變換函數(shù)不僅改變了元素,同時(shí)也會(huì)改變和元素關(guān)聯(lián)的transform坐標(biāo)系,當(dāng)變換函數(shù)依次執(zhí)行時(shí),后一個(gè)變換函數(shù)總是基于前一個(gè)變換后的新transform坐標(biāo)系。

例如,下面一個(gè)包含兩個(gè)變換函數(shù)的transform的效果(gif):

如果交換這兩個(gè)變換函數(shù)的順序,是這樣的效果:

可以看到,由于坐標(biāo)系會(huì)隨著每一次變換發(fā)生改變,因此不同順序的情況下,元素最終的位置也不同。

對(duì)此還有一種解釋,即變換函數(shù)是通過數(shù)學(xué)上的矩陣乘法運(yùn)算完成的,而矩陣的乘法是不滿足交換律的。任意坐標(biāo)空間內(nèi)的變換函數(shù)或者變換函數(shù)的組合,都可以轉(zhuǎn)換為一個(gè)矩陣(還有一個(gè)矩陣小工具可以幫你做這個(gè)轉(zhuǎn)換)。

創(chuàng)建三維物體

前面已經(jīng)提到,3d transform并沒有像三維引擎那樣為你創(chuàng)建三維場景提供全面的資源。因此,就以創(chuàng)建一個(gè)三維物體來說,我們只能利用網(wǎng)頁目前已有的內(nèi)容,自己想辦法。

在網(wǎng)頁里,你并不能直接定義一系列坐標(biāo)為(x, y, z)的空間中的點(diǎn),然后基于這些點(diǎn)來生成三維圖形。網(wǎng)頁里有的,是平面圖形。不管是

還是其他html元素,它們都是平的,沒有厚度,像紙片一樣。但紙片就可以搭東西,所以,一個(gè)DOM元素用作三維物體的一個(gè)“面”,把這些“面”有序地組織起來,得到的就是三維物體了!

事實(shí)上,在三維引擎里,三維物體也不是實(shí)體,它們都是由一系列平面(多邊形)所圍成的(并可以在平面上添加紋理和貼圖)。

正方體

現(xiàn)在來做一個(gè)正方體,現(xiàn)在先不用考慮perspective。正方體有六個(gè)面,然后需要用一個(gè)元素來裝這六個(gè)面,所以html是:

1
2
3
4
5
6

對(duì)應(yīng)的css是(邊長120px,省略瀏覽器私有前綴,后文同):

.cube{
    position: absolute;
    transform-style: preserve-3d;
}
.cube .surface{
    position: absolute;
    width: 120px;
    height: 120px;
    border: 1px solid #ccc;
    background: rgba(255,255,255,0.8);
    box-shadow: inset 0 0 20px rgba(0,0,0,0.2);
    line-height: 120px;
    text-align: center;
    color: #333;
    font-size: 100px;
}
.cube .surface-1 {
    transform: translateZ(60px);
}
.cube .surface-2 {
    transform: rotateY(90deg) translateZ(60px);
} 
.cube .surface-3 {
    transform: rotateX(90deg) translateZ(60px);
}
.cube .surface-4 {
    transform: rotateY(180deg) translateZ(60px);
}
.cube .surface-5 {
    transform: rotateY(-90deg) translateZ(60px);
}
.cube .surface-6 {
    transform: rotateX(-90deg) translateZ(60px);
}

其中,transform-style: preserve-3d;保證所有子元素都處于同一個(gè)三維空間(這里是三維渲染上下文3D rendering context)內(nèi),也就是告訴瀏覽器你是想用這些元素做一個(gè)三維場景,而不僅僅只是要單個(gè)元素的簡單三維效果。

position: absolute;是一個(gè)習(xí)慣做法,因?yàn)槿S物體并不符合一般平面網(wǎng)頁內(nèi)容的排版,所以我們會(huì)比較多地希望它不要占據(jù)布局空間。

6個(gè)面位置都不一樣,但卻都有translateZ(60px);,你已經(jīng)知道這是因?yàn)榍擅畲钆淞嗽谒暗淖儞Q函數(shù)。

一旦構(gòu)成正方體的6個(gè)div.surface的位置確定后,就可以操作它們的父元素div.cube來整體移動(dòng)、旋轉(zhuǎn)這個(gè)正方體。

將三維物體添加到可視區(qū)域

只是有了這樣的一個(gè)三維物體,我們就可以說有了一個(gè)三維場景了。但是,三維場景和平面圖不同,比如這個(gè)正方體,我從不同的位置,不同的角度去觀察它,我眼里看到的都是不一樣的:

那么,這樣的三維場景要如何呈現(xiàn)在平面的網(wǎng)頁里呢?

這就是三維引擎里的攝像機(jī)的概念來源了。就像電影里表現(xiàn)同一個(gè)場景會(huì)用不同的鏡頭那樣,我們需要定義場景里的攝像機(jī)來生成最終呈現(xiàn)在屏幕里的二維畫面。比如three.js里的攝像機(jī)是這樣的感覺:

這個(gè)圖里標(biāo)明的是攝像機(jī)定義時(shí)使用的參數(shù),其中包括視野范圍,圖像寬高比等??梢愿惺艿竭€是有很多內(nèi)容的。

相比之下,網(wǎng)頁里的三維場景攝像機(jī)就弱多了,你需要用的是perspectiveperspective-origin

perspective定義攝像機(jī)(也就是作為觀眾的我們)到屏幕的距離,perspective-origin定義攝像機(jī)觀察到的畫面中的滅點(diǎn)(vanishing point)的位置。雖然它們并不能方便地讓你直接定義攝像機(jī)的位置和觀察角度等,但只要適當(dāng)?shù)貞?yīng)用它們,是可以一定程度上控制攝像機(jī)的畫面效果的。

控制攝像機(jī)畫面

網(wǎng)頁里的攝像機(jī)一般是這樣用的:

.camera{
    position: relative;
    perspective: 1200px;
    perspective-origin: 50% 50%;
    transform-style: preserve-3d;
}

在網(wǎng)頁里,無論你搭建了怎樣的三維場景,只要你希望它顯示出來,就應(yīng)該像這樣把構(gòu)成場景的三維物體都放在一個(gè)容器元素里,然后為容器元素添加攝像機(jī)屬性(perspectiveperspective-origin)。

此外,還需要注意添加transform-style: preserve-3d;以保證多個(gè)三維物體都位于同一空間(這樣才有三維引擎的味道,對(duì)吧?)。

下面這個(gè)場景里有三個(gè)正方體,然后攝影師正在做彈跳練習(xí)(限支持3d transform的瀏覽器):

http://runjs.cn/detail/daqoq5tf

這段動(dòng)作的動(dòng)畫代碼是這樣:

.camera{
    animation: cameraMove 2s ease-out infinite alternate both;
}
@keyframes cameraMove{
    0%{
       perspective-origin: 50% 180px;
    }
    100%{
       perspective-origin: 50% -200px;
    }
}

可以看出,perspective-origin雖然是指三維透視的滅點(diǎn)的位置,但它的確和我們理解的攝像機(jī)的位置是緊密關(guān)聯(lián)的。如果攝像機(jī)在空間里的位置是(x, y, z)的話,perspective-origin的兩個(gè)值有一點(diǎn)像指定xy的感覺。這里只說“有一點(diǎn)像”,是因?yàn)闇琰c(diǎn)位置和攝像機(jī)的位置畢竟是不同的概念,這可能還需要多看一些三維空間來體會(huì)。

那么,在上面的例子中,攝影師不只是這樣跳起來,而是想要向更深處前進(jìn),應(yīng)該怎么做呢?

答案是,在網(wǎng)頁里,你不能這樣移動(dòng)攝像機(jī),你需要換一個(gè)思路,參照相對(duì)運(yùn)動(dòng)的關(guān)系,改為讓整個(gè)三維場景向你移動(dòng)。不過,說到這里,前面提到的攝像機(jī)的另一個(gè)屬性,perspective,為什么它不行呢?

perspective代表攝像機(jī)距離屏幕的距離,看上去和z軸深度非常近似。但是,它并不等同于攝像機(jī)的z坐標(biāo)位置(perspective還只能取正值),而是會(huì)影響攝像機(jī)本身的其他屬性。下面用這個(gè)圖說明perspective的值變化的效果(修改自w3c的配圖):

圖中d1d2分別表示兩個(gè)不同的perspective的值,其中d2小于d1。然后,你會(huì)驚奇地發(fā)現(xiàn),一個(gè)原本位于屏幕之后(z坐標(biāo)為負(fù)值)的物體,竟然是隨著“走近”而變得更小了!顯然,這不符合我們?cè)谌S空間里運(yùn)動(dòng)的基本感受。其原因是,網(wǎng)頁的三維投影平面是固定的,perspective在改變攝像機(jī)的位置的同時(shí),也同時(shí)改變了攝像機(jī)本身的其他屬性(類似前面的three.js的攝像機(jī)那張圖里的各種參數(shù))。

所以,一般來說,perspective應(yīng)維持一個(gè)固定的值。想要用3d transform做出在三維空間里自由移動(dòng)的效果(就像各種3d游戲),應(yīng)該通過相對(duì)運(yùn)動(dòng)的方法實(shí)現(xiàn)。

其他補(bǔ)充 transform對(duì)布局的影響

transform影響的是視覺渲染,而不是布局。因此,除以下情況外,transform不會(huì)影響到布局:

這個(gè)因?yàn)?b>overflow生成滾動(dòng)條從而影響布局的反例,也發(fā)生于position: relative;再進(jìn)行偏移的情況。

left、top等常規(guī)屬性對(duì)3d transform的影響

相對(duì)于transform的translate3d()這類改變空間位置的變換函數(shù),原來css里就有的定位屬性left、top似乎會(huì)讓情況變得很復(fù)雜。

對(duì)此,有一個(gè)比較推薦的分析方式:就三維空間的位置而言,常規(guī)屬性left、top,甚至margin-left等,是先生效的,它們的效果其實(shí)只有一個(gè),就是改變?cè)氐某跏嘉恢?,從而改變?cè)氐?b>transform-origin的那個(gè)原點(diǎn)位置,然后三維空間的transform是后生效的,它會(huì)再基于前面的transform-origin繼續(xù)改變位置。

perspective-origin和transform-origin的區(qū)別

現(xiàn)在你已經(jīng)了解到,perspective-origin是一個(gè)攝像機(jī)的屬性,定義的是透視畫面的滅點(diǎn),而transform-origin是任意元素都有的,定義的是的元素的transform坐標(biāo)系的原點(diǎn)。

結(jié)語

本文是我對(duì)目前網(wǎng)頁里用3d transform創(chuàng)建三維空間的總結(jié),其中混入了一些三維引擎的知識(shí),并對(duì)比著來一一說明。感覺3d transform還是有自己比較明確的定位的,雖然和三維引擎相比很簡陋,但它已經(jīng)足夠用來為網(wǎng)頁添加吸引人的三維效果。

如果你也想過用3d transform做稍復(fù)雜的三維空間,希望本文能有所幫助。

(重新編輯自我的博客,原文地址:http://acgtofe.com/posts/2015/12/xyz-3d-in-css)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/111247.html

相關(guān)文章

  • 祖先元素transform非none時(shí)在Iphone6上引起后代fixed/absolute元素

    摘要:如題,祖先元素非時(shí),記錄一下中引起后代元素參考視圖怪異表現(xiàn)和解決方案。不為元素預(yù)留空間,而是通過指定元素相對(duì)于屏幕視口的位置來指定元素位置。打印時(shí),元素會(huì)出現(xiàn)在的每頁的固定位置。 如題,祖先元素transform非none時(shí),記錄一下Iphone6中引起后代元素fixed參考視圖怪異表現(xiàn)和解決方案。 層疊關(guān)系及參考視圖 層疊上下文是HTML元素的三維概念,這些HTML元素在一條假想的相...

    MarvinZhang 評(píng)論0 收藏0
  • 祖先元素transform非none時(shí)在Iphone6上引起后代fixed/absolute元素

    摘要:如題,祖先元素非時(shí),記錄一下中引起后代元素參考視圖怪異表現(xiàn)和解決方案。不為元素預(yù)留空間,而是通過指定元素相對(duì)于屏幕視口的位置來指定元素位置。打印時(shí),元素會(huì)出現(xiàn)在的每頁的固定位置。 如題,祖先元素transform非none時(shí),記錄一下Iphone6中引起后代元素fixed參考視圖怪異表現(xiàn)和解決方案。 層疊關(guān)系及參考視圖 層疊上下文是HTML元素的三維概念,這些HTML元素在一條假想的相...

    lei___ 評(píng)論0 收藏0
  • CSS3 變換

    摘要:概覽變換也叫轉(zhuǎn)換,主要包括以下幾種旋轉(zhuǎn)扭曲縮放和移動(dòng)以及矩陣變形。變換沒有扭曲操作,有移動(dòng),旋轉(zhuǎn),縮放。三,取消的變換,將變換應(yīng)用到上并置于縮放前,改變縮放值,沒有任何變化。 概覽 CSS3 變換也叫 2D/3D轉(zhuǎn)換,主要包括以下幾種:旋轉(zhuǎn)(rotate) 、扭曲 (skew) 、縮放(scale) 和 移動(dòng)(translate) 以及 矩陣變形(matrix) 。transform ...

    wayneli 評(píng)論0 收藏0
  • H5打造3d場景不完全攻略(二): Amazing CSS3D

    摘要:實(shí)現(xiàn)方法可參考這篇文章純打造的模型渲染器實(shí)現(xiàn)全景。天空盒子相信很多打造過或有了解過全景的同行們都知道這個(gè)概念。首先將創(chuàng)建好的六個(gè)面切割出來,以命名標(biāo)記位置。柱形柱形全景也不算復(fù)雜。 前言 對(duì)的,本文就是著重介紹如何使用CSS3中的3D變換打造出H5中的3D效果。靈感來源于造物節(jié)團(tuán)隊(duì)的3d引擎,因?yàn)槭褂梅椒ū容^復(fù)雜,也沒有開源的API文檔,于是想自己另外造個(gè)輪子,便開始了相關(guān)內(nèi)容的學(xué)習(xí)和...

    fancyLuo 評(píng)論0 收藏0
  • 不會(huì)做動(dòng)畫程序猿不是好動(dòng)畫師(如何用css3動(dòng)畫做動(dòng)畫)

    摘要:一過渡一的作用二的屬性二和動(dòng)畫一動(dòng)畫序列書寫簡例二書寫簡例常用屬性簡寫屬性三完整動(dòng)畫簡例代碼三轉(zhuǎn)換一轉(zhuǎn)換縮放移動(dòng)旋轉(zhuǎn)設(shè)置元素轉(zhuǎn)換的中心點(diǎn)綜合性寫法二轉(zhuǎn)換三維坐標(biāo)系透視呈現(xiàn)位移旋轉(zhuǎn)一過渡一的作用如果你有一個(gè)盒子,他的體內(nèi)也有個(gè)小盒子。 ...

    xeblog 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<