效果:W 键 前进;S 键后退;A 键左转;D 键右转;使用了 tween.js 动画库;

代码:
- <template>
- <div>
- <el-container>
- <el-main>
- <div class="box-card-left">
- <div id="threejs">div>
- div>
- el-main>
- el-container>
- div>
- template>s
- <script>
- // 引入轨道控制器扩展库OrbitControls.js
- import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
- import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
- import TWEEN from '@tweenjs/tween.js';
- export default {
- data() {
- return {
- scene: null,
- camera: null,
- renderer: null,
- res1: null,
- res2: null,
- clock: null,
- keyState: {
- W: false,
- S: false,
- A: false,
- D: false,
- },
- left_rotation: true, // 向左旋转的标志
- right_rotation: true, // 向右旋转的标志
- VW: new this.$three.Vector3(0, 0, 0),
- VS: new this.$three.Vector3(0, 0, 0),
- curr_v: new this.$three.Vector3(0, 0, 0),
- person: null,
- deltaTime: 0,
- a: 30, // 加速度
- damping: -0.04,
- };
- },
- created() {},
- mounted() {
- this.name = this.$route.query.name;
- this.init();
- },
- methods: {
- goBack() {
- this.$router.go(-1);
- },
- init() {
- this.clock = new this.$three.Clock();
- // 创建场景
- this.scene = new this.$three.Scene();
- // 创建辅助坐标轴对象
- const axesHelper = new this.$three.AxesHelper(100);
- this.scene.add(axesHelper);
- // 创建环境光
-
- const ambientLight = new this.$three.AmbientLight(0xffffff, 10);
- this.scene.add(ambientLight);
- // 创建相机对象
- this.camera = new this.$three.PerspectiveCamera(60,1,0.01,2000);
- this.camera.position.set(10,10,10);
- this.camera.lookAt(0,0,0);
- // 创建渲染器对象
- this.renderer = new this.$three.WebGLRenderer();
- this.renderer.setSize(1500,1200);
- // 创建GLTFLoader对象;加载人物模型
- const gltfLoader = new GLTFLoader();
- gltfLoader.load("models/gltf/person2/scene.gltf", gltf => {
- gltf.scene.position.set(0,0,-10);
- gltf.scene.scale.set(2,2,2);
- this.person = gltf.scene;
- this.scene.add(gltf.scene);
- this.renderer.render(this.scene, this.camera);
- window.document.getElementById("threejs").appendChild(this.renderer.domElement);
- })
- const controls = new OrbitControls(this.camera, this.renderer.domElement);
- controls.addEventListener("change", () => {
- this.renderer.render(this.scene, this.camera);
- })
- this.addEventListenerFn();
- this.renderLoop();
-
- },
- renderLoop() {
- const deltaTime = this.clock.getDelta();
- if(this.keyState.W) {
- if(this.VW.length() < 5) {
- this.VW.add(new this.$three.Vector3(0,0,1).multiplyScalar(this.a * deltaTime));
- this.curr_v = this.VW.clone();
- }
- let pos = this.VW.clone().multiplyScalar(deltaTime);
- this.person.position.add(pos);
- }
-
- if(this.keyState.S) {
- if(this.VS.length() < 5) {
- this.VS.add(new this.$three.Vector3(0,0,-1).multiplyScalar(this.a * deltaTime));
- this.curr_v = this.VS.clone();
- }
- let pos = this.VS.clone().multiplyScalar(deltaTime);
- this.person.position.add(pos);
- }
- if(this.keyState.A) {
- }
- if(this.person) {
- // .addScaledVector ( v : Vector3, s : Float ) : 将所传入的v与s相乘所得的乘积和这个向量相加。
- this.curr_v.addScaledVector(this.curr_v, this.damping);
- let pos = this.curr_v.clone().multiplyScalar(deltaTime);
- this.person.position.add(pos);
- }
- this.renderer.render(this.scene, this.camera);
-
- TWEEN.update();
- requestAnimationFrame(this.renderLoop);
- },
- addEventListenerFn() {
- // 监听按下的 W 键
- document.addEventListener("keydown", e => {
- if(e.code == "KeyW") {
- this.keyState.W = true;
- }
- if(e.code == "KeyS") {
- this.keyState.S = true;
- }
- if(e.code == "KeyA") {
- this.keyState.A = true;
- if(!this.left_rotation)return false;
- const tween0 = new TWEEN.Tween(this.person.rotation);
- let deg = this.$three.MathUtils.radToDeg(this.person.rotation.y);
- let rad = this.$three.MathUtils.degToRad(deg + 90);
-
- if(rad != null) {
- tween0.to({x:0, y: rad, z:0}, 1000);
- tween0.start();
- tween0.onStart(() => {
- this.left_rotation = false;
- });
- tween0.onComplete(() => {
- this.left_rotation = true;
- });
- }
- }
- if(e.code == "KeyD") {
- this.keyState.D = true;
- if(!this.right_rotation)return false;
- const tween0 = new TWEEN.Tween(this.person.rotation);
- let deg = this.$three.MathUtils.radToDeg(this.person.rotation.y);
- let rad = this.$three.MathUtils.degToRad(deg - 90);
-
- if(rad != null) {
- tween0.to({x:0, y: rad, z:0}, 1000);
- tween0.start();
- tween0.onStart(() => {
- this.right_rotation = false;
- });
- tween0.onComplete(() => {
- this.right_rotation = true;
- });
- }
- }
- })
- document.addEventListener("keyup", e => {
- if(e.code == "KeyW") {
- this.keyState.W = false;
- this.VW = new this.$three.Vector3(0, 0, 0);
- }
- if(e.code == "KeyS") {
- this.keyState.S = false;
- this.VS = new this.$three.Vector3(0, 0, 0);
- }
- if(e.code == "KeyA") {
- this.keyState.A = false;
- }
- if(e.code == "KeyD") {
- this.keyState.D = false;
- }
- })
- }
- },
- };
- script>
- <style lang="less" scoped>
- .box-card-left {
- display: flex;
- align-items: flex-start;
- flex-direction: row;
- width: 100%;
- .box-right {
- img {
- width: 500px;
- user-select: none;
- }
- }
- }
- style>