Vue集成three.js 3D场景渲染示例
Demo工程目录结构如下所示│.browserslistrc│.eslintrc.js│.gitignore│babel.config.js│package-lock.json│package.json│README.md│tsconfig.json│├─public││favicon.ico││index.html│││└─model│agvCar.gltf│house001.
·
- Demo工程目录结构如下所示
│ .browserslistrc
│ .eslintrc.js
│ .gitignore
│ babel.config.js
│ package-lock.json
│ package.json
│ README.md
│ tsconfig.json
│
├─public
│ │ favicon.ico
│ │ index.html
│ │
│ └─model
│ agvCar.gltf
│ house001.glb
│
└─src
│ App.vue
│ main.ts
│ shims-tsx.d.ts
│ shims-vue.d.ts
│
├─assets
│ logo.png
│
├─components
│ HelloWorld.vue
│
├─router
│ index.ts
│
├─store
│ index.ts
│
└─views
About.vue
Home.vue
- 导入threejs库
// 当前版本为 "three": "^0.118.3",
npm i three
HelloWorld.vue
创建并渲染3D场景主要逻辑
<template>
<div style="width:100%;height:100%;text-align:center;">
<div id="threeContent" style="width:1000px;height:800px;margin: 0 auto;"></div>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import {
Scene,
PerspectiveCamera,
Color,
WebGLRenderer,
LinearToneMapping,
AmbientLight,
DirectionalLight,
PointLight,
SpotLight,
Vector3,
} from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; // 控制器
import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; // gltf文件加载
@Component
export default class HelloWorld extends Vue {
@Prop() private msg!: string;
private threeContainer!: HTMLElement;
private scene!: Scene;
private camera!: PerspectiveCamera;
private loader!: GLTFLoader;
private renderer!: WebGLRenderer;
private controls!: OrbitControls;
public created(): void {
setTimeout(() => {
this.initScene();
this.loadModel();
}, 200);
}
public mounted(): void {
this.startAnimation();
}
public initScene() {
this.threeContainer = document.getElementById(
'threeContent'
) as HTMLElement;
this.scene = new Scene();
this.scene.background = new Color(0xccccee);
//环境光 / 平行光
this.scene.add(new AmbientLight(0xffffff, 2.5));
const light = new PointLight(0xdfebff, 1);
this.scene.add(light);
// 相机
this.camera = new PerspectiveCamera(
45,
this.threeContainer.clientWidth / this.threeContainer.clientHeight,
0.1,
2500
);
this.camera.position.copy(new Vector3(-50, 50, 0));
// this.camera.lookAt(new Vector3(100, 0, 100));
this.scene.add(this.camera);
// 渲染器
this.renderer = new WebGLRenderer({ antialias: true, alpha: true });
this.renderer.context.getShaderInfoLog = () => '';
this.renderer.setSize(
this.threeContainer.scrollWidth,
this.threeContainer.scrollHeight
);
this.renderer.setPixelRatio(devicePixelRatio);
this.renderer.toneMapping = LinearToneMapping;
this.renderer.toneMappingExposure = 0.4;
// 相机控件
this.controls = new OrbitControls(
this.camera,
this.renderer.domElement
);
this.controls.minDistance = 10;
this.controls.maxDistance = 400;
// 设置相机的lookAt
this.controls.target.copy(new Vector3(100, 0, 50));
this.threeContainer.appendChild(this.renderer.domElement);
}
public loadModel() {
this.loader = new GLTFLoader();
this.loader.load('/model/house001.glb', (obj: GLTF) => {
this.scene.add(obj.scene);
});
}
public startAnimation() {
const animation = () => {
if (this.renderer) {
this.renderer.render(this.scene, this.camera);
}
if (this.controls) {
this.controls.update();
}
requestAnimationFrame(animation);
};
animation();
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
- 演示效果,如图所示:
更多推荐
已为社区贡献1条内容
所有评论(0)