摘要:淘寶造物節(jié)的活動(dòng)頁就是全景的一個(gè)很贊的頁面,它將全景圖分割成等份,相鄰的元素構(gòu)成的夾角,相鄰兩側(cè)面相對(duì)于棱柱中心所構(gòu)成的夾角。
本文轉(zhuǎn)自凹凸實(shí)驗(yàn)室:https://aotu.io/notes/2016/08...
前言3D 全景并不是什么新鮮事物了,但以前我們在 Web 上看到的 3D 全景一般是通過 Flash 實(shí)現(xiàn)的。若我們能將 CSS3 Transform 的相關(guān)知識(shí)運(yùn)用得當(dāng),也是能實(shí)現(xiàn)類似的效果。換句話說,3D 全景其實(shí)就是 CSS3 3D 的應(yīng)用場景之一。
準(zhǔn)備在實(shí)現(xiàn) CSS3 3D 全景之前,我們先理清部分 CSS3 Transform 相關(guān)的屬性:
transform-origin:元素變形的原點(diǎn)(默認(rèn)值為 50% 50% 0,該數(shù)值和后續(xù)提及的百分比默認(rèn)均基于元素自身的寬高算出具體數(shù)值);
transform-style:為子元素提供 2D 還是 3D 的場景。另外,該屬性是非繼承的;
transform:修改 CSS 可視化模型的坐標(biāo)空間,包括 平移(translate)、旋轉(zhuǎn)(rotate)、縮放(scale) 和 扭曲(skew)。
下面我們對(duì)上述的一些點(diǎn)進(jìn)行更深入的分析:
對(duì)于 perspective,該屬性指定了“眼睛”與元素的 perspective-origin(默認(rèn)值是 50% 50% 0)點(diǎn)的距離。那么問題來了:“當(dāng)我們以 px 作為衡量單位時(shí),它的實(shí)際距離該如何量化呢?”
答:當(dāng)屏幕分辨率是 1080P(1920*1080px)且該元素或其祖先元素的 perspective 數(shù)值的值為 1920px 時(shí),應(yīng)用了 CSS3 3D Transform 的子元素的立體效果就相當(dāng)于我們在距離一個(gè)屏幕寬度(1920px)的屏幕前觀看該元素時(shí)的真實(shí)效果。盡管如此,目前筆者也不知道如何準(zhǔn)確地為元素設(shè)置一個(gè)合適的 perspective 值,只能猜測大概值后進(jìn)行調(diào)整,以達(dá)到滿意的呈現(xiàn)效果。
根據(jù) 相似三角形 的性質(zhì)可計(jì)算出被前移的元素最終在屏幕上顯示的實(shí)際大小
另外,關(guān)于 perspective 還有另外一個(gè)重要的點(diǎn)是:因?yàn)?perspective-origin 屬性的默認(rèn)值是 50% 50% 0,所以對(duì)哪個(gè)元素應(yīng)用 perspective 屬性,就決定了“眼睛”的位置(即我們的“眼睛”是在哪個(gè)角度看物體)。一般來說,當(dāng)我們需要正視物體時(shí),就會(huì)將該屬性設(shè)置在與該元素中心重合的某一祖先元素上。
再另外,如果說:“如何讓一個(gè)元素(的背面)不可見?”,你可能會(huì)回答 backface-visibility:hidden;。其實(shí),對(duì)于在“眼睛”背后的元素(以元素的 transform-origin 為參考點(diǎn)),即元素的 Z 軸坐標(biāo)值大于 perspective 的值時(shí),瀏覽器是不會(huì)將其渲染出來的。
對(duì)于 transform-style,該屬性指定了其子元素是處于 3D 場景還是 2D 場景。對(duì)于 2D 場景,元素的前后位置是按照平時(shí)的渲染方式(即若在普通文檔流中,同層級(jí)元素是按照代碼中元素的先后編寫順序,后面的元素會(huì)遮住在其前面的元素);對(duì)于 3D 場景,元素的前后位置則按照真實(shí)世界的規(guī)則排序(即靠近“眼睛”的元素,會(huì)遮住離“眼睛”遠(yuǎn)的元素)。
另外,由于 transform-style 屬性是非繼承的,對(duì)于中間節(jié)點(diǎn)需要顯式設(shè)定。
對(duì)于 transform 屬性:下圖整理了 rotate3d、translate3d 的變換方向:
需要注意的是:transform 中的變換屬性的順序是有關(guān)系的,如 translateX(10px) rotate(30deg) 與 rotate(30deg) translateX(10px) 是不等價(jià)的。
另外,需要注意的是 scale 中如果有負(fù)值,則該方向會(huì)產(chǎn)生 180 度的翻轉(zhuǎn);
再另外,部分 transform 效果會(huì)導(dǎo)致元素(字體)模糊,如 translate 的數(shù)值存在小數(shù)、通過 translateZ 或 scale 放大元素等等。每個(gè)瀏覽器都有其不同的表現(xiàn)。
實(shí)現(xiàn)上面理清了一些 CSS Transform 相關(guān)的知識(shí)點(diǎn),下面就講講如何實(shí)現(xiàn) CSS 3D 全景 :
想象一下,當(dāng)我們站在十字路口中間,身體旋轉(zhuǎn) 360°,這個(gè)過程中所看到的畫面就是一幅以你為中心的全景圖了。其實(shí),當(dāng)焦距不變時(shí),我們就等同于站在一個(gè)圓柱體的中心。
但是,虛擬世界與現(xiàn)實(shí)世界的最大不同是:沒有東西是連續(xù)的,即所有東西都是離散的。例如,你無法在屏幕上顯示一個(gè)完美的圓。你只能以一個(gè)正多邊形表示圓:邊越多,圓就越“完美”。
同理,在三維空間中,每個(gè) 3D 模型都是一個(gè)多面體(即 3D 模型由不可彎曲的平面組成)。當(dāng)我們討論一個(gè)本身就是多面體(如立方體)的模型時(shí)并不足以為奇,但我們想展示其它模型時(shí),如球體,就需要記住這個(gè)原理了。
淘寶造物節(jié)的活動(dòng)頁 就是 CSS 3D 全景的一個(gè)很贊的頁面,它將全景圖分割成 20 等份,相鄰的元素構(gòu)成的夾角 18°(360/20,相鄰兩側(cè)面相對(duì)于棱柱中心所構(gòu)成的夾角)。需要注意的是:我們要確保每個(gè)元素的正面是指向棱柱中心的。所以要計(jì)算好每等份的旋轉(zhuǎn)角度值后,再將元素向外(即 Z 軸方向)平移 r px。對(duì)于立方體的 r 就是 邊長/2,而對(duì)于其它更復(fù)雜的正多面體呢?
舉例:對(duì)于正九棱柱,每個(gè)元素的寬為 210px,對(duì)應(yīng)的角度為 40°,即如下圖:
圖片來自:https://desandro.github.io/3d...
正九棱柱的俯視圖
計(jì)算過程
由此可得到一個(gè)公用函數(shù),只需傳入含有元素的寬度和元素?cái)?shù)量的對(duì)象,即可得到 r 值:
function calTranslateZ(opts) { return Math.round(opts.width / (2 * Math.tan(Math.PI / opts.number))) } calTranlateZ({ width: 210, number: 9 }); // 288
俯視時(shí)所看到的元素外移動(dòng)畫
另外,為了讓下文易于理解,我們約定 HTML 的結(jié)構(gòu):
#view(perspective:1000px) #stage(transform-style:preserve-3d) #cube(transform-style:preserve-3d) .div(width:600px;height:600px;) /*組成立方體的元素*/
正棱柱構(gòu)建完成后,就需要將我們的“眼睛”放置在正棱柱內(nèi)。由于在“眼睛”后的元素是不會(huì)被瀏覽器渲染的(與 .div元素 是否設(shè)置 backface-visibility:hidden; 無關(guān)),而且我們保證 .div元素 的正面都是指向正棱柱中心,這樣就形成 360° 被環(huán)繞的效果了。
那“眼睛”具體被放置在哪個(gè)位置呢?
答:通過設(shè)置 #stage 元素的 translateZ 值,讓不能被看到的 .div元素 在 Z 軸上的最終坐標(biāo)值(即其自身 Z 坐標(biāo)和祖先元素 Z 坐標(biāo)相加)大于 #view 元素的 perspective 值即可。如:立方體的正面的 translateZ 是 -300px(為了保證立方體的正面是指向立方體中心,正面元素需要以自身水平方向上的中線為軸,旋轉(zhuǎn) 180度,即 rotateY(-180deg) translateZ(-300px),即正面元素向“眼球”方向平移了 300px),而 #view 的 perspective 值為 1000px,那么 #stage 的 translateZ 值應(yīng)該大于 700px 且小于 1300px 即可,具體數(shù)值則取決于你想要的呈現(xiàn)效果。
根據(jù)上述知識(shí),筆者粗略地模仿了“造物節(jié)”的效果:http://jdc.jd.com/lab/zaowu/i...
另外,只需 6 幅圖就可以實(shí)現(xiàn)一張常見的無死角全景圖。
筆者自己又試驗(yàn)了下:http://jdc.jd.com/lab/zaowu/i...
可由下圖看出,將水平的 4 張圖片合成后就是一張全景圖:
因此,理解上述知識(shí)后,通過 CSS3 Transform 相關(guān)屬性就可以實(shí)現(xiàn)可交互的全景效果了。當(dāng)然,交互的效果可以是拖拽,也可以是重力感應(yīng)等。
正如在上文提到的:“沒有東西是連續(xù)的,即所有東西都是離散的...”。通過兩個(gè)案例的對(duì)比可以發(fā)現(xiàn):圖片數(shù)量越多,對(duì)圖片的要求也越低。你覺得呢?
造物節(jié)全景圖
將全景圖制作分為設(shè)計(jì)類與實(shí)景類:
設(shè)計(jì)類要制作類似 《淘寶造物節(jié)》 的全景頁面,設(shè)計(jì)稿需要有以下這些要求。
注:下面提及的具體數(shù)據(jù)均基于《造物節(jié)》,可根據(jù)自身要求進(jìn)行調(diào)整(若發(fā)現(xiàn)欠缺,歡迎作出補(bǔ)充)。
整體背景設(shè)計(jì)圖如下(2580*1170px,被分成 20 等份):
基本要求:
水平方向上需要首尾相連;
因?yàn)樾Ч麍D最終需要切成 N 等份,所以盡可能讓 設(shè)計(jì)圖的寬度能被 N 整除;
圖片尺寸不僅要考慮正視圖的大小,還要考慮元素在上下旋轉(zhuǎn)時(shí)依然能覆蓋視野(可選)。
當(dāng)然,上圖只是作為背景,我們還可以添加一些小物體素材(與背景圖的運(yùn)動(dòng)速度不同時(shí),可形成視差效果,增強(qiáng)立體感),如:
小物體元素(虛線用于參考,造物節(jié)中共有 21 個(gè)小物體)
如上圖所示,每個(gè)圖片也被等分成 M 等份,而且 M 的寬度應(yīng)該與 N(背景元素)的寬度相等(具體原因,請看文章評(píng)論)。
對(duì)于頂部和底圖圖片,則無特殊要求。
實(shí)景類如果想制作實(shí)景的全景效果,可以看看 Google 街景:
Google 街景 推薦的設(shè)備如下:
如上圖,最實(shí)惠的方式就是最后一個(gè)選項(xiàng)——Google 街景 APP,該應(yīng)用提供了全景相機(jī)功能,但正如圖片介紹所說,這是需要練習(xí)的,因此對(duì)操作要求比較高。
補(bǔ)充:
上周六(2016.8.20)參加了 TGDC 的分享會(huì),嘉賓分享了他們處理全景的方式:
利用 RICOH THETA S 等專業(yè)設(shè)備拍出全景圖
導(dǎo)出靜態(tài)圖像
利用設(shè)備專門提供的 APP 或 krpamo tools、pano2vr、Glsky box 等工具將靜態(tài)圖像轉(zhuǎn)為 6 張圖
利用 Web 技術(shù)制作可交互的全景圖
其中 Web 技術(shù)有以下 3 種可選方式(當(dāng)然,還有其它):
CSS3(本文所提及的方式)
Three.js
krpano(為全景而生,低級(jí)瀏覽器則回退到 Flash),查看教程
當(dāng)時(shí),嘉賓現(xiàn)場快速制作的 會(huì)議現(xiàn)場全景。
可見,優(yōu)秀硬件設(shè)備的出現(xiàn),大大減少了后期處理的時(shí)間,而 Web 則提供了一個(gè)很好的展現(xiàn)平臺(tái)。
最后隨著終端設(shè)備的軟硬件不斷完善和提高,Web 在 3D 領(lǐng)域也不甘落后,如果你玩膩了 2D 的 H5 或者想為用戶提供更加新穎優(yōu)秀的體驗(yàn),全景也許是一種選擇。
最后,如有不清晰或不明白的地方,可以留言,我會(huì)盡可能解決的。謝謝謝~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/111536.html
摘要:實(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í)和...
摘要:可選,默認(rèn)值為,設(shè)置為則禁止用戶和全景圖交互導(dǎo)航條不可用。可選,默認(rèn)值為,全景圖在毫秒后會(huì)自動(dòng)進(jìn)行動(dòng)畫。當(dāng)全景圖準(zhǔn)備就緒并且第一張圖片顯示時(shí)的回調(diào)函數(shù)。 3D全景漫游 showImg(http://mmbiz.qpic.cn/mmbiz/cibketMByvrbpDqUQ9LiaBvutnwMehicnO2RZurdl96FLtwqlf6LjWS0Bv8ApQY0YjHdtyFWuzz...
摘要:同時(shí)需要注意橫豎屏?xí)淹勇輧x的改變開始傾斜時(shí),記錄開始的陀螺儀位置,主體層的位置。檢測陀螺儀轉(zhuǎn)動(dòng)時(shí)間與插件的兼容角度傾斜進(jìn)行緩沖動(dòng)畫以上便是主要代碼,最好自己運(yùn)行調(diào)試下,運(yùn)用好動(dòng)畫函數(shù),理解每一個(gè)步驟。前端實(shí)現(xiàn)還有更牛的。 前端的3D(css3版本),其實(shí)是依托Css3的功勞,先上一個(gè)例子 http://antario.act.qq.com/代碼地址:鏈接:https://pan.b...
閱讀 1932·2021-11-23 09:51
閱讀 1249·2019-08-30 15:55
閱讀 1620·2019-08-30 15:44
閱讀 764·2019-08-30 14:11
閱讀 1148·2019-08-30 14:10
閱讀 920·2019-08-30 13:52
閱讀 2633·2019-08-30 12:50
閱讀 618·2019-08-29 15:04