在地图上指定位置标注四棱锥,之前学习threejs实现4棱锥效果,今天学习将四棱锥标注到的地图上。
在3d地图上标注四棱锥效果实例
创建棱锥
// 引入three.js
import * as THREE from 'three/build/three.module.js';
function ConeMesh(size, x, y) {
var height = size * 4;//棱锥高度
var radius = size;//半径
// ConeBufferGeometry ConeGeometry
// 圆锥体几何体API(ConeGeometry)圆周方向四等分实现四棱锥效果
var geometry = new THREE.ConeGeometry(radius, height, 4);
// 缓冲类型几何体BufferGeometry没有computeFlatVertexNormals方法
geometry.computeFlatVertexNormals();//一种计算顶点法线方式,非光滑渲染
// 可以根据需要旋转到特定角度
// geometry.rotateX(Math.PI);
geometry.rotateX(-Math.PI / 2);
geometry.translate(0, 0, height / 2);
// MeshBasicMaterial MeshLambertMaterial
var material = new THREE.MeshLambertMaterial({
color: 0x00ffff,
});
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set(x, y, 0)
return mesh;
}
export { ConeMesh };
创建棱锥光圈
// 引入three.js
import * as THREE from 'three/build/three.module.js';
import {modelUrl} from "@/config/config.js";
// 矩形平面网格模型设置背景透明的png贴图
var geometry = new THREE.PlaneBufferGeometry(1, 1); //默认在XOY平面上
var textureLoader = new THREE.TextureLoader(); // TextureLoader创建一个纹理加载器对象
var texture = textureLoader.load(modelUrl + 'assets/guangquan.png');
var material = new THREE.MeshBasicMaterial({
map: texture,
transparent: true, //使用背景透明的png贴图,注意开启透明计算
// side: THREE.DoubleSide, //双面可见
});
// 所有矩形平面mesh材质material和几何体geometry可以共享
// size:矩形平面Mesh的尺寸
// x,y表示矩形平面在一个平面上位置坐标
function cityPointMesh2(size, x, y) {
var material = new THREE.MeshBasicMaterial({
color: 0x00ffff,//设置光圈颜色
map: texture,
transparent: true, //使用背景透明的png贴图,注意开启透明计算
// side: THREE.DoubleSide, //双面可见
});
var mesh = new THREE.Mesh(geometry, material);
mesh.scale.set(size,size,size);//设置mesh大小
mesh.position.set(x,y,0);//设置mesh位置
return mesh;
}
export {cityPointMesh2};
渲染代码
// 标注出来省份的行政中心
var pos = [116.365749, 39.911393];//省份行政中心位置经纬度
var size = 2.0;//大小根据地图尺寸范围设置或者说相机渲染范围
// 北京市经纬度
var mesh2 = cityPointMesh2(size, pos[0], pos[1]);
mesh2.position.z = mapHeight + 2.0;//棱锥高度二分之一位置
scene.add(mesh2);
var lengzhui = ConeMesh(1.0, pos[0], pos[1]);
lengzhui.position.z = mapHeight;
scene.add(lengzhui);
// 光圈大小在原大小基础上1~2.5倍在之间变化,也就是mesh.size范围2~5之间
var _s = 2.0;
// 渲染函数
function render() {
lengzhui.rotateZ(0.01);
_s += 0.02;
mesh2.scale.set(_s, _s, _s);
if (_s <= 2.6) {
mesh2.material.opacity = (_s - 2.0) * 1.67;//1.67约等于1/(2.6-2.0),保证透明度在0~1之间变化
} else if (_s > 2.6 && _s <= 5) {
mesh2.material.opacity = 1 - (_s - 2) / 3;//缩放5.0对应0 缩放2.0对应1
} else {
_s = 2.0;
}
renderer.render(scene, camera); //执行渲染操作
requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}