threejs下载位置: http://www.threejs.org
我在Facebook上看到Facebook实现了3D全景图,然后,一直很好奇,最后,我发现threejs里面有一个库竟然可以实现,一下我贴出代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <title>three.js css3d - panorama</title> <style> body { background-color: #000000; margin: 0; cursor: move; overflow: hidden; } a { color: #ffffff; } #info { position: absolute; width: 100%; color: #ffffff; padding: 5px; font-family: Monospace; font-size: 13px; font-weight: bold; text-align: center; z-index: 1; } </style> </head> <body> <script src="../build/three.min.js"></script> <!-- 此处引入threejs基础类 --> <script src="js/renderers/CSS3DRenderer.js"></script> <!-- 此处引入CSS3Drenderer.js类 --> <!-- 以上两个文件,在下载threejs的时候就有的,引入就好 --> <script> var camera, scene, renderer; var geometry, material, mesh; var target = new THREE.Vector3(); var lon = 90, lat = 0; var phi = 0, theta = 0; var touchX, touchY; init(); animate(); function init() { camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 ); scene = new THREE.Scene(); /** 次数是重点说明的 * 这个sides对应的是六张图位于立体坐标轴内的位置,里面的position又包含x,y,三个轴 * 然后ratation是三个轴上的变换 */ var sides = [ { position: [ 512, 0, 0 ], // 1 rotation: [ 0, -Math.PI / 2, 0 ] }, { position: [ -512, 0, 0 ], // 2 rotation: [ 0, Math.PI / 2, 0 ] }, { position: [ 0, 512, 0 ], // 3 rotation: [ Math.PI / 2, 0, Math.PI ] }, { position: [ 0, -512, 0 ], // 4 rotation: [ - Math.PI / 2, 0, Math.PI ] }, { position: [ 0, 0, 512 ], // 5 rotation: [ 0, Math.PI, 0 ] }, { position: [ 0, 0, -512 ], // 6 rotation: [ 0, 0, 0 ] } ]; var canvas = document.createElement('canvas'); var image = document.createElement('img'); image.src = 'picture/360photos.jpg'; // 画图,这里引入的这张图片,是一张图上集合了6张图片 image.height = 6144; image.width = 1024; canvas.width = 1024; canvas.height = 1024; // 这里有判断image.onload,这里是判断创建的image节点是否把引入的图片加载进来 image.onload = function() { for ( var i = 0; i < sides.length; i ++ ) { // 由于是六张图放在一张图片上,然后这里分割六张图片 var cxt = canvas.getContext("2d"); cxt.drawImage(image, 0, -1024*i); var side = sides[ i ]; var element = document.createElement( 'img' ); element.width = 1026; // 2 pixels extra to close the gap. document.getElementsByTagName('body')[0].appendChild(canvas); var _img_url = canvas.toDataURL("image/png"); // 获取图片位置 element.src = _img_url; var object = new THREE.CSS3DObject( element ); // 这里根据sides把图片放在坐标轴上进行渲染 object.position.fromArray( side.position ); object.rotation.fromArray( side.rotation ); scene.add( object ); } } renderer = new THREE.CSS3DRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // document.addEventListener( 'mousedown', onDocumentMouseDown, false ); document.addEventListener( 'mousewheel', onDocumentMouseWheel, false ); document.addEventListener( 'touchstart', onDocumentTouchStart, false ); document.addEventListener( 'touchmove', onDocumentTouchMove, false ); window.addEventListener( 'resize', onWindowResize, false ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function onDocumentMouseDown( event ) { event.preventDefault(); document.addEventListener( 'mousemove', onDocumentMouseMove, false ); document.addEventListener( 'mouseup', onDocumentMouseUp, false ); } function onDocumentMouseMove( event ) { var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; lon -= movementX * 0.1; lat += movementY * 0.1; } function onDocumentMouseUp( event ) { document.removeEventListener( 'mousemove', onDocumentMouseMove ); document.removeEventListener( 'mouseup', onDocumentMouseUp ); } function onDocumentMouseWheel( event ) { camera.fov -= event.wheelDeltaY * 0.05; camera.updateProjectionMatrix(); } function onDocumentTouchStart( event ) { event.preventDefault(); var touch = event.touches[ 0 ]; touchX = touch.screenX; touchY = touch.screenY; } function onDocumentTouchMove( event ) { event.preventDefault(); var touch = event.touches[ 0 ]; lon -= ( touch.screenX - touchX ) * 0.1; lat += ( touch.screenY - touchY ) * 0.1; touchX = touch.screenX; touchY = touch.screenY; } function animate() { requestAnimationFrame( animate ); lon += 0.1; lat = Math.max( - 85, Math.min( 85, lat ) ); phi = THREE.Math.degToRad( 90 - lat ); theta = THREE.Math.degToRad( lon ); target.x = Math.sin( phi ) * Math.cos( theta ); target.y = Math.cos( phi ); target.z = Math.sin( phi ) * Math.sin( theta ); camera.lookAt( target ); renderer.render( scene, camera ); } </script> </body> </html>
以上,我把重要的说明点都写上了注释,然后,注意,我这里的图片是去facebook上下载下来的,我把Facebook上的图片手动进行了左右翻转实现的程序,如果不需要手动翻转,如果是渲染Facebook上的图片的话,需要把Facebook的图片用程序进行翻转再分割才能渲染出正常的图片,否则渲染出来的全景是不正常的。
我下面附上的图很大,宽度是1024像素的,然后高度是1024像素*6;原图是这张图的左右翻转。
下面,我附上图,此图来自简书上传的,可能会有盗链导致加载不出来: