three.js实现炫酷的全景3D重力感应

实现three.js 全景图 demo

使用three.js 写了球体和圆柱体版本的3D重力感应全景图,支持手指触摸和陀螺仪感应,也支持PC端的鼠标。给大家介绍一下基于移动端H5球体的实现方法,圆柱体类似。

设置容器和展示的样式
设置容器的宽高为全屏展示,清除body的margin,引用three.min.js(3D渲染框架) 和orienter.js (陀螺仪经纬度计算)

three.js实现炫酷的全景3D重力感应

<div></div> <script src="https://www.jb51.net/js/three.min.js"></script> <!--重力感应--> <script src="https://www.jb51.net/js/orienter.js"></script> <!--动画效果--> <script src="https://www.jb51.net/js/tween.js"></script> <!-- 代码 -->

body {margin: 0;} html, body, #CanvasBody {width: 100vw;height: 100vh;overflow: hidden;} #CanvasBody {position: relative;}

设置html的data-dpr 属性,设置html 的fontSize

设置html的fontSize,重新计算body的实际可展示尺寸,这样可以使渲染出来的画面更清晰,分辨率最完美。

(function(_window) { var navigatorUserAgent = navigator.userAgent; var iPhone = navigatorUserAgent.indexOf("iPhone"); if (iPhone > -1) { var dpr = Number(window.devicePixelRatio), one_dpr = 1 / dpr } else { var dpr = 1, one_dpr = 1 } var writeText = "<meta name=\"viewport\" content=\"width=device-width,initial-scale=" + one_dpr + ",maximum-scale=" + one_dpr + ",minimum-scale=" + one_dpr + ",user-scalable=no\">\n <meta name=\"'flexible\" content=\"initial-dpr=" + dpr + "\">"; document.write(writeText); var html = document.getElementsByTagName("html"); var F0 = 75; html[0].setAttribute("data-dpr", dpr); var getFontSize = function getFontSize() { var windowWidth = window.innerWidth; html[0].style.fontSize = F0 * windowWidth / 750 + "px" }; getFontSize(); _window.addEventListener("resize", getFontSize, false) })(window);

定义相关变量

var camera,//摄像机 scene,//舞台 renderer,//渲染器 isUserInteracting = false,//用户是否正在操作 onMouseDownMouseX = 0, onMouseDownMouseY = 0,//鼠标点击的x和Y坐标 lon = 0, onMouseDownLon = 0, onPointerDownLon= 0.0,onPointerDownPointerX = 0,//经度 lat = 0, onMouseDownLat = 0, onPointerDownLat= 0.0,onPointerDownPointerY = 0,//纬度 phi = 0, theta = 0,//计算相机位置的重要参数 o = new Orienter(),//陀螺仪方法对象 new_longitude=0,last_longitude=0,move_longitude=0,//改变的经度的计算 new_latitude=0,last_latitude=0,move_latitude=0,//改变的纬度的计算 is_touch=false,is_start=false,isPlay=true,isMusicPlay=true,tsa=100.1,ppl=''; var raycaster = new THREE.Raycaster();//拾取场景里面的物体,可判断点击或交互事件对应的元素 var mouse = new THREE.Vector2();//二维向量的对象,鼠标计算

初始化舞台的元素和内容

图片的长宽控制在4096px以内,部分机型性能不够,渲染不了超大的图片

function init() {/**初始化**/ var container, mesh;//容器和素材 container = document.getElementById( 'CanvasBody' );//容器 camera = new THREE.PerspectiveCamera( 72, window.innerWidth / window.innerHeight, 0.01, 1100 );//相机 camera.target = new THREE.Vector3( 0, 0, 0 );//相机位置 scene = new THREE.Scene();//舞台 scene.updateMatrixWorld(true); var geometry = new THREE.SphereGeometry(1, 32, 16);//球体 geometry.scale( 1, 1, -1 ); //设置球体的背景贴图 var textureBg = new THREE.TextureLoader().load("img/bg.jpg"); textureBg.generateMipmaps = true; textureBg.magFilter = THREE.LinearFilter;//设置贴纸素材的质量 textureBg.minFilter = THREE.LinearFilter; var material = new THREE.MeshBasicMaterial( { map: textureBg,//圆柱体贴图,全景图 //color:0xFF0000, //transparent: true } ); mesh = new THREE.Mesh( geometry, material ); //这里可以设置对应的动画效果 // new TWEEN.Tween( mesh).to( {transform:"rotate(90deg)"}, 800 ).repeat( false ).delay( 300 ).yoyo( true ).easing( TWEEN.Easing.Cubic.InOut ).start(); scene.add( mesh ); // 旋转预设 摄影机看到的角度 Start// scene.rotation.set(0,0,0); //首頁 //初始化渲染器,追加到容器 renderer = new THREE.WebGLRenderer({precision: 'highp' ,mipmap: 'highp',antialias:false});//加上precision 和 mipmap参数,调整画面清晰度 renderer.setPixelRatio( window.devicePixelRatio );//设置像素比 renderer.setSize( window.innerWidth, window.innerHeight );//设置渲染窗口的大小 container.appendChild( renderer.domElement );//追加到容器中去 //鼠标、手机touch的各个事件 document.addEventListener( 'mousedown', onDocumentMouseDown, false ); document.addEventListener( 'mousemove', onDocumentMouseMove, false ); document.addEventListener( 'mouseup', onDocumentMouseUp, false ); document.addEventListener( 'touchstart', onDocumentTouchDown, false ); document.addEventListener( 'touchmove', onDocumentTouchMove, false ); document.addEventListener( 'touchend', onDocumentTouchUp, false ); // document.addEventListener( 'wheel', onDocumentMouseWheel, false ); // document.addEventListener( 'dragover', function ( event ) { event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; }, false ); document.addEventListener( 'dragenter', function ( event ) { document.body.style.opacity = 0.5; }, false ); document.addEventListener( 'dragleave', function ( event ) { document.body.style.opacity = 1; }, false ); document.addEventListener( 'drop', function ( event ) { event.preventDefault(); var reader = new FileReader(); reader.addEventListener( 'load', function ( event ) { material.map.image.src = event.target.result; material.map.needsUpdate = true; }, false ); reader.readAsDataURL( event.dataTransfer.files[ 0 ] ); document.body.style.opacity = 1; }, false ); }

监听的各事件和方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/cf040e7c16a6b44b0409c46f64dfc8bf.html