threejs 全景区加可点击标注

<template>

    <div class="test-wrapper" id="container">

        <el-dialog :visible.sync="dialogVisible">

            {{pointName}}

        </el-dialog>

    </div>

</template>

 

<script>

import * as THREE from "three";

 

import qjt from "@/assets/threejs/p2.png";

import Icon from "@/assets/threejs/test1.png";

 

var OrbitControls = require('three-orbit-controls')(THREE)

 

var camera, scene, renderer,controls;

var cameraOrtho, sceneOrtho;

var _sprites = [];

var _lables = [];

var clickableObjects = [];

var _pRadius = 100;

var _raycaster;

var _mouse = new THREE.Vector2();

var containerWidth, containerHeight;

 

export default {

    name: "test",

    data() {

        return {

            pointList:[

                {

                    id:1,

                    name:'aaa',

                    lon:120,

                    lat:0,

                },

                {

                    id:2,

                    name:'bbbb',

                    lon:120,

                    lat:10,

                }

            ],

            rotateSpeed:1,

            pointName:'',

            dialogVisible:false,

        };

    },

    mounted() {

        this.$nextTick(() => {

            this.init();

            this.animate();

        })

       

    },

    methods: {

        init() {

 

            

            let container = document.getElementById('container');

 

            containerWidth = container.clientWidth;

            containerHeight = container.clientHeight;

 

            scene = new THREE.Scene();

            camera = new THREE.PerspectiveCamera(

                75,

                containerWidth / containerHeight,

                0.1,

                1000

            );

 

            var width = containerWidth;

            var height = containerHeight;

            cameraOrtho = new THREE.OrthographicCamera(

                -width / 2,

                width / 2,

                height / 2,

                -height / 2,

                1,

                10

            );

            cameraOrtho.position.z = 10;

 

            sceneOrtho = new THREE.Scene();


 

            var geometry = new THREE.SphereBufferGeometry(100, 60, 40);

            geometry.scale(-1, 1, 1);

 

            var texture = new THREE.TextureLoader().load(qjt);

            var material = new THREE.MeshBasicMaterial({ map: texture });

 

            let mesh = new THREE.Mesh(geometry, material);

 

            scene.add(mesh);

 

            camera.position.z = 50;

 

            renderer = new THREE.WebGLRenderer();

            renderer.setSize(containerWidth, containerHeight);

            renderer.autoClear = false;

            container.appendChild(renderer.domElement);

 

            controls = new OrbitControls(camera, renderer.domElement);

            controls.enablePan = false;

            controls.maxDistance = 100;

            controls.autoRotate = true;

            controls.autoRotateSpeed = this.rotateSpeed;

 

            this.loadPoint();

 

            _raycaster = new THREE.Raycaster();

 

            document.addEventListener("mousedown", this.onMouseDown, false);


 

        },

        animate() {

            requestAnimationFrame(this.animate);

            this.update();

            

        },

        update(){

            controls.update();

            this.renderSprites();

            renderer.render(scene, camera);

            renderer.render(sceneOrtho, cameraOrtho);

        },

        loadPoint(){

            this.pointList.forEach(item => {

                _sprites.push(this.createSprite(item));

            })

        },

        createSprite(item) {

            var textureLoader = new THREE.TextureLoader();

            var ballMaterial = new THREE.SpriteMaterial({

                map: textureLoader.load(Icon)

            });

            var sp1 = {

                lon: item.lon,

                lat: item.lat,

                name: item.name,

                sprite: new THREE.Sprite(ballMaterial)

            };

            sp1.sprite.scale.set(1, 1, 1);

            sp1.sprite.position.set(0, 0, 0);

            sp1.sprite.name = item.name;

            sceneOrtho.add(sp1.sprite);

            clickableObjects.push(sp1.sprite);

            return sp1;

        },

        geoPosition2World(lon, lat) {

            lat = Math.max(-85, Math.min(85, lat));

            var phi = THREE.Math.degToRad(90 - lat);

            var theta = THREE.Math.degToRad(lon);

 

            var result = {

                x: _pRadius * Math.sin(phi) * Math.cos(theta),

                y: _pRadius * Math.cos(phi),

                z: _pRadius * Math.sin(phi) * Math.sin(theta)

            };

            return new THREE.Vector3(result.x, result.y, result.z);

        },

        worldPostion2Screen(world_vector, camera) {

            var vector = world_vector.clone();

            vector.project(camera);

            var result = {

                x: Math.round((vector.x + 1) * containerWidth / 2 - containerWidth / 2),

                y: Math.round(containerHeight / 2 - (-vector.y + 1) * containerHeight / 2),

                z: 0

            };

            return new THREE.Vector3(result.x, result.y, result.z);

        },

        renderSprites(){

            for (var i = 0; i < _sprites.length; i++) {

                var wp = this.geoPosition2World(_sprites[i].lon, _sprites[i].lat);

                var sp = this.worldPostion2Screen(wp, camera);

                var test = wp.clone();

                test.project(camera);

                if (test.x > -1 && test.x < 1 && test.y > -1 && test.y < 1 && test.z > -1 && test.z < 1) {

                    _sprites[i].sprite.scale.set(24, 24, 1.0);

                    _sprites[i].sprite.position.set(sp.x, sp.y, 1);

                } else {

                    _sprites[i].sprite.scale.set(1.0, 1.0, 1.0);

                    _sprites[i].sprite.position.set(0, 0, 0);

                }

            }

        },

        onMouseDown(event){

            controls.autoRotateSpeed = 0;

            _mouse.x = event.clientX / containerWidth * 2 - 1;

            _mouse.y = -(event.clientY / containerHeight) * 2 + 1;

            _raycaster.setFromCamera(_mouse, cameraOrtho);

            var intersects = _raycaster.intersectObjects(clickableObjects);

            if(intersects != null && intersects.length > 0){

                this.pointName = intersects[0].object.name;

                this.dialogVisible = true;

            }else{

                this.dialogVisible = false;

            }

        }

    }

};

</script>

 

<style lang="less" scoped>

.test-wrapper {

    height: 100vh;

}

</style>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
three.js是一个用于创建和展示 3D 地图的开源 JavaScript 库。它提供了许多功能和工具,可以轻松地创建和标注 3D 地图。 首先,我们需要加载地图的基本模型。在 three.js 中,我们可以通过导入地形数据或使用现有的地形模型来创建一个基本的 3D 地图。这可以通过使用 three.js 中的几何体和纹理进行实现。例如,我们可以使用高程数据创建山脉和河流,使用贴图添加地面纹理。 接下来,我们可以使用标注工具在地图上加入标记。这些标记可以是地点、建筑物或其他感兴趣的地方等。我们可以使用 three.js 的几何体和纹理来创建不同类型的标记,如球体、立方体或自定义模型。然后,我们可以将这些标记放置在地图的特定位置,并添加相应的标记文字或图标。 除了标注工具,three.js 还提供了交互性的功能,例如可以通过鼠标或触摸屏进行地图的旋转、缩放和平移操作。这允许用户自由地探索地图,并更好地了解地理环境。 最后,我们可以根据需要对地图进行自定义和优化。我们可以添加光源,使地图的光照效果更加真实。我们还可以使用 three.js 的特效功能,如雾效和阴影效果,来提高地图的视觉质量。 总之,通过使用three.js,我们可以轻松创建和标注3D地图,并使其具有交互性和视觉效果。这个库提供了许多功能和工具,使我们能够将地理数据可视化,并为用户提供一个更加 immersive 和有趣的地图浏览体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值