使用three.js写全景图,使用sprite类canvas,结合射线,点击跳转指定全景图

话不多说上代码:

1、html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        html, body {
            margin: 0;
            height: 100%;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body onload="draw();">
</body>
<script src="js/three.js"></script>
<script src="js/panorama.js"></script>
</html>

2、js

	var key=4;
    var renderer;
    var camera;
    var scene;
    var light;
    var stats;
    var isUserInteracting = false,lon = 90,lat = 0,phi = 0, theta = 0,target = new THREE.Vector3();
    var raycaster = new THREE.Raycaster();
    var mouse = new THREE.Vector2();    //鼠标位置
    var mesh,texture=[],go_room=[];
    texture[0] = THREE.ImageUtils.loadTexture("images/1.jpg",null,function(t){});
    texture[1] = THREE.ImageUtils.loadTexture("images/2.jpg",null,function(t){});
    texture[2] = THREE.ImageUtils.loadTexture("images/3.jpg",null,function(t){});
    texture[3] = THREE.ImageUtils.loadTexture("images/4.jpg",null,function(t){});
    texture[4] = THREE.ImageUtils.loadTexture("images/5.jpg",null,function(t){});
    texture[5] = THREE.ImageUtils.loadTexture("images/6.jpg",null,function(t){});
    function initRender() {
        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
    }
    function initCamera() {
        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 11000);
        camera.target = new THREE.Vector3( 0, 0, 0 );
    }
    function initScene() {
        scene = new THREE.Scene();
    }
    function initLight() {
    }
    function initModel() {
        //声明一个球体
        var geometry = new THREE.SphereGeometry( 500, 60, 40 );
        // 反转X轴上的几何图形,使所有的面点向内。
        geometry.scale( -1, 1, 1 );
        //声明球体纹理
        if(texture[key-1]==undefined){
            texture[key-1]=THREE.ImageUtils.loadTexture("images/"+key+".jpg",null,function(t){});
        }
        var material = new THREE.MeshBasicMaterial({map:texture[key-1]});
        mesh = new THREE.Mesh( geometry,material );
        scene.add( mesh );
        initpos();
    }
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );
    }
    function onDocumentMouseMove( event ) {
        if ( isUserInteracting === true ) {
            lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
            lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
        }
    }
    function onDocumentMouseUp( event ) {
        isUserInteracting = false;
    }
    function onDocumentMouseDown( event ) {
        //通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1.
        mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
        mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
        // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
        raycaster.setFromCamera( mouse, camera );
        // 获取raycaster直线和所有模型相交的数组集合
        var intersects = raycaster.intersectObjects(go_room);
        console.log(intersects);
        if(intersects.length ==1){
            switch (intersects[0].object.name){
                case "room1":
                    changeScene(1);
                    break;
                case "room2":
                    changeScene(2);
                    break;
                case "room3":
                    changeScene(3);
                    break;
                case "room4":
                    changeScene(4);
                    break;
                case "room5":
                    changeScene(5);
                    break;
                case "room6":
                    changeScene(6);
                    break;
            }
        }else{
            event.preventDefault();
            isUserInteracting = true;
            onPointerDownPointerX = event.clientX;
            onPointerDownPointerY = event.clientY;
            onPointerDownLon = lon;
            onPointerDownLat = lat;
        }
    }
    function onDocumentMouseWheel( event ) {
        var fov = camera.fov + event.deltaY * 0.05;
        camera.fov = THREE.Math.clamp( fov, 10, 75 );
        camera.updateProjectionMatrix();
    }
    function onDocumentTouchStart( event ) {
        if ( event.touches.length == 1 ) {
            event.preventDefault();
            onPointerDownPointerX = event.touches[ 0 ].pageX;
            onPointerDownPointerY = event.touches[ 0 ].pageY;
            onPointerDownLon = lon;
            onPointerDownLat = lat;
        }
    }
    function onDocumentTouchMove( event ) {
        if ( event.touches.length == 1 ) {
            event.preventDefault();
            lon = ( onPointerDownPointerX - event.touches[0].pageX ) * 0.1 + onPointerDownLon;
            lat = ( event.touches[0].pageY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
        }
    }
    function animate() {
        update();
        requestAnimationFrame( animate );
    }
    function update() {
        if ( isUserInteracting === false ) {
            lon += 0.1;
        }
        lat = Math.max( - 85, Math.min( 85, lat ) );
        phi = THREE.Math.degToRad( 90 - lat );
        theta = THREE.Math.degToRad( lon );
        target.x = 500 * Math.sin( phi ) * Math.cos( theta );
        target.y = 500 * Math.cos( phi );
        target.z = 500 * Math.sin( phi ) * Math.sin( theta );
        camera.lookAt( target );
        renderer.render( scene, camera );
    }
    function draw() {
        initRender();
        initScene();
        initCamera();
        initLight();
        initModel();
        animate();
    }
    function changeScene(index){
        key=index;
        var material = mesh.material;
        if(texture[key-1]==undefined){
            texture[key-1]=THREE.ImageUtils.loadTexture("images/"+key+".jpg",null,function(t){});
        }
        material.map = texture[key-1];
        material.map.needsUpdate = true;
        throwDir(key);
    }
    function throwDir(key){
        switch (key){
            case 1:
                for(var i=0;i<6;i++){
                    if(i==3){
                        go_room[i].position.set(3.5,0,-0.3);
                    }else{
                        go_room[i].position.set(100,100,100);
                    }
                    scene.add(go_room[i]);
                }
                break;
            case 2:
                for(var i=0;i<6;i++){
                    if(i==3){
                        go_room[i].position.set(3.5,0,-0.5);
                    }else{
                        go_room[i].position.set(100,100,100);
                    }
                    scene.add(go_room[i]);
                }
                break;
            case 3:
                for(var i=0;i<6;i++){
                    if(i==3){
                        go_room[i].position.set(3,0,1);
                    }else{
                        go_room[i].position.set(100,100,100);
                    }
                    scene.add(go_room[i]);
                }
                break;
            case 4:
                go_room[0].position.set(-2.5,-0.2,-0.6);
                scene.add(go_room[0]);
                go_room[1].position.set(-3.8,0.3,-0.3);
                scene.add(go_room[1]);
                go_room[2].position.set(-3.8,0.3,0.3);
                scene.add(go_room[2]);
                go_room[3].position.set(-3,100,-0.6);
                scene.add(go_room[3]);
                go_room[4].position.set(-2.5,-0.2,0.6);
                scene.add(go_room[4]);
                go_room[5].position.set(-1.7,0,3);
                scene.add(go_room[5]);
                break;
            case 5:
                for(var i=0;i<6;i++){
                    if(i==3){
                        go_room[i].position.set(0.5,0,-2);
                    }else{
                        go_room[i].position.set(100,100,100);
                    }
                    scene.add(go_room[i]);
                }
                break;
            case 6:
                for(var i=0;i<6;i++){
                    if(i==3){
                        go_room[i].position.set(-0.3,0,2);
                    }else{
                        go_room[i].position.set(100,100,100);
                    }
                    scene.add(go_room[i]);
                }
                break;
        }
    }
    function initpos(){
        go_room[0] = makeTextSprite( " ","☝卧室1",{
            "fontsize":20
        });
        go_room[0].name="room1";
        go_room[0].position.set(-2.5,-0.2,-0.6);
        scene.add(go_room[0]);


        go_room[1] = makeTextSprite( " ","☝卧室2",{
            "fontsize":20
        });
        go_room[1].name="room2";
        go_room[1].position.set(-3.8,0.3,-0.3);
        scene.add(go_room[1]);


        go_room[2] = makeTextSprite( " ","☝卧室3",{
            "fontsize":20
        });
        go_room[2].name="room3";
        go_room[2].position.set(-3.8,0.3,0.3);
        scene.add(go_room[2]);


        go_room[3] = makeTextSprite( " ","☝客厅",{
            "fontsize":20
        });
        go_room[3].name="room4";
        go_room[3].position.set(-3,100,-0.6);
        scene.add(go_room[3]);


        go_room[4] = makeTextSprite( " ","☝卫生间",{
            "fontsize":20
        });
        go_room[4].name="room5";
        go_room[4].position.set(-2.5,-0.2,0.6);
        scene.add(go_room[4]);


        go_room[5] = makeTextSprite( " ","☝厨房",{
            "fontsize":12
        });
        go_room[5].name="room6";
        go_room[5].position.set(-1.7,0,3);
        scene.add(go_room[5]);
    }
    window.addEventListener( 'resize', onWindowResize, false );
    document.addEventListener( 'mousedown', onDocumentMouseDown, false );
    document.addEventListener( 'mousemove', onDocumentMouseMove, false );
    document.addEventListener( 'mouseup', onDocumentMouseUp, false );
    document.addEventListener( 'wheel', onDocumentMouseWheel, false );
    document.addEventListener( 'touchstart', onDocumentTouchStart, false );
    document.addEventListener( 'touchmove', onDocumentTouchMove, false );
    document.addEventListener( 'touchend', onDocumentMouseDown, false );
    function makeTextSprite( message,message_zw, parameters){
	    if ( parameters === undefined ) parameters = {};
	    var fontface = parameters.hasOwnProperty("fontface") ?
	        parameters["fontface"] : "Arial";
	    var fontsize = parameters.hasOwnProperty("fontsize") ?
	        parameters["fontsize"] : 30;
	    var borderThickness = parameters.hasOwnProperty("borderThickness") ?
	        parameters["borderThickness"] : 4;
	    var borderColor = parameters.hasOwnProperty("borderColor") ?
	        parameters["borderColor"] : { r:0, g:0, b:0, a:1.0 };
	    var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?
	        parameters["backgroundColor"] : { r:0, g:0, b:0, a:1.0 };
	    var canvas = document.createElement('canvas');
	    var context = canvas.getContext('2d');
	    context.font = "Bold " + fontsize + "px " + fontface;
	    var metrics = context.measureText( message );
	    var textWidth = metrics.width;
	    context.fillStyle   = "rgba(" + backgroundColor.r + "," + backgroundColor.g + ","
	        + backgroundColor.b + "," + backgroundColor.a + ")";
	    context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + ","
	        + borderColor.b + "," + borderColor.a + ")";
	    context.lineWidth = borderThickness;
	    context.fillStyle = "#ff0000";
	    context.fillText( message, borderThickness, fontsize + borderThickness);
	    context.font =  40 + "px " + fontface;
	    context.fillText( message_zw, borderThickness, fontsize + borderThickness+40);
	    var texture = new THREE.Texture(canvas);
	    texture.needsUpdate = true;

	    var spriteMaterial = new THREE.SpriteMaterial(
	        { map: texture, useScreenCoordinates: false} );
	    var sprite = new THREE.Sprite( spriteMaterial );
	    sprite.scale.set(0.5,0.5,0.5);
	    return sprite;
	}

个人服务器,一兆带宽,全景图比较大,下载慢,需要等一会

查看地址:http://47.104.152.68/panorama/changeqjt.html

各位有没有啥处理图片的好方式尽量压缩图片,因为我的全景图平均每张有一兆大小,访问比较慢,请关注评论我

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值