Three.js 地理边界教程

Three.js 地理边界教程 地理边界 ·Geo Border· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么OrbitControls 相机轨道交互CatmullRomCurve3 样条曲线路径requestAnimationFrame渲染循环与resize自适应效果说明本案例演示地理边界效果基于 WebGL 实现「地理边界」可视化效果附完整可运行源码核心用到 OrbitControls、CatmullRomCurve3。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念OrbitControls轨道旋转缩放开enableDamping时每帧需controls.update()。实现步骤搭建 Scene / Camera / Renderer 与 OrbitControlsrAF 循环中 update 并 render代码要点import * as THREE from threeimport { OrbitControls } from three/examples/jsm/controls/OrbitControls.jsconst box document.getElementById(box)const scene new THREE.Scene()const camera new THREE.PerspectiveCamera(75, box.clientWidth / box.clientHeight, 0.1, 1000)camera.position.set(0, 0, 500)const renderer new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })renderer.setSize(box.clientWidth, box.clientHeight)box.appendChild(renderer.domElement)const controls new OrbitControls(camera, renderer.domElement)controls.enableDamping truescene.add(new THREE.AmbientLight(0xffffff, 1))const directionalLight new THREE.DirectionalLight(0xffffff, 2)directionalLight.position.set(300, 300, 300)scene.add(directionalLight)const map new THREE.TextureLoader().load(FILE_HOST images/channels/lmap.png)map.wrapS THREE.RepeatWrappingmap.wrapT THREE.RepeatWrappingmap.needsUpdate trueanimate()function animate() {requestAnimationFrame(animate)map.offset.x 0.001controls.update()renderer.render(scene, camera)}window.onresize () {renderer.setSize(box.clientWidth, box.clientHeight)camera.aspect box.clientWidth / box.clientHeightcamera.updateProjectionMatrix()}/边界/ const group new THREE.Group()fetch(FILE_HOST files/json/chinaBound.json).then(r r.json()).then(res {const { features } resfeatures.forEach((i) {if (i.geometry.type MultiPolygon) i.geometry.coordinates.forEach((j) j.forEach((z) createShapeWithCoord(group, z)))else if (i.geometry.type Polygon) i.geometry.coordinates.forEach((j) createShapeWithCoord(group, j))else if (i.geometry.type LineString) i.geometry.coordinates.length 1 createShapeWithCoord(group, i.geometry.coordinates)})translationOriginForGroup(group)scene.add(group)})function createShapeWithCoord(group, coordinates) { if (coordinates.length 1000) return // 设置点数限制 如果点太少则不绘制const curvePoints coordinates.map((k) coordToVector3(k))const curve new THREE.CatmullRomCurve3(curvePoints)const geometry new THREE.TubeGeometry(curve, curvePoints.length - 1, 1, 40, false)const material new THREE.MeshPhongMaterial({ color: 0xffffff , map , transparent: true })const mesh new THREE.Mesh(geometry, material)translationOriginForMesh(mesh)group.attach(mesh)}function coordToVector3(coord, slace 10000) {const [lng, lat] coordconst x lng * 20037508.34 / 180const y Math.log(Math.tan((90 lat)Math.PI / 360)) / (Math.PI / 180)20037508.34 / 180return new THREE.Vector3(x / slace, y / slace, 0)}function translationOriginForMesh(mesh) { const boundingBox new THREE.Box3().setFromObject(mesh)boundingBox.getCenter(mesh.position)mesh.geometry.center()}// 设置组中心点 function translationOriginForGroup(group) {const boundingBox new THREE.Box3().setFromObject(group)boundingBox.getCenter(group.position)group.traverse((c) {c.isMesh c.position.sub(group.position)})group.position.set(0, 0, 0)}完整源码GitHub小结本文提供地理边界完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库