{{pointName}}
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;
}
}
}
};
.test-wrapper {
height: 100vh;
}