<!DOCTYPE html>
<html lang="en">
<head>
<title>hujiulong - earth</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
color: #808080;
font-family:Monospace;
font-size:13px;
text-align:center;
background-color: #ffffff;
margin: 0px;
overflow: hidden;
}
#container {
width: 100%;
height: 100%;
}
#info {
position: absolute;
width: 100px;
right: 0;
font-size: 14px;
padding-top: 10px;
}
#info > a {
color: #eee;
text-decoration: none;
}
</style>
</head>
<body>
<div id="info">
<a href="https://github.com/hujiulong/echarts-three-earth">hujiulong</a>
</div>
<div id="container"></div>
<script src="./libs/three.min.js"></script>
<script src="./libs/OrbitControls.js"></script>
<script src="./libs/echarts.min.js"></script>
<script src="./data/world.js"></script>
<script src="./data/population.js"></script>
<script>
var camera, controls, scene, renderer;
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var directionalLight;
var earth;
var mapSize = {
width: 4096,
height: 2048
};
var mapCanvas, mapTexture;
init();
animate();
// 初始化echarts地图
function initMap() {
mapCanvas = document.createElement( 'canvas' );
mapCanvas.width = mapSize.width;
mapCanvas.height = mapSize.height;
mapTexture = new THREE.Texture( mapCanvas );
var chart = echarts.init ( mapCanvas );
option = {
visualMap: {
show: false,
min: 0,
max: 1000000,
text:[ 'High', 'Low' ],
realtime: false,
calculable: true,
inRange: {
color: [ 'lightskyblue', 'yellow', 'orangered' ]
}
},
backgroundColor: 'rgb( 255, 255, 255 )',
series: [
{
type: 'map',
mapType: 'world',
roam: true,
aspectScale: 1,
layoutCenter: [ '50%', '50%' ],
layoutSize: 4096,
itemStyle:{
emphasis:{ label: { show: true } }
},
data: population // from population.js
}
]
};
chart.setOption( option );
mapTexture.needsUpdate = true;
// 选中或移出时才更新贴图
// 内存向显存上传数据很慢,应该尽量减少贴图更新
chart.on( 'mouseover', function () {
mapTexture.needsUpdate = true;
} );
chart.on( 'mouseout', function () {
mapTexture.needsUpdate = true;
} );
}
// 初始化three.js场景
function initScene() {
var container = document.getElementById( 'container' );
// 场景
scene = new THREE.Scene();
// 相机
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = -500;
// 渲染器
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0x333333 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
// 控制器
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.dampingFactor = 0.1;
controls.enablePan = false;
controls.rotateSpeed = 0.4;
// 平行光
directionalLight = new THREE.DirectionalLight( 0xffffff, 0.9 );
scene.add( directionalLight );
// 环境光
var light = new THREE.AmbientLight( 0x202020 );
scene.add( light );
// 地球
var earthGeometry = new THREE.SphereBufferGeometry( 200, 36, 36 );
var earthMaterial = new THREE.MeshLambertMaterial( { map: mapTexture, color: 0xffffff } );
earth = new THREE.Mesh( earthGeometry, earthMaterial );
scene.add( earth );
}
function init() {
initMap();
initScene();
window.addEventListener( 'resize', onWindowResize, false );
container.addEventListener( 'mousemove', onMouseMove, false );
}
function onMouseMove( event ) {
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera ); // 通过鼠标坐标和相机位置构造射线
var intersected = raycaster.intersectObject( earth ); // 获取射线和地球的相交点
if ( intersected && intersected.length > 0 ) {
// 根据射线相交点的uv反算出在canvas上的坐标
var x = intersected[ 0 ].uv.x * mapSize.width;
var y = mapSize.height - intersected[ 0 ].uv.y * mapSize.height;
// 在mapCanvas上模拟鼠标事件,这里或许有更好的方法
var virtualEvent = document.createEvent( 'MouseEvents' );
virtualEvent.initMouseEvent( 'mousemove', false, true, document.defaultView, 1, x, y, x, y,false, false, false, false, 0, null );
mapCanvas.dispatchEvent(virtualEvent);
}
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate ); // 循环渲染
controls.update();
render();
}
function render() {
// 平行光始终从相机位置照向地球
directionalLight.position.copy( camera.position )
renderer.render( scene, camera );
}
</script>
</body>
</html>
文件不上传了,有需要可以私聊。 更多可以了解下:https://github.com/ecomfe/echarts-gl 网盘里面存储名字:echarts+threejs+earth
|