国产三级黄色在线网址_日韩欧美成人影院_国产精品国产名人在线_“黄片在线免费看”_51免费午夜啪啪_金瓶梅在线3D456影院_欧美色 亚洲色 偷拍_免费国产精品黄片_黄色三级电影在线播放_国产人妖视频一区二区精品

北京網(wǎng)站制作|北京網(wǎng)站制作公司|北京網(wǎng)站設(shè)計(jì)|北京網(wǎng)站設(shè)計(jì)公司-龍禧網(wǎng)絡(luò)專(zhuān)注網(wǎng)站建設(shè)19年,服務(wù)客戶(hù)超5000家!

業(yè)務(wù)咨詢(xún):158-0164-8880

北京網(wǎng)站制作之—網(wǎng)頁(yè)前端設(shè)計(jì)也能做的AR互動(dòng)

發(fā)布時(shí)間:2017-09-19    瀏覽:

  目錄

 
一、項(xiàng)目體驗(yàn)
二、技術(shù)實(shí)現(xiàn)
三、兼容情況
四、遇到的問(wèn)題
五、結(jié)語(yǔ)
 
 
正文

 
一、項(xiàng)目體驗(yàn)
 
    以往的AR,都是要在某個(gè)APP內(nèi)才可以體驗(yàn)到的,例如pokemon go和QQ AR火炬?zhèn)鬟f活動(dòng)。

