用threejs实现三维全景图

 

 

网络上看到了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>

 

posted on 2020-03-07 13:19  dawn888  阅读(11045)  评论(2编辑  收藏  举报

导航