问题
渲染出的中国地图没有在坐标中心。
解决方案
使用包围盒获取地图的中心,调整相机的lookAt坐标
创建包围盒
// 地图mapGroup的包围盒计算
var box3 = new THREE.Box3();//创建一个包围盒
// .expandByObject()方法:计算层级模型group包围盒
box3.expandByObject(lineGroup);
// console.log('查看包围盒box3', box3);
//scaleV3表示包围盒长宽高尺寸
var scaleV3 = new THREE.Vector3();
// .getSize()计算包围盒长宽高尺寸
box3.getSize(scaleV3)
// 查看控制台包围盒大小,辅助设置相机参数
console.log('查看包围盒尺寸', scaleV3);
//scaleV3表示包围盒的几何体中心
var center = new THREE.Vector3();
// .getCenter()计算一个层级模型对应包围盒的几何体中心
box3.getCenter(center);
// 查看控制台包围盒集合中心,作为lookAt()参数
console.log('查看几何中心', center);
显示效果
实例代码
<!--渲染中国地图-->
<template>
<div class="homebody">
<div class="canvasGLTFBody">
<div ref='canvasGLTF' class="canvasGLTF">
</div>
</div>
</div>
</template>
<script>
import * as THREE from 'three'
// 引入Three.js扩展库
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { borderArr } from '@/utils/line.js'
import { shapeMesh } from '@/utils/shapeMesh.js'
export default {
name: 'GLTFCanvas',
data () {
return {
list: []
}
},
created: function () {
},
mounted: function () {
var that = this
/**
* 创建场景对象Scene
*/
var scene = new THREE.Scene()
//three.js文件加载类FileLoader:封装了XMLHttpRequest
var loader = new THREE.FileLoader()
loader.setResponseType('json')
// 组对象mapGroup是所有国家边界Line模型的父对象
var mapGroup = new THREE.Group()
var lineGroup = new THREE.Group()
var meshGroup = new THREE.Group()
mapGroup.add(lineGroup)
mapGroup.add(meshGroup)
lineGroup.position.z += 0.1
scene.add(mapGroup)
// 异步加载包含世界各个国家边界坐标的GeoJSON文件:china.json
loader.load('data/china.json', function (data) {
// 访问所有国家边界坐标数据:data.features
data.features.forEach(function (area) {
// "Polygon":国家area有一个封闭轮廓
//"MultiPolygon":国家area有多个封闭轮廓
if (area.geometry.type === 'Polygon') {
// 把"Polygon"和"MultiPolygon"的geometry.coordinates数据结构处理为一致
area.geometry.coordinates = [area.geometry.coordinates]
}
// 解析所有封闭轮廓边界坐标area.geometry.coordinates
lineGroup.add(borderArr(area.geometry.coordinates))//国家边界轮廓插入组对象mapGroup
meshGroup.add(shapeMesh(area.geometry.coordinates))//国家轮廓Mesh插入组对象mapGroup
})
// 地图mapGroup的包围盒计算
var box3 = new THREE.Box3()//创建一个包围盒
// .expandByObject()方法:计算层级模型group包围盒
box3.expandByObject(mapGroup)
// console.log('查看包围盒box3', box3);
//scaleV3表示包围盒长宽高尺寸
var scaleV3 = new THREE.Vector3()
// .getSize()计算包围盒长宽高尺寸
box3.getSize(scaleV3)
// 查看控制台包围盒大小,辅助设置相机参数
console.log('查看包围盒尺寸', scaleV3)
//scaleV3表示包围盒的几何体中心
var center = new THREE.Vector3()
// .getCenter()计算一个层级模型对应包围盒的几何体中心
box3.getCenter(center)
// 查看控制台包围盒集合中心,作为lookAt()参数
console.log('查看几何中心', center)
})
//three.js辅助坐标系
var axesHelper = new THREE.AxesHelper(300)
scene.add(axesHelper)
/**
* 相机设置
*/
var width = window.innerWidth //窗口宽度
var height = window.innerHeight //窗口高度
var k = width / height //窗口宽高比
// var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
var s = 30//缩小渲染渲染范围,地图尽量100%填充canvas画布
//创建相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000)
// camera.position.set(200, 300, 200); //设置相机位置
camera.position.set(104.28225326538086, 35.83740043640137, 200) //沿着z轴观察
camera.lookAt(0, 0, 0) //设置相机方向(指向的场景对象)
/**
* 创建渲染器对象
*/
var renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height) //设置渲染区域尺寸
// renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
// 渲染函数
function render () {
renderer.render(scene, camera) //执行渲染操作
requestAnimationFrame(render) //请求再次执行渲染函数render,渲染下一帧
}
render()
//创建控件对象 控件可以监听鼠标的变化,改变相机对象的属性
// 旋转、缩放用于代码调试
var controls = new OrbitControls(camera, renderer.domElement)
// 相机控件与.lookAt()无效( .target属性 )
controls.target.set(104, 35, 0)
controls.update()
that.$refs.canvasGLTF.appendChild(renderer.domElement)
},
methods: {}
}
</script>
<style lang="scss" scoped>
.homebody {
width: 100%;
height: 100%;
position: fixed;
background: #0f1633;
//position: relative;
.pageMain {
position: relative;
width: calc(100% - 60px - 60px);
margin: 0 auto;
height: calc(100% - 108px - 150px);
}
}
</style>