当前位置:网站首页>three. JS tag and pop-up the earth
three. JS tag and pop-up the earth
2022-07-26 20:10:00 【Rookie post station 2020】
design sketch :
Pay attention to the point :
Attributes should be given when creating wizard tags Name assignment , So that the current value can be obtained when the mouse clicks .


Complete code :
<!DOCTYPE html>
<html>
<head>
<title>Threejs Realize drawing the earth , Geographical location annotation </title>
<meta charset="UTF-8">
<script type="text/javascript" src="js/three.js"></script>
<script type="text/javascript" src="js/OrbitControls.js"></script>
<script type="text/javascript" src="js/makeTextSprite.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="dom"></div>
<script type="text/javascript">
// Define global variables
var scene, camera, renderer ;
var radius = 100; // Earth radius
var areas = [{
name: " China ",
position: [116.20, 39.55]
}, {
name: " Central African Republic ",
position: [18.35, 4.23]
}, {
name: " Chile ",
position: [-70.40, -33.24]
}, {
name: " Chad ",
position: [14.59, 12.10]
}, {
name: " Zambia ",
position: [28.16, -15.28]
}, {
name: " Vietnam ",
position: [105.55, 21.05]
}, {
name: " Jordan ",
position: [35.52, 31.57]
}, {
name: " Virgin Islands ",
position: [-64.37, 18.27]
}, {
name: " The British ",
position: [-0.05, 51.36]
}];
// initialization
function init() {
// Create a scene , It will contain all our elements , Like an object , Cameras and lights .
scene = new THREE.Scene();
// The ambient light ( Color , brightness )
var ambientLight = new THREE.AmbientLight("#ffffff", 1.2);
scene.add(ambientLight);
// Create a camera , It defines where we are looking
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// Aim the camera at the center of the scene
camera.position.set(0, 100, -400);
camera.lookAt(scene.position);
// Create a renderer and set the size ,WebGLRenderer The computer graphics card will be used to render the scene
renderer = new THREE.WebGLRenderer({
antialias: true, // Whether anti aliasing is performed
logarithmicDepthBuffer: false, // If you want to deal with large scale differences in a single scene , It is necessary to use . Use... Here false, Otherwise, the text label will not display
});
renderer.setSize(window.innerWidth, window.innerHeight);
// renderer.setClearColor(0x000000, 1); // Set the background color
// Setting the background
var texture = new THREE.TextureLoader().load('imges/back.jpg');
scene.background = texture;
// Show axis
var axes = new THREE.AxisHelper(radius);
scene.add(axes);
// Track controller
var controls = new THREE.OrbitControls(camera);
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 1; // Flip up and down 0-max degree
controls.minDistance = 120; // Set the shortest distance to move ( Default to zero )
controls.maxDistance = 1000; // Set the maximum distance to move ( The default is infinite )
controls.update(); // When the camera rotates , The controller must be updated
// Add content to HTML page
document.getElementById("dom").appendChild(renderer.domElement);
// Operation function
createEarth();
createAreaPoint();
renderScene();
// Create the earth radius 100
function createEarth() {
var earthGeo = new THREE.SphereGeometry(radius, 50, 50);
earthGeo.name = ' The earth '
var earthMater = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('imges/earth.jpg'),
// Transparent sphere
// transparent: true,
// depthWrite: false,
// side: THREE.DoubleSide,
// blending: THREE.AdditiveBlending,
// opacity: 0.8,
// color: 0x03d98e
});
var earthMesh = new THREE.Mesh(earthGeo, earthMater);
scene.add(earthMesh);
}
// Create a label
function createAreaPoint() {
// Loop to create labels
for (let i = 0, length = areas.length; i < length; i++) {
let name = areas[i].name
let position = createPosition(areas[i].position)
createTxt(position,name); // Sprite tag function
}
}
// Longitude and latitude to coordinate
function createPosition(lnglat) {
let spherical = new THREE.Spherical
spherical.radius = radius;
let lng = lnglat[0]
let lat = lnglat[1]
let theta = (lng + 90) * (Math.PI / 180)
let phi = (90 - lat) * (Math.PI / 180)
spherical.phi = phi; // phi It's the azimuth ( level ) The angle inside , Range 0~360 degree
spherical.theta = theta; // theta It's the pitch plane ( Vertical plane ) The angle inside , Range 0~180 degree
let position = new THREE.Vector3()
position.setFromSpherical(spherical)
return position
}
// Elf tag -- The label is always facing the camera
function createTxt(position,name){
let texture = new THREE.TextureLoader().load('imges/tip.png');
let material = new THREE.SpriteMaterial({
map: texture });
let spriteMesh = new THREE.Sprite(material);
/*** Set up mesh Of name attribute , It is used to click the label with the mouse to pop up the corresponding name ***/
spriteMesh.name = name;
// Zoom in
spriteMesh.scale.x = 4;
spriteMesh.scale.y = 4;
// spriteMesh.position.copy(position); // Original location
// Add at the original position 1px , Avoid overlapping icons with the earth
spriteMesh.position.x = (position.x >0 ? position.x+1 : position.x-1);
spriteMesh.position.y = (position.y >0 ? position.y+1 : position.y-1);
spriteMesh.position.z = (position.z >0 ? position.z+1 : position.z-1);
spriteMesh.lookAt(new THREE.Vector3(0, 0,0));
scene.add(spriteMesh);
}
// Rendering
function renderScene() {
requestAnimationFrame(renderScene); // Cycle call renderScene function
renderer.render(scene, camera);
}
}
// Click on the marked event
function clickMouse(event) {
event.preventDefault();
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector2();
// Click the location with the mouse , To calculate the raycaster Point location , Focus on the screen , Range -1 To 1
let getBoundingClientRect = dom.getBoundingClientRect();
mouse.x = ((event.clientX - getBoundingClientRect.left) / dom.offsetWidth) * 2 - 1;
mouse.y = -((event.clientY - getBoundingClientRect.top) / dom.offsetHeight) * 2 + 1;
// Location by mouse click ( Two dimensional coordinates ) And the matrix of the current camera
raycaster.setFromCamera(mouse, camera);
// Gets the array of objects that intersect the ray , The elements are sorted by distance , The closer it is, the more forward it is
let intersects = raycaster.intersectObjects(scene.children);
deleteDiv(); // Call the clear popup function
// Get the value of the clicked object
for (let i = 0; i < intersects.length; i++) {
if (intersects[i].object.type == 'Sprite') {
let countryName = intersects[i].object.name; // Country
let V3 = intersects[i].object.position ; // Three dimensional coordinates
if(countryName !=''){
divPop(countryName, V3); // Call the popup function
}
}
}
// Pop up content and style
function divPop(countryName, V3){
let rs = WorldToScreen(V3.x, V3.y, V3.z); // Call the world coordinate to screen coordinate function
let div = document.createElement("divCell"); // Create a div
div.id = "divCell"; // Set up ID
div.innerHTML = countryName; //div The content of
div.style.padding = '5px';
div.style.position = 'absolute';
div.style.backgroundColor = 'rgba(255, 255, 255, 0.8)';
div.style.left = rs.x + "px";
div.style.top = rs.y + "px";
document.body.appendChild(div); // Add to page
}
// Clear Popup
function deleteDiv(){
// If there were “divCell” This layer , Delete this layer first
let d = document.getElementById("divCell");
if (d != null){
d.parentNode.removeChild(d);
}
}
// World coordinates to screen coordinates
function WorldToScreen(x, y, z) {
let worldVector = new THREE.Vector3(x, y, z);
let vector = worldVector.project(camera); // World coordinates to standard equipment coordinates
let w = window.innerWidth / 2;
let h = window.innerHeight / 2;
return {
x: Math.round(vector.x * w + w),
y: Math.round(-vector.y * h + h)
}
}
}
// Modify the scene size as the form changes
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// Listen for form resizing events
window.addEventListener('resize', onResize, false);
// Listening to mouse events
window.addEventListener('click', clickMouse, false);
// Load the page after drawing , Avoid page flashing
window.onload = function() {
init();
}
</script>
</body>
</html>
边栏推荐
- 高瓴加入的PRI,君联、华控、盛世、绿动等百家机构都杀进去了
- 一文读懂 .NET 中的高性能队列 Channel
- C # use the default transformation method
- 金仓数据库 KingbaseES SQL 语言参考手册 (12. SQL语句:ALTER LANGUAGE 到 ALTER SUBSCRIPTION)
- 徽商期货开户安全吗?请问徽商期货开户应该注意什么呢?
- numpy.zeros_like
- 金仓数据库 KingbaseES SQL 语言参考手册 (21. KES正则表达式支持)
- Excel-VBA 快速上手(十一、字符串常用操作)
- 事务回滚,同时记录异常信息
- 京东荣获中国智能科学技术最高奖!盘点京东体系智能技术
猜你喜欢
随机推荐
go+mysql+redis+vue3简单聊室,第5弹:使用消息队列和定时任务同步消息到mysql
金仓数据库 KingbaseES SQL 语言参考手册 (13. SQL语句:ALTER SYNONYM 到 COMMENT)
eadiness probe failed: calico/node is not ready: BIRD is not ready: Error querying BIRD: unable to c
How to wait for the return results of multiple asynchronous tasks synchronously?
DOM case: 10 second countdown - write jump page related knowledge
Leetcode daily practice - 27. Remove elements
Kingbases SQL language reference manual of Jincang database (15. SQL statement: create materialized view to create schema)
【MySQL】 - 索引原理与使用
Dio问题总结
Codeforces Round #810 (Div. 2)(A~C)
C#将PDF文件转成图片
猎聘问卷星,成为微信「寄生虫」
【shell】转载:批量替换 find awk sed xargs
Ten sorting details
Student‘s t分布
3万脱发人,撑起一个IPO
金融机构盘点
一文读懂 .NET 中的高性能队列 Channel
2022年下半年(软考高级)信息系统项目管理师报名条件
I tried many report tools and finally found a report based on Net 6








