<!-- -->
<template>
<div id="threeBox">
<n-spin v-if="loading" size="medium" class="absolute left-1/2 top-1/2" />
</div>
<div class="absolute right-20 z-50 bottom-20">
<div v-for="item in btnGroup" :key="item.name" @click="camreaAnimateTo(item.xyz)">{{ item.name }}</div>
</div>
</template>
<script lang='ts' setup>
import * as THREE from 'THREE'
import TWEEN from '@tweenjs/tween.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
const width = window.innerWidth - 300
const height = window.innerHeight - 104
const loading = ref(false)
const scene = new THREE.Scene()
const btnGroup = [
{
name: '海鲜寿司店',
xyz: {
x: -152, y: -150, z: 350
}
},
{
name: '书店',
xyz: {
x: 102, y: -50, z: 300
}
},
{
name: '我的车',
xyz: {
x: 452, y: 0, z: -150
}
}
]
let mixer: any;
/** 坐标系 */
// const axesHelper = new THREE.AxesHelper(150)
// scene.add(axesHelper) // 坐标系
/** 相机 */
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 10000);
camera.position.z = 100;
/** 灯光 */
const lingt = new THREE.AmbientLight(0xffffff, 2)
scene.add(lingt) // 坐标系
/** 渲染器 */
const renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xBFE3DD, 1)
renderer.setSize(width, height);
/** 解码器 */
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('jsm/gltf/') // 设置public下的解码路径,注意最后面的/
/** 控制器 */
const controls = new OrbitControls(camera, renderer.domElement);
/** 房子 */
const loader = new GLTFLoader()
loader.setDRACOLoader(dracoLoader)
loader.load(
'moudle/LittlestTokyo.glb',
(gltf: any) => {
console.log(gltf)
const model = gltf.scene;
console.log('模型加载完成')
camera.position.setZ(600);
scene.add(model)
mixer = new THREE.AnimationMixer(model);
mixer.clipAction(gltf.animations[0]).play();
animate();
loading.value = false
},
() => {
loading.value = true
console.log('模型加载中')
},
function (error: any) {
console.log('模型加载失败')
loading.value = false
console.error(error);
}
)
// 汽车
loader.load(
'moudle/moskvich_407.glb',
(gltf: any) => {
const model = gltf.scene
model.position.set(300, -200)
model.scale.set(0.45, 0.45, 0.45)
scene.add(model)
loading.value = false
},
() => {
loading.value = true
console.log('模型加载中')
},
function (error: any) {
console.log('模型加载失败')
loading.value = false
console.error(error);
}
)
const clock = new THREE.Clock();
const animate = () => {
requestAnimationFrame(animate);
const delta = clock.getDelta();
mixer.update(delta);
controls.update();
renderer.render(scene, camera);
}
/** 增加鼠标事件 */
const useAddOrbitControls = () => {
//监听鼠标、键盘事件
controls.addEventListener('change', function () {
renderer.render(scene, camera); //执行渲染操作
});
}
const render = () => {
console.log(123)
TWEEN.update();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
/** 右侧鼠标 */
const camreaAnimateTo = (xyz: any) => {
new TWEEN.Tween(camera.position)
.to(xyz, 500)
.onUpdate(function () {
// camera.lookAt(500, 100, 100);
})
.start()
render()
}
onMounted(() => {
useAddOrbitControls() // 增加鼠标事件
renderer.render(scene, camera);
document.getElementById('threeBox')?.appendChild(renderer.domElement);
})
</script>
Three.js模型导入与视角切换
最新推荐文章于 2024-01-09 10:14:03 发布