1、在vue文件导入GLTFLoader.js
2、初始化loader
需要注意的点:
文件必须放在public下面,否则会报unexpected token < in json at position 0错误。
路径是'models/gltf/Duck/glTF/Duck.gltf',前面不用再加public了。
不要用function而要用=>,否则this指向会乱。
用一个全局变量把导入的模型保存起来,以便其他地方调用。
mounted里先导入模型,然后再执行动画,在动画方法里调用了导入方法里的this.model变量,会产生异步数据问题,也就是说this.model在动画里变成了一个未初始化的变量了,所以,再动画方法里,需要延迟一点点再调用this.model,用settimeout就可以了。
代码:
<template>
<div>
<!-- 本案例演示导入模型 -->
<div id="container"></div>
</div>
</template>
<script>
import * as THREE from 'three'
// 注意OrbitControls要加{},注意路径是jsm
import {
OrbitControls
} from 'three/examples/jsm/controls/OrbitControls.js'
// dat gui这个插件,是另外自己下载的,threejs的安装包里没有这个
// dat gui组件能够方便地改变某些值,并快速预览这些值的改变所产生的变化
import {
dat
} from 'three/examples/jsm/controls/dat.gui.js'
import {
GLTFLoader
} from 'three/examples/jsm/loaders/GLTFLoader.js'
export default {
name: "hello",
props: {
},
components: {
},
data() {
return {
scene: null,
renderer: null,
camera: null,
orbitControls: null,
model:null
}
},
created() {},
mounted() {
this.init();
this.loadModel();
this.animate();
},
//后续还要在beforeDestory中进行销毁
beforeDestroy() {
this.scene = null;
this.renderer = null;
this.camera = null;
this.orbitControls = null;
this.model = null;
},
methods: {
init() {
let container = document.getElementById('container');
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 特别注意,相机的位置要大于几何体的尺寸
this.camera.position.z = -10;
this.scene = new THREE.Scene();
this.renderer = new THREE.WebGLRenderer({
// 抗锯齿性
antialias: true
});
// 设置背景色
this.renderer.setClearColor('#428bca',1.0);
this.renderer.setSize(window.innerWidth,window.innerHeight);
container.appendChild(this.renderer.domElement);
// 环境光不能用来投射阴影,因为它没有方向。
var ambienLight = new THREE.AmbientLight(0xcccccc);
this.scene.add(ambienLight);
// 初始化轨道控制器
// 还需要配合animate,不断循环渲染,达到用鼠标旋转物体的作用。
this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);
// 窗口大小自适应
window.addEventListener('resize',this.onWindowResize,false);
},
animate() {
setTimeout(()=>{
this.model.rotation.x += 0.01;
this.model.rotation.y += 0.01;
this.model.rotation.z += 0.01;
},500)
requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera);
},
onWindowResize(){
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth,window.innerHeight);
},
loadModel(){
var loader = new GLTFLoader();
// 路径要特别注意,默认是从public读取的,模型文件必须放在public下,并且路径前的public要省略
loader.load( 'models/gltf/Duck/glTF/Duck.gltf', gltf=> {
// 设置模型尺寸
this.model = gltf.scene;
this.model.scale.set(5,5,5);
this.model.position.y = -5;
this.scene.add(this.model);
}, undefined, error=>{
console.error( error );
} );
}
}
}
</script>
<style scoped>
#container {
height: 500px;
}
</style>
最终效果: