基于Three.js的全景展示框架-TPano

        在一些全景展示类应用中,经常需要对采集到全景照片进行展示,一般情况下,可以通过制作人员使用pano2vr进行数据处理(教程可参见:实战!使用pano2vr生成html5全景页面),将处理好的数据发布至静态服务器,再关联相应位置即可完成全景展示(详情见基于Leaflet的全景综合展示实战)。

        以上这种方式可用于素材不多,发布后不会轻易变化,而且对制作时间没有精确时间要求的场景。而且应用多依赖于人工操作,如果想直接对采集的全景照片进行直接展示的,可以采用什么方案呢?本文将介绍一种不依赖于人工的全景素材直接展示的解决方案。

       Three.js是一个可以运行在浏览器端的3D引擎,可以创建多种三维场景,是webGL的一种丰富展示,通过控制相机、场景、材质、光照等信息来完成3D展示(Three.js的专业知识可以具体参考官网或者搜索引擎,本文不赘述)。

        TPano基于Three.js可以直接对全景照片进行展示,无需任何人工处理,所见即所得,非常方便。下面将如何在TPano中集成全景进行简单阐述。

       第一步、引入Three.js 和TPano.js 等信息

!--引入three.js-->
<script src="./three.js"></script>
<script src="../dist/tpano.js"></script>
<!--设备朝向控制器,不引入无法使用体感控制-->
<script src="./DeviceOrientationControls.js"></script>
<!--jquery框架,这里引入用来做一些其它的操作,TPano不依赖它,故你不需要可以不引入-->
<script src="./jquery-2.1.4.js"></script>

      第二步、定义全景照片对象

let panoPhoto = [
        //全景照片数组,每项为一张照片
        {
            url: 'pano/DSCN0007.JPG',
            name: '足球场入口',
        },
        {
            url: 'pano/DSCN0009.JPG',
            name: '足球场'
        }, {
            url: 'pano/DSCN0013.JPG',
            name: '足球场坡道'
        }, {
            url: 'pano/DSCN0016.JPG',
            name: '湖边'
        }, {
            url: 'pano/DSCN0017.JPG',
            name: '图书馆旁'
        }, {
            url: 'pano/DSCN0018.JPG',
            name: '小公园'
        }, {
            url: 'pano/DSCN0019.JPG',
            name: '篮球场旁'
        },
        {
            url: 'pano/DSCN0035_1.avi',
            type: 'VIDEO',
            name: '视频'
        },
    ];

       第三步、定义网页dom渲染节点

<body id="pano">
    <div id="load">
        <div id="load-bar-k">
            <div id="load-bar-x"></div>
        </div>
    </div>

    <div id="controller-y">
        <div id="photo" onclick="switchPhoto()" class="item item-f">
            <img src="./img/bar/photo.png" alt="照片">
            <div class="point"></div>
        </div>
        <div id="gyro" onclick="switchGyro()" class="item item-f">
            <img src="./img/bar/gyro.png" alt="体感">
            <div class="point"></div>
        </div>
        <div class="item item-s" onclick="hidefunction()">
            <img src="./img/bar/function.png" alt="功能">
        </div>
    </div>

    <div id="photo-box">
        <div>
            <div hidden class="photo-box-div" id="example">
                <img class="photo-box-img" src="" alt="">
                <p class="photo-box-p">示例</p>
            </div>
        </div>
    </div>
</body>

       第四步、开启TPano加载

 var tpano = new TPano({
        el: 'pano',//照片查看器根节点dom的id
        photo: panoPhoto,
        photoLoad: function (e) {
            console.log(e);
            closeLoadAnimate();
            if (gi == 0) {
                //第一张照片加载完毕

                //解锁控制器
                controllerLock = true;

                //6秒后隐藏功能键
                setTimeout(() => {
                    hidefunction();
                }, 6000);
            }

            gi++;

            if (gi == panoPhoto.length) {
                //全部加载完毕
                //这个时间点开始加载相册,此功能未经后端优化的情况下加载的是原始照片,故非常的占用带宽,我们希望晚一些加载它
                cratePhoneBox();
                photoBoxLock = true;
            }
        },
        switchLoad: function (e) {
            console.log(e);
            switch (e.status) {
                case 'loading':
                    loadAnimate();
                    break;
                case 'end':
                    closeLoadAnimate();
                    break;
                default:
                    alert('加载出错');
                    break;
            }
        },
        gyroSport: function (e) {
            if (!e && !msgStatus) {
                msgStatus = true;
                alert('设备可能不支持陀螺仪,或者您没有启用https。多数浏览器安全策略只对启用了https的网站提供陀螺仪服务。');
            }
        },
        hotspot: [
            //全景照片上的热点
            {
                source: '足球场入口',//此热点放置在哪张全景照片上
                position: {//热点所在的位置
                    x: 496.89276177820193,
                    y: -45.470141450240746,
                    z: 15.7856948039098
                },
                imgUrl: './img/foot.png',
                jumpTo: '足球场'//热点点击后跳往何方
            },
            {
                source: '足球场',
                position: {
                    x: -336.2550875236564,
                    y: -14.322516705554547,
                    z: -369.0878923870561
                },
                imgUrl: './img/foot.png',
                jumpTo: '足球场坡道'
            },
            {
                source: '足球场坡道',
                position: {
                    x: 9.916517848911612,
                    y: -73.87696480294954,
                    z: -493.83818114696464
                },
                imgUrl: './img/foot.png',
                jumpTo: '湖边'
            },
            {
                source: '湖边',
                position: {
                    x: 54.089284409982234,
                    y: -25.567089425803836,
                    z: 495.95622841487307
                },
                imgUrl: './img/foot.png',
                jumpTo: '图书馆旁'
            },
            {
                source: '足球场坡道',
                position: {
                    x: -496.45652472791767,
                    y: -25.137666788574762,
                    z: -48.767873292494635
                },
                imgUrl: './img/foot.png',
                jumpTo: '图书馆旁'
            },
            {
                source: '图书馆旁',
                position: {
                    x: -22.146984058775047,
                    y: -53.75657318610189,
                    z: 495.5786184825647
                },
                imgUrl: './img/foot.png',
                jumpTo: '小公园'
            },
            {
                source: '小公园',
                position: {
                    x: 470.9682632032511,
                    y: -66.67077805764235,
                    z: 153.04203582643925
                },
                imgUrl: './img/foot.png',
                jumpTo: '篮球场旁'
            },
            {
                source: '篮球场旁',
                position: {
                    x: -452.2504972710258,
                    y: 7.828318511793819,
                    z: 211.56713992810768
                },
                imgUrl: './video.png',
                jumpTo: '视频'
            }
        ],
        DeviceOrientationControls: false,//设备朝向体感控制,默认关闭
        rotateAnimateController: true,//镜头自转
        debug: true,//调试模式
    });

        第五步、展示效果如下

图片

全景展示1

图片

全景相册

       六、总结,以上展示了如何使用TPano进行全景素材的展示。基于Three.js即可完成图片和视频的展示而不需要进行图片切片处理,从而提高了数据从采集到发布的效率。

       TPano框架展示地址:https://gitee.com/push_0x57df/TPano,这是gitee上分享的框架地址,感兴趣的朋友可以clone到本地进行调试。

      留一个思考的问题:全景照片一般都很大,如果直接展示不仅影响速度,而且会加大服务器的带宽压力,那么如何解决全景的快速可视化呢?欢迎交流。

猜你喜欢

转载自blog.csdn.net/yelangkingwuzuhu/article/details/121060112
今日推荐