\\

 
     我們團(tuán)隊(duì)在做技術(shù)儲(chǔ)備的時(shí)候,發(fā)現(xiàn)Android設(shè)備下微信、手Q支持getUserMedia()網(wǎng)頁(yè)拉起攝像頭,并通過(guò)createObjectURL把數(shù)據(jù)流傳給video在頁(yè)面展示,以營(yíng)造出實(shí)時(shí)視頻的效果。據(jù)最新統(tǒng)計(jì)數(shù)據(jù)顯示,安卓操作系統(tǒng)占有全球移動(dòng)智能手機(jī)系統(tǒng)86.2%的市場(chǎng)份額。也就是說(shuō),我們可以基于微信和手Q來(lái)做網(wǎng)頁(yè)的AR互動(dòng)啦?。。?/strong>(http://digi.tech.qq.com/a/20160822/034526.htm?t=1471877263208)
于是我們基于實(shí)際需求發(fā)起并開(kāi)發(fā)了一個(gè)WebAR的H5項(xiàng)目,玩家進(jìn)來(lái)頁(yè)面可以在不安裝額外APP的情況下,體驗(yàn)到AR帶來(lái)的樂(lè)趣;針對(duì)不支持實(shí)時(shí)視頻的瀏覽器,就提供3D全景體驗(yàn)版。進(jìn)入頁(yè)面根據(jù)提示操作即可完成WebAR小游戲,跳轉(zhuǎn)落地頁(yè)。

\   

\  \

 
 
二、技術(shù)實(shí)現(xiàn)
 
2.1 WebRTC——WebAR的基礎(chǔ)
 
     無(wú)論是APPAR還是WebAR的一個(gè)最基礎(chǔ)要實(shí)現(xiàn)的功能就是實(shí)時(shí)視頻效果。WebRTC(網(wǎng)頁(yè)實(shí)時(shí)通信,Web Real-Time Communication)是一個(gè)支持網(wǎng)頁(yè)瀏覽器進(jìn)行實(shí)時(shí)語(yǔ)音對(duì)話(huà)或視頻對(duì)話(huà)的API。getUserMedia()是WebRTC的其中一個(gè)API,就是支持網(wǎng)頁(yè)拉起攝像頭的API,攝像頭獲取到的數(shù)據(jù)流會(huì)以<video>標(biāo)簽作為載體呈現(xiàn)在頁(yè)面上,這就給了我們一個(gè)很好的信息,可以在video上疊加任何我們需要的內(nèi)容和操作,從而營(yíng)造出WebAR的效果。
 
關(guān)鍵代碼:
function getMedia() { 
 if (navigator.getUserMedia) { 
 navigator.getUserMedia({ 
 'video': { 
 'optional': [{ 
 }] 
 }
 }, successFunc, errorFunc); 
 } 
 else { 
 alert('Native device media streaming (getUserMedia) not supported in this browser.'); 
 }
} 
var localStream;
function successFunc(stream) { 
 document.getElementById('video').src = window.URL && window.URL.createObjectURL(stream) || stream;
 localStream = stream; 
} 
function errorFunc(e) { 
 alert('Error!'+e); 
} 
function closeMedia() { 
 localStream.stop();
 document.getElementById('video').src = '';
}

 (http://blog.csdn.net/journey191/article/details/40744015)

 
2.2 3D模型——WebGL、three.js、3DMAX
 
    這次做的WebAR非??犰诺囊粋€(gè)體驗(yàn)是他的3D模型展示。要在網(wǎng)頁(yè)展示3D模型,需要先把模型放到3DMAX里進(jìn)行預(yù)處理(過(guò)程會(huì)遇到很多bug和困難),導(dǎo)出成js文件,再借助three.js在頁(yè)面里建立模型、調(diào)整動(dòng)畫(huà)等(過(guò)程也會(huì)遇到很多bug和困難)。這塊工作主要是四姑娘(signhuang)來(lái)負(fù)責(zé)的,讓我們期待四姑娘后面更詳細(xì)心酸的分享吧。
 
2.3 3D全景——three.js、球體全景
 
    3D全景的制作有很多種方法,CSS3、Flash、Krpano等,因?yàn)?D模型動(dòng)畫(huà)我們是借助three.js在頁(yè)面建模的,所以3D全景我們也考慮用three.js來(lái)制作。
 
 
三、兼容情況
 
3.1 getUserMedia()
 
     由于蘋(píng)果的安全機(jī)制問(wèn)題,iOS設(shè)備任何瀏覽器都不支持getUserMedia()。
     最終數(shù)據(jù)展示,Android設(shè)備下,有99.45%的設(shè)備在微信是支持getUserMedia()的,98.05%的設(shè)備在手Q是支持getUserMedia()的。而我們之前測(cè)試機(jī)型里面,本機(jī)瀏覽器、QQ瀏覽器對(duì)getUserMedia()都有不同程度的支持。
     2015年底前,也就是chrome47版本前,chrome是支持http頁(yè)面拉起攝像頭的,出于安全問(wèn)題考慮,chrome47版本后只支持https頁(yè)面拉起攝像頭。

\

(http://caniuse.mojijs.com/Home/Html/item/key/stream/index.html)
 
3.2 3D模型&3D全景
 
     WebGL是一項(xiàng)利用JavaScript API渲染交互式3D電腦圖形和2D圖形的技術(shù),可兼容任何的網(wǎng)頁(yè)瀏覽器,無(wú)需加裝插件。WebGL在現(xiàn)代瀏覽器中已經(jīng)被廣泛支持。3D模型在移動(dòng)設(shè)備瀏覽器上的兼容情況還是很好的,已測(cè)試機(jī)型里面,92%的設(shè)備是支持瀏覽器3D建模和動(dòng)畫(huà)的。

\

(http://caniuse.mojijs.com/Home/Html/item/key/webgl/index.html)
 
 
四、遇到的問(wèn)題
 
4.1 getusermedia()
 
4.1.1 前后攝像頭
遇到問(wèn)題:
      使用getUserMedia()拉起攝像頭時(shí),默認(rèn)是拉起前置攝像頭的,但是要營(yíng)造WebAR的效果,肯定是需要拉起后置攝像頭的。
 
解決方法:
      因?yàn)樵讷@取設(shè)備源ID的時(shí)候,前置攝像頭會(huì)排在后置攝像頭前,不單獨(dú)設(shè)置的話(huà),就會(huì)使用第一個(gè)獲取到的設(shè)備源ID,也就是前置攝像頭的ID。稍微增加點(diǎn)預(yù)處理即可。
 
關(guān)鍵代碼:
var exArray = []; //存儲(chǔ)設(shè)備源ID 
if (navigator.getUserMedia) { 
 MediaStreamTrack.getSources(function (sourceInfos) { 
 for (var i = 0; i != sourceInfos.length; ++i) { 
 var sourceInfo = sourceInfos[i]; 
 //這里會(huì)遍歷audio,video,所以要加以區(qū)分 
 if (sourceInfo.kind === 'video') { 
 exArray.push(sourceInfo.id); 
 } 
 }
 navigator.getUserMedia({ 
 'video': { 
 'optional': [{ 
 'sourceId': exArray[1] //0為前置攝像頭,1為后置 
 }] 
 },
 'audio':false 
 }, successFunc, errorFunc); 
 });
}

 

4.1.2 攝像頭全屏
遇到問(wèn)題:
    攝像頭拍攝的內(nèi)容不能完美的全屏,上下總有留白,不完美。嘗試了多種原生設(shè)置來(lái)設(shè)置<video>大小,希望能完美鋪滿(mǎn)全屏,然而都不成功。
 
解決方法:
     上圖是用CSS設(shè)置了<video>為紅色背景,并且設(shè)置了寬高鋪滿(mǎn)全屏。<video>標(biāo)簽確實(shí)如期待的展現(xiàn),但攝像頭拍攝到的內(nèi)容卻不會(huì)被合理鋪滿(mǎn)全屏??梢岳斫鉃榫拖裎覀兤匠E臄z的視頻,是有固定寬高比的,在瀏覽器寬高比不同又要求視頻全部顯示時(shí),就會(huì)出現(xiàn)上下留白或者左右留白的情況。測(cè)試發(fā)現(xiàn),<video>標(biāo)簽不需要另外設(shè)置寬高,會(huì)默認(rèn)為鋪滿(mǎn)全屏并且溢出,那我們?cè)谕鈱釉黾右粋€(gè)div并且設(shè)置為瀏覽器寬高,再增加 overflow:hidden就可以模擬全屏的效果了。

\    \

 
關(guān)鍵代碼:
<style>
#videoBox{position: absolute;left: 50%;top: 50%;z-index: 1;-webkit-transform: translate(-50%,-50%);-webkit-transform-origin: 50% 50%;}
#videoWrap{position: relative;left: 0;top: 0;background: #4CAABE;overflow: hidden;}
</style>
<div id="videoWrap">
 <video autoplay="autoplay" id="videoBox"></video>
</div>
<script>
var videoWrap = document.getElementById('videoWrap');
videoWrap.style.width = window.innerWidth + 'px';
videoWrap.style.height = window.innerHeight + 'px';
</script>
 
4.1.3 頁(yè)面無(wú)法針對(duì)模型點(diǎn)擊
遇到問(wèn)題:
    本來(lái)頁(yè)面設(shè)置的是讓用戶(hù)點(diǎn)擊3D模型來(lái)進(jìn)行交互的,可發(fā)現(xiàn)沒(méi)辦法單獨(dú)點(diǎn)擊到模型,整個(gè)交互就不能進(jìn)行下去了。
 
解決方法:
      修改了頁(yè)面的點(diǎn)擊交互方式,改用坐標(biāo)瞄準(zhǔn)判定的方式。頁(yè)面中心設(shè)置一個(gè)瞄準(zhǔn)區(qū)域,用戶(hù)移動(dòng)手機(jī)讓3D模型處在瞄準(zhǔn)區(qū)域內(nèi),即判定為成功,進(jìn)行下一步。這樣就避免了頁(yè)面需要點(diǎn)擊的情況。
     思路是:3D模型和camera都有自己的三維坐標(biāo),new THREE.Vector3獲取到兩者的坐標(biāo),a.angleTo(b)求他們的夾角,夾角小于設(shè)定范圍,則判斷為已瞄準(zhǔn)。
      由于最開(kāi)始的需求是要做一個(gè)tips,提醒用戶(hù)向左轉(zhuǎn)或者向右轉(zhuǎn),用的是new THREE.Vector2獲取到兩者在Y面的坐標(biāo),再用a.angle()-b.angle()求得兩者在Y面的夾角來(lái)判斷當(dāng)前camera在模型的右側(cè)還是左側(cè)。新需求相當(dāng)于要增加上下的判定,用new THREE.Vector2獲取到兩者在X面的坐標(biāo),再用a.angle()-b.angle()求得兩者在X面的夾角。Y面夾角和X面夾角都小于設(shè)定范圍時(shí),則判斷為已瞄準(zhǔn)。
 

\

 
關(guān)鍵代碼:
/***瞄準(zhǔn)判定***/
var v = camera.getWorldDirection();
//左右判斷
var a1 = new THREE.Vector2( a.position.x, a.position.z );
var b1 = new THREE.Vector2( v.x, v.z );
dt1 = a1.angle()-b1.angle();
//上下判斷
var a2 = new THREE.Vector2( a.position.y, a.position.z );
var b2 = new THREE.Vector2( v.y, v.z );
dt2 = a2.angle()-b2.angle();
if(Math.abs(dt1)<0.1 && Math.abs(dt2)<0.1){
 //居中啦!
}

 

4.2 3D全景
 
4.2.1 iOS和Android初始化3D全景的朝向不一致
遇到問(wèn)題:
    iOS設(shè)備在任何朝向(東南西北)打開(kāi)3D全景,都是看向一個(gè)固定方向的。

\

 
    Android設(shè)備在不同朝向(東南西北)打開(kāi)3D全景,看向的是不同方向。

\

 
    這個(gè)頁(yè)面為了降低交互難度以及固定讓3D模型出現(xiàn)在舞臺(tái)上(背景比較好看),需要的是在不同朝向(東南西北)打開(kāi)3D全景,都是看向一個(gè)固定方向的。
 
解決方法:
      頁(yè)面加載完畢初始化camera,獲取到camera看向的矢量(不會(huì)根據(jù)看向角度不同而不同),lookAt(target)旋轉(zhuǎn)3D全景朝向那個(gè)位置,這樣每次打開(kāi)頁(yè)面都會(huì)朝向一個(gè)固定的方向,再rotate各個(gè)方向進(jìn)行最終調(diào)整。
 
關(guān)鍵代碼:
var v = camera.getWorldDirection();
var geometry = new THREE.SphereGeometry( 1000, 16, 8 );
 geometry.scale( -1, 1, 1 );
var material = new THREE.MeshBasicMaterial( {
 map: new THREE.TextureLoader().load( 'bg.jpg' )
} );
var stage = new THREE.Mesh( geometry, material );
stage.lookAt(new THREE.Vector3( v.x, 0, v.z ));
stage.rotateY((85 * Math.PI)/180);
stage.rotateZ((-4 * Math.PI)/180);
scene.add( stage );

 

4.2.2 初始化定位
遇到問(wèn)題:
    用戶(hù)進(jìn)入頁(yè)面時(shí)候的手機(jī)角度有各種情況,可能是豎著手機(jī)掃描二維碼,然后平放手機(jī)等待加載完成查看頁(yè)面。頁(yè)面初始化方向和最終查看方向差太多的話(huà),渲染的全景、3D模型等的位置可能會(huì)偏移很大。
 
解決方法:
    進(jìn)入頁(yè)面捕獲camera看向的矢量,加載完成捕獲當(dāng)前camera看向的矢量,有偏移的話(huà)重新初始化全景、3D模型等的位置和角度。
 
關(guān)鍵代碼:
if(!hasMoved && typeof(defaultCameraDirection)!='undefined'){
 var v = camera.getWorldDirection();
 if( v.x != defaultCameraDirection.x
 || v.y != defaultCameraDirection.y
 || v.z != defaultCameraDirection.z
 ){
 hasMoved = true;
 resetLocationAndRotation();//初始化
 }
}

 

4.3 不支持情況排除
 
4.3.1 getUserMedia()、three.js、陀螺儀
 
①判斷是否支持getUserMedia()
function getMedia() { 
 if (navigator.getUserMedia) { 
 }, successFunc, errorFunc);//errorFunc是設(shè)備支持getUserMedia但是用戶(hù)不同意調(diào)用攝像頭的情況
 } 
 else { 
 //設(shè)備不支持getUserMedia
 }
} 
function errorFunc(e) { 
 alert('Error!'+e); 
}

 

