const labelParentElem = document.querySelector('#box_text');
var camera,container,scene,loader,renderer,controls;
var _wid=$(window).width();
var options;
if(_wid>768){
options = {
radius: 80, // 地球的半径
segments: 80,
};
}else{
options = {
radius: 70, // 地球的半径
segments: 70,
};
}
let mesh;
let earth = new THREE.Group();
let canvas;
const tempV = new THREE.Vector3();
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
var ball;
var marking = new THREE.Group();
var aaa=$(".city div").length;
var bbb=[];
$(".city div").each(function(){
var site=$(this).attr("data-site").split(",");
var name=$(this).attr("data-name");
var phone=$(this).attr("data-phone");
var address=$(this).attr("data-address");
var j=Number($(this).attr("data-j"));
var w=Number($(this).attr("data-w"));
if ($(this).data('data-phone') !== undefined || $(this).data('data-address') !== undefined) {
// 如果 div 元素有自定义属性 "data-myAttribute",则执行这里的代码
}
if(phone && address ){
bbb.push({
'pos': [j,w],
'textEdit': '
'+name+'
电话:'+phone+'
地址:'+address+'
'
})
}
if(!phone && address){
bbb.push({
'pos': [j,w],
'textEdit': ''+name+'
地址:'+address+'
'
})
}
if(phone && !address ){
bbb.push({
'pos': [j,w],
'textEdit': ''+name+'
电话:'+phone+'
'
})
}
if( !phone && !address ){
bbb.push({
'pos': [j,w],
'textEdit': ''+name+'
'
})
}
})
var markingPos = {
"marking": bbb
}
init();
render();
function getPosition(longitude, latitude, radius) {
var lg = THREE.Math.degToRad(longitude);
var lt = THREE.Math.degToRad(latitude);
var temp = radius * Math.cos(lt);
var x = temp * Math.sin(lg);
var y = radius * Math.sin(lt);
var z = temp * Math.cos(lg);
return {
x: x,
y: y,
z: z
}
}
function init(){
container = document.querySelector('#box');
scene = new THREE.Scene();
loader = new THREE.TextureLoader();
camera = new THREE.PerspectiveCamera(30,container.clientWidth/container.clientHeight,1,1000);
camera.position.x = -200;
camera.position.y = 200;
camera.position.z = -200;
scene.add(camera)
renderer = new THREE.WebGLRenderer({ antialias: true,alpha: true});
renderer.setSize(container.clientWidth,container.clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.physicallyCorrectLights = true;
canvas = renderer.domElement
container.append(renderer.domElement);
controls = new THREE.OrbitControls(camera,renderer.domElement);
controls.minDistance = 100;
controls.maxDistance = 400;
controls.autoRotate= true;
controls.autoRotateSpeed = 0.5;
controls.enableZoom = false;
initGlobe()
dian();
}
function initGlobe() {
// 地球
var geo = new THREE.SphereGeometry(options.radius, options.segments, options.segments);
var texture = new THREE.TextureLoader().load('https://omo-oss-image.thefastimg.com/portal-saas/ngc202308100003/cms/image/5e61e072-77f8-47dd-aab8-d5986be420b7.png',function(){
renderer.render(scene, camera);
});
texture.minFilter = THREE.LinearFilter;
var material = new THREE.MeshBasicMaterial({
map: texture,
transparent: true,
});
mesh = new THREE.Mesh(geo, material);
// mesh.rotation.y = THREE.MathUtils.degToRad(170);
// mesh.rotation.x = THREE.MathUtils.degToRad(35);
earth.add(mesh)
}
function dian(){
const map = new THREE.TextureLoader().load( 'https://omo-oss-video.thefastvideo.com/portal-saas/ngc202308100003/cms/image/31f0db67-eeec-406e-a145-834c6bd7a48f.png' );
var geometry = new THREE.PlaneBufferGeometry(5, 5);
var material = new THREE.MeshBasicMaterial({
map: map,
transparent: true,
depthWrite:true,
color:0xffffff,
});
markingPos.marking.forEach(function (markingItem) {
ball = new THREE.Mesh(geometry, material);
var coord = getPosition(markingItem.pos[0] + 90, markingItem.pos[1], options.radius);
var coordVec3 = new THREE.Vector3(coord.x, coord.y, coord.z).normalize();
var meshNormal = new THREE.Vector3(0, 0, 1);
markingItem.position = coord;
ball.edit_tit = markingItem.textEdit;
ball.position.set(coord.x, coord.y, coord.z);
ball.quaternion.setFromUnitVectors(meshNormal, coordVec3);
marking.add(ball);
})
earth.add(marking)
scene.add(earth);
}
function onMouseMove( event ) {
// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
mouse.x = ( event.clientX / container.clientWidth ) * 2 - 1;
mouse.y = - ( (event.clientY-container.getBoundingClientRect().top) / (container.clientHeight) ) * 2 + 1;
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = container.clientWidth;
const height = container.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
var INTERSECTED = null;
var renderRequested=false;
function render() {
raycaster.setFromCamera( mouse, camera);
var childArray = []
scene.children[1].children.forEach( function(child){
if(child.type == 'Group'){
childArray = child.children
}
})
const intersects = raycaster.intersectObjects( childArray );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].object ) {
if ( INTERSECTED ) labelParentElem.style.display='none';
INTERSECTED = intersects[ 0 ].object;
tempV.copy(INTERSECTED.position);
tempV.project(camera);
const x = (tempV.x * .5 + .5) * canvas.clientWidth;
const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
labelParentElem.getElementsByTagName("div")[0].innerHTML =INTERSECTED.edit_tit;
labelParentElem.style.display='block'
labelParentElem.style.transform = `translate(${x+40}px,${y-45}px)`;
controls.autoRotate= false;
}
}else{
INTERSECTED = null;
labelParentElem.style.display='none';
controls.autoRotate= true;
}
renderRequested = undefined;
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
}
controls.update()
camera.updateProjectionMatrix();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function requestRenderIfNotRequested(){
if (!renderRequested) {
renderRequested = true;
}
}
controls.addEventListener('change', requestRenderIfNotRequested);
window.addEventListener('resize', requestRenderIfNotRequested);
window.addEventListener( 'mousemove', onMouseMove, false );