一、效果图:
二、实现过程
1、加载json数据和贴图,绘制城市PM.25分布图
var cityInfo = document.getElementById('cityInfo');
//定义一个数组存放坐标点
var points = [];
var shape;
var geometry,material,line;
/**
* 一个精灵模型对象表示一个城市的位置和数据
*/
// 加载一个背景透明的圆形贴图,矩形精灵显示为圆形效果
var texture = new THREE.TextureLoader().load("picture/圆形.png");
// 创建组对象,包含所有精灵对象
let group = new THREE.Group();
// 文件加载对象
var loader = new THREE.FileLoader().setResponseType('json');
// 加载PM2.5数据
loader.load('./json/pmdata.json', function(data) {
//遍历数据
data.forEach(elem => {
// 精灵材质
var spriteMaterial = new THREE.SpriteMaterial({
color:"#1A41E5",
map: texture, //设置精灵纹理贴图
transparent: true,
opacity: 0.8,
});
// 创建精灵模型对象
var sprite = new THREE.Sprite(spriteMaterial);
group.add(sprite);
// 控制精灵大小 使用PM2.5大小设置精灵模型的大小
// 注意适当缩放pm2.5大小,以便得到更好的显示效果
var k = elem.value / 200
sprite.scale.set(k, k, 1);
sprite.name = elem.name;
//获得城市坐标设置精灵模型对象的位置
sprite.position.set(elem.coordinate[0], elem.coordinate[1], 0)
});
// 中国城市坐标整体的几何中心不在坐标原点,需要适当的平移
group.position.set(-110, -30, 0);
scene.add(group);//把精灵群组插入场景中
})
2、显示城市标注
function showCity(name, flag) { //显示当前鼠标移动到的城市名称
if (flag) {
document.getElementById('cityInfo').style.visibility = 'visible';
document.getElementById('cityInfo').innerText = name;
}
else document.getElementById('cityInfo').style.visibility = 'hidden';
}
3、监听鼠标移动事件,鼠标拾取位置更新
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
var eventOffset = {};
function onMouseMove( event ) {
// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
eventOffset.x = event.clientX;
eventOffset.y = event.clientY;
cityInfo.style.left = eventOffset.x + 4 + 'px';
cityInfo.style.top = eventOffset.y + 4 + 'px';
}
4、渲染方法,更新鼠标选中的颜色
function render()
{
// 通过摄像机和鼠标位置更新射线
raycaster.setFromCamera( mouse, camera );
// 计算物体和射线的焦点 true代表包括后代模型
let intersects = raycaster.intersectObjects( scene.children, true );
// console.log(intersects)
if (intersects.length > 0) { //判断鼠标移动到的模型数量
if (currentSprite != intersects && currentSprite) {
for (let i = 0; i < currentSprite.length; i++ )
{
currentSprite[i].object.material.color.set( '#1A41E5' );
}
}
for (let i = 0; i < intersects.length; i++ )
{
intersects[i].object.material.color.set( '#F7AA07' );
}
currentSprite = intersects;
if (!currentSpriteTitle || currentSpriteTitle != currentSprite[0].object.title) { // 判断是否在城市上,和城市名是否改变
currentSpriteTitle = currentSprite[0].object.name;
showCity(currentSpriteTitle, true)
}
}
//更新矩阵,将相机位置更新到正确的位置
// camera.updateMatrixWorld();
update();
renderer.render(scene,camera); //执行渲染操作
requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}
5、初始化对象
<!DOCTYPE html