Web前端也能做的AR互动

2023-06-01 0 321

Web前端也能做的AR互动

产品目录

一、工程项目新体验

二、控制技术同时实现

三、相容情形

四、碰到的难题

五、引言

节录

一、工程项目新体验

    过往的AR,都是要在某一APP内才能新体验到的,比如pokemon go和QQ AR圣火传达公益活动。

Web前端也能做的AR互动Web前端也能做的AR互动

他们项目组在做控制技术实力的时候,发现Android设备下微信、手Q支持getUserMedia()网页拉起摄像头,并通过createObjectURL把数据流传给video在页面展示,以营造出实时视频的效果。据最新统计数据显示,安卓操作系统占有全球移动智能手机系统86.2%的市场份额。也就是说,他们能基于微信和手Q来做网页的AR交互啦!!!

(http://digi.tech.qq.com/a/20160822/034526.htm?t=1471877263208)

于是他们基于实际需求发起并开发了一个WebAR的H5工程项目,玩家进来页面能在不安装额外APP的情形下,新体验到AR带来的乐趣;针对不支持实时视频的浏览器,就提供3D全景新体验版。进入页面根据提示操作即可完成WebAR小游戏,跳转落地页。

Web前端也能做的AR互动

   Web前端也能做的AR互动  Web前端也能做的AR互动

二、控制技术同时实现

2.1 WebRTC——WebAR的基础

无论是APPAR还是WebAR的一个最基础要同时实现的功能就是实时视频效果。WebRTC(网页实时通信,Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的API。getUserMedia()是WebRTC的ebAR的效果。

关键代码:

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非常酷炫的一个新体验是他的3D模型展示。要在网页展示3D模型,需要先把模型放到3DMAX里进行预处理(过程会碰到很多bug和困难),导出成js文件,再借助three.js在页面里建立模型、调整动画等(过程也会碰到很多bug和困难)。这块工作主要是四姑娘(signhuang)来负责的,让他们期待四姑娘后面更详细心酸的分享吧。

2.3 3D全景——three.js、球体全景

    3D全景的制作有很多种方法,CSS3、Flash、Krpano等,因为3D模型动画他们是借助three.js在页面建模的,所以3D全景他们也考虑用three.js来制作。

三、相容情形

3.1 getUserMedia()

     由于苹果的安全机制难题,iOS设备任何浏览器都不支持getUserMedia()。

最终数据展示,Android设备下,有99.45%的设备在微信是支持getUserMedia()的,98.05%的设备在手Q是支持getUserMedia()的。而他们之前测试机型里面,本机浏览器、QQ浏览器对getUserMedia()都有不同程度的支持。

2015年底前,也就是chrome47版本前,chrome是支持http页面拉起摄像头的,出于安全难题考虑,chrome47版本后只支持https页面拉起摄像头。

Web前端也能做的AR互动

(http://caniuse.mojijs.com/Home/Html/item/key/stream/index.html)

3.2 3D模型&3D全景

WebGL是一项利用JavaScript API渲染交互式3D电脑图形和2D图形的控制技术,可相容任何的网页浏览器,无需加装插件。WebGL在现代浏览器中已经被广泛支持。3D模型在移动设备浏览器上的相容情形还是很好的,已测试机型里面,92%的设备是支持浏览器3D建模和动画的。

Web前端也能做的AR互动

(http://caniuse.mojijs.com/Home/Html/item/key/webgl/index.html)

四、碰到的难题

4.1 getusermedia()

4.1.1 前后摄像头

碰到难题:

使用getUserMedia()拉起摄像头时,默认是拉起前置摄像头的,但是要营造WebAR的效果,肯定是需要拉起后置摄像头的。

解决方法:

的设备源ID,也就是前置摄像头的ID。稍微增加点预处理即可。

关键代码:

var exArray = []; //存储设备源ID if(navigator.getUserMedia) { MediaStreamTrack.getSources(function (sourceInfos) { for (var i = 0; i != sourceInfos.length; ++i) { varsourceInfo = sourceInfos[i];//这里会遍历audio,video,所以要加以区分 if (sourceInfo.kind === video) { exArray.push(sourceInfo.id); } } navigator.getUserMedia({video: { optional: [{ sourceId: exArray[1] //0为前置摄像头,1为后置 }] }, audio:false }, successFunc, errorFunc); }); }

4.1.2 摄像头全屏

碰到难题:

    摄像头拍摄的内容不能完美的全屏,上下总有留白,不完美。尝试了多种原生设置来设置<video>大小,希望能完美铺满全屏,然而都不成功。

解决方法:

上图是用CSS设置了<video>为红色背景,并且设置了宽高铺满全屏。<video>标签确实如期待的展现,但摄像头拍摄到的内容却不会被合理铺满全屏。能理解为就像他们平常拍摄的视频,是有固定宽高比的,在浏览器宽高比不同又要求视频全部显示时,就会出现上下留白或者左右留白的情形。测试发现,<video>标签不需要另外设置宽高,会默认为铺满全屏并且溢出,那他们在外层增加一个div并且设置为浏览器宽高,再增加 overflow:hidden就能模拟全屏的效果了。

Web前端也能做的AR互动    Web前端也能做的AR互动

关键代码:

<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 页面无法针对模型点击

碰到难题:

    本来页面设置的是让用户点击3D模型来进行交互的,可发现没办法单独点击到模型,整个交互就不能进行下去了。

解决方法:

修改了页面的点击交互方式,改用坐标瞄准判定的方式。页面中心设置一个瞄准区域,用户移动手机让3D模型处在瞄准区域内,即判定为成功,进行下一步。这样就避免了页面需要点击的情形。

思路是:3D模型和camera都有自己的三维坐标,new THREE.Vecto

者在X面的坐标,再用a.angle()-b.angle()求得两者在X面的夹角。Y面夹角和X面夹角都小于设定范围时,则判断为已瞄准。

Web前端也能做的AR互动

关键代码:

/***瞄准判定***/varv = camera.getWorldDirection();//左右判断var a1 = new THREE.Vector2( a.position.x, a.position.z );var b1 = newTHREE.Vector2( v.x, v.z ); dt1 = a1.angle()-b1.angle();//上下判断var a2 = newTHREE.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全景的朝向不一致

碰到难题:

iOS设备在任何朝向(东南西北)打开3D全景,都是看向一个固定方向的。

Web前端也能做的AR互动

    Android设备在不同朝向(东南西北)打开3D全景,看向的是不同方向。

Web前端也能做的AR互动

这个页面为了降低交互难度以及固定让3D模型出现在舞台上(背景比较好看),需要的是在不同朝向(东南西北)打开3D全景,都是看向一个固定方向的。

解决方法:

面都会朝向一个固定的方向,再rotate各个方向进行最终调整。

关键代码:

var v = camera.getWorldDirection();var geometry = newTHREE.SphereGeometry(1000, 16, 8 ); geometry.scale( -1, 1, 1 );var material = newTHREE.MeshBasicMaterial( { map:new THREE.TextureLoader().load( bg.jpg ) } );var stage = newTHREE.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 初始化定位

碰到难题:

用户进入页面时候的手机角度有各种情形,

解决方法:

进入页面捕获camera看向的矢量,加载完成捕获当前camera看向的矢量,有偏移的话重新初始化全景、3D模型等的位置和角度。

关键代码:

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是设备支持getUserMedia但是用户不同意调用摄像头的情形 } else { //设备不支持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有报错时

console.error = (function(origin){ return function(errorlog) { if(/THREE/.test(errorlog)) {//Three报错 } } })(console.error);console.warn = (function(origin){ return function(errorlog) { if(/^THREE.WebGLRenderer:$/.test(errorlog)) { //Three渲染时报错 } } })(console.warn);

④设备不支持陀螺仪

if(window.DeviceOrientationEvent) { //支持陀螺仪}else{ //不支持陀螺仪}

4.3.2 iOS8未知错误

碰到难题:

有位远方的同事是iPhone 5S,测试发现加载到100%了,加载界面一直不消失,页面卡住。

解决方法:

本身页面的设置是:为了防止加载界面隐藏后,3D全景和3D模型没渲染完成显示一片空白,于是加了个判定,建模渲染完成才隐藏加载界面。找身边的同事借了iPhone 5S测试,能顺利进入3D全景AR界面,所以不是设备难题。问了下微信版本也是最新的,系统版本是iOS8,而没有难题的iPhone 5S的系统版本是iOS9,所以考虑是系统版本导致的难题。但是设备不在身边没办法一步步排除可能性,查了下iOS8的占比只有2.8%,该游戏用户群体iOS设备占比少于30%,所以决定放弃这部分用户的页面新体验,直接跳转落地页。

关键代码:

var agent = navigator.userAgent.toLowerCase() ;var version;if(agent.indexOf(“like mac os x”) > 0){ //ios var regStr_saf = /os [\d._]*/gi ; varverinfo = 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以下直接跳转落地页 } }

五、引言

做新控制技术研究和实践的过程中会碰到没有先例的坑,去查API文档,曲线救国的方式解决难题(有时候觉得重构/后端是一个需要带

最终页面的数据展示出,部分用户设备是支持拉起摄像头的,但可能出于安全难题的考虑,他们拒绝拉起。这是他们后续工作要考虑的一个难题,如何保护用户隐私以及让用户信任他们。

总的来说,这是一次很有趣充实的新控制技术研究和实践,学习的过程是很让人幸福的。

设计交流渠道

欢迎加入TGideas粉丝交流群

QQ群:532110024

暗号:TGideas

知乎IDTGideas

Web前端也能做的AR互动

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务