three.js实现场景方向的左上角小地图
思路
1:创建单独场景
2.添加辅助线
3.添加坐标轴的XYZ文字-使用sprite实现
4.旋转主视图时同步相机位置到小地图。
<template>
? ? <div ref="miniMapContainer" class="mini-map"></div>
</template>
<script>
import * as THREE from 'three';
import createHelper from './createHelper';
export default {
? ? name: 'miniMap',
? ? data() {
? ? ? ? return {
? ? ? ? ? ? width: 100,
? ? ? ? ? ? height: 100,
? ? ? ? ? ? renderer: null,
? ? ? ? ? ? sprites: [],
? ? ? ? ? ? scene: null,
? ? ? ? ? ? camera: null,
? ? ? ? ? ? axesHelper: null
? ? ? ? };
? ? },
? ? mounted() {
? ? ? ? this.initThree();
? ? },
? ? methods: {
? ? ? ? updatePosition(mainCamera) {
? ? ? ? ? ? // 复制主地图的视角
? ? ? ? ? ?
? ? ? ? ? ? this.camera.position.copy(mainCamera.position);
? ? ? ? ? ? // if( this.camera.position.y>0&& this.camera.position.y<35){
? ? ? ? ? ? // ? ? this.camera.position.y=35;
? ? ? ? ? ? // }
? ? ? ? ? ? this.camera.rotation.copy(mainCamera.rotation);
? ? ? ? ? ? this.camera.lookAt(new THREE.Vector3(0, 0, 0));
? ? ? ? },
? ? ? ? initThree() {
? ? ? ? ? ? // 创建渲染器
? ? ? ? ? ? this.renderer = new THREE.WebGLRenderer({ alpha: true });
? ? ? ? ? ? this.renderer.setClearColor(0x000000, 0); // the default ?
? ? ? ? ? ? this.renderer.setSize(this.width, this.height);
? ? ? ? ? ? // this.renderer.setClearColor(0x000000, 0.1);
? ? ? ? ? ? // 将渲染器的dom元素加入Vue组件的容器中
? ? ? ? ? ? this.$refs.miniMapContainer.appendChild(this.renderer.domElement);
? ? ? ? ? ? // 创建场景
? ? ? ? ? ? this.scene = new THREE.Scene();
? ? ? ? ? ? this.scene.background = new THREE.Color(0x002244);
? ? ? ? ? ? // 创建相机
? ? ? ? ? ? // this. camera = new THREE.PerspectiveCamera(70, this. width / ?this.height, 0.01, 10);
? ? ? ? ? ? this.camera = new THREE.OrthographicCamera(
? ? ? ? ? ? ? ? this.width / - 2, this.width / 2, this.height / 2, this.height / - 2, 1, 1000
? ? ? ? ? ? );
? ? ? ? ? ? this.camera.position.z = 5;
? ? ? ? ? ? this.scene.add(this.camera);
? ? ? ? ? ? // 创建XYZ辅助线并加入场景
? ? ? ? ? ? const axesHelper = new THREE.AxesHelper(35);
? ? ? ? ? ? this.scene.add(axesHelper);
? ? ? ? ? ? // 加载一个Sprite材质,Sprite的尺寸、颜色由材质控制
? ? ? ? ? ? const matLite = new THREE.SpriteMaterial({
? ? ? ? ? ? ? ? color: 0xffffff,
? ? ? ? ? ? ? ? transparent: true,
? ? ? ? ? ? ? ? opacity: 0.8
? ? ? ? ? ? });
? ? ? ? ? ? ['X', 'Y', 'Z'].forEach((axis, i) => {
? ? ? ? ? ? ?
? ? ? ? ? ? ? ? const sprite = createHelper.createTextureBySprite({
? ? ? ? ? ? ? ? ? title:axis,
? ? ? ? ? ? ? ? ? textcolor:'#fffefa',
? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ? sprite.position.set(i === 0 ? 35 : 0, i === 1 ? 35 : 0, i === 2 ? 35 : 0);
? ? ? ? ? ? ? ? ?sprite.scale.set(20, 20, 20);
? ? ? ? ? ? ? ? this.sprites.push(sprite);
? ? ? ? ? ? ? ? this.scene.add(sprite);
? ? ? ? ? ? ? ?
? ? ? ? ? ? })
? ? ? ? ? ? // 定义渲染函数
? ? ? ? ? ? const animate = () => {
? ? ? ? ? ? ? ? requestAnimationFrame(animate);
? ? ? ? ? ? ? ? // this.sprites.forEach(sprite => {
? ? ? ? ? ? ? ? // ? ? sprite.lookAt(this.camera.position)
? ? ? ? ? ? ? ? // })
? ? ? ? ? ? ?
? ? ? ? ? ? ? ? this.renderer.render(this.scene, this.camera);
? ? ? ? ? ? };
? ? ? ? ? ? animate(); // 开始渲染
? ? ? ? },
? ? },
};
</script>
<style scoped>
.mini-map {
? ? position: absolute;
? ? top: 0;
? ? left: 0;
? ? opacity: 0.7;
}
</style>