效果:
代码:
<template><div><el-container><el-main><div class="box-card-left"><div id="threejs" style="border: 1px solid red"></div>1. 匀速动画(向量表示速度)</div></el-main></el-container></div>
</template>
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// 效果制作器
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
// 渲染通道
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
// 发光描边OutlinePass
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js";
import {CSS2DObject,CSS2DRenderer,
} from "three/examples/jsm/renderers/CSS2DRenderer.js";
import TWEEN from "@tweenjs/tween.js";
// TextGeometry 是一个附加组件,必须显式导入。 three/examples/jsm/geometries
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';
// FontLoader 是一个附加组件,必须显式导入。
import { FontLoader } from "three/examples/jsm/loaders/FontLoader.js";
export default {data() {return {textGeometry: null,group: null,camera: null,box: null,renderer: null,clock: null,sudu: null,mesh: null,group: null,flag: true};},created() {},mounted() {this.name = this.$route.query.name;this.init();},methods: {goBack() {this.$router.go(-1);},// 1. 匀速动画(向量表示速度)init() {// 创建场景对象this.scene = new this.$three.Scene();const axesHelper = new this.$three.AxesHelper(200);this.scene.add(axesHelper);const ambientLight = new this.$three.AmbientLight(0xffffff, 1);this.scene.add(ambientLight);this.clock = new this.$three.Clock();this.sudu = new this.$three.Vector3(0,0,10);//物体运动速度// 创建文本模型对象/*** TextGeometry(text, parameters)* text: 要显示的文字* parameters: {* font -- THREE.字体* size -- Float.大小* height -- Float.字体厚度, 默认是50* curveSegments — Integer. 曲线上点的数量. 默认值为12.bevelEnabled — Boolean. 是否打开斜面. 默认值为False.bevelThickness — Float. 文本斜面的深度. 默认值为10.bevelSize — Float. 斜面离轮廓的距离. 默认值为8.* * }*/this.box = new this.$three.Box3();const fontLoader = new FontLoader();fontLoader.load("/fonts/Fontquan-XinYiJiXiangSong_Regular.json", font => {const mesh = this.createText(font, 0xFB0606);const mesh2 = this.createText(font,0xF84949);mesh2.rotateX(Math.PI);mesh2.translateY(-this.box.min.y + 10)mesh2.translateZ(-10)this.group = new this.$three.Group();this.group.add(mesh,mesh2);this.scene.add(this.group);this.camera = new this.$three.PerspectiveCamera();this.camera.position.set(0,30,500);this.camera.lookAt(0,0,0);this.renderer = new this.$three.WebGLRenderer();this.renderer.setSize(1000,800);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", e => {this.renderer.render(this.scene, this.camera);})this.loopFun();})},loopFun() {const spt = this.clock.getDelta() * 2;const dis = this.sudu.clone().multiplyScalar(spt);this.group.position.add(dis);this.renderer.render(this.scene, this.camera);requestAnimationFrame(this.loopFun);},createText(font, color) {const textGeometry = new TextGeometry('龙年大吉', { font: font, size:50, height: 10});const material = new this.$three.MeshLambertMaterial({color: color});const mesh = new this.$three.Mesh(textGeometry, material);this.box.expandByObject(mesh);const move_x = (this.box.max.x - this.box.min.x) / 2;mesh.translateX(-move_x)mesh.translateZ(-5)mesh.translateY(-this.box.min.y+ 0)return mesh;}},
};
</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>