②用Detector.js判斷是否支持WebGL
<script src="https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js"></script>
<script>
if(!Detector.webgl) {
 //不支持WebGL
}else{
 //支持WebGL
}
</script>

 

③使用three.js有報(bào)錯(cuò)時(shí)
console.error = (function(origin){ 
 return function(errorlog) {
 if(/THREE/.test(errorlog)) {
 //Three報(bào)錯(cuò)
 }
 } 
})(console.error);
console.warn = (function(origin){ 
 return function(errorlog) {
 if(/^THREE.WebGLRenderer:$/.test(errorlog)) {
 //Three渲染時(shí)報(bào)錯(cuò)
 }
 } 
})(console.warn);

 

④設(shè)備不支持陀螺儀
if(window.DeviceOrientationEvent) {
 //支持陀螺儀
}else{
 //不支持陀螺儀
}

 

4.3.2 iOS8未知錯(cuò)誤
遇到問(wèn)題:
      有位遠(yuǎn)方的同事是iPhone 5S,測(cè)試發(fā)現(xiàn)加載到100%了,加載界面一直不消失,頁(yè)面卡住。
 
解決方法:
      本身頁(yè)面的設(shè)置是:為了防止加載界面隱藏后,3D全景和3D模型沒(méi)渲染完成顯示一片空白,于是加了個(gè)判定,建模渲染完成才隱藏加載界面。找身邊的同事借了iPhone 5S測(cè)試,能順利進(jìn)入3D全景AR界面,所以不是設(shè)備問(wèn)題。問(wèn)了下微信版本也是最新的,系統(tǒng)版本是iOS8,而沒(méi)有問(wèn)題的iPhone 5S的系統(tǒng)版本是iOS9,所以考慮是系統(tǒng)版本導(dǎo)致的問(wèn)題。但是設(shè)備不在身邊沒(méi)辦法一步步排除可能性,查了下iOS8的占比只有2.8%,該游戲用戶(hù)群體iOS設(shè)備占比少于30%,所以決定放棄這部分用戶(hù)的頁(yè)面體驗(yàn),直接跳轉(zhuǎn)落地頁(yè)。
 
關(guān)鍵代碼:
var agent = navigator.userAgent.toLowerCase() ;
var version;
if(agent.indexOf("like mac os x") > 0){
 //ios
 var regStr_saf = /os [\d._]*/gi ;
 var verinfo = agent.match(regStr_saf) ;
 version = (verinfo+"").replace(/[^0-9|_.]/ig,"").replace(/_/ig,".");
}
var version_str = version+"";
if(version_str != "undefined" && version_str.length >0){
 version=version.substring(0,1);
 if(version>5 && version <9){
 //版本為iOS8以下直接跳轉(zhuǎn)落地頁(yè)
 }
}

 

 
五、結(jié)語(yǔ)

 

做新技術(shù)研究和實(shí)踐的過(guò)程中會(huì)遇到?jīng)]有先例的坑,去查API文檔,曲線(xiàn)救國(guó)的方式解決問(wèn)題(有時(shí)候覺(jué)得重構(gòu)/前端是一個(gè)需要帶著小聰明的工種XD)。很感謝游戲公眾號(hào)的同事們給予的大力支持讓我們的頁(yè)面能順利上線(xiàn)并被推送給玩家,看著數(shù)據(jù)蹭蹭蹭的漲,終于覺(jué)得努力沒(méi)有白費(fèi)了。

最終頁(yè)面的數(shù)據(jù)展示出,部分用戶(hù)設(shè)備是支持拉起攝像頭的,但可能出于安全問(wèn)題的考慮,他們拒絕拉起。這是我們后續(xù)工作要考慮的一個(gè)問(wèn)題,如何保護(hù)用戶(hù)隱私以及讓用戶(hù)信任我們。

總的來(lái)說(shuō),這是一次很有趣充實(shí)的新技術(shù)研究和實(shí)踐,學(xué)習(xí)的過(guò)程是很讓人幸福的。

新聞推薦

熱度排行

北京龍禧科技發(fā)展有限公司 電話(huà):158 0164 8880 早8:00—晚22:00(周一至周日) 在線(xiàn)咨詢(xún)
在線(xiàn)咨詢(xún) 電話(huà)咨詢(xún)