Vite+vue3+ts 结合threejs项目开发

Vite+vue3+ts 结合threejs

代码结构

参考郭隆邦老师的代码结构
项目文件夹test
项目内模块代码必须为.js结尾 此时如果写成.ts 参数导出取不到

test/scene/index.js(初始化场景)

import * as THREE from "three";
import { model } from "./model";
let scene = new THREE.Scene();
/**
 * 添加模型
 */
scene.add(model);
/**
 * 光源设置
 */
// 平行光1
let directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(400, 200, 300);
scene.add(directionalLight);
// 平行光2
let directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight2.position.set(-400, -200, -300);
scene.add(directionalLight2);
//环境光
var ambient = new THREE.AmbientLight(0xffffff, 0.3);
scene.add(ambient);

// Three.js三维坐标轴 三个坐标轴颜色RGB分别对应xyz轴
let axesHelper = new THREE.AxesHelper(250);
scene.add(axesHelper);

export { scene };

test/scene/model,js(加载模型)

import * as THREE from "three";
// 模型组
let model = new THREE.Group();
// 添加正方体模型
let geometry = new THREE.BoxGeometry(50, 50, 50);
let material = new THREE.MeshLambertMaterial({
	color: 0x00ffff,
});
let mesh = new THREE.Mesh(geometry, material);
model.add(mesh);
export { model };

test/RendererCamera.js(初始化渲染器及相机)

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

// width和height用来设置Three.js输出Canvas画布尺寸,同时用来辅助设置相机渲染范围
let width = window.innerWidth; //窗口文档显示区的宽度
let height = window.innerHeight; //窗口文档显示区的高度
/**
 * 透视投影相机设置
 */
// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
let camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(292, 223, 185); //相机在Three.js三维坐标系中的位置
camera.lookAt(0, 0, 0); //相机指向Three.js坐标系原点
/**
 * 创建渲染器对象
 */
let renderer = new THREE.WebGLRenderer({
	antialias: true, //开启锯齿
});
renderer.setPixelRatio(window.devicePixelRatio); //设置设备像素比率,防止Canvas画布输出模糊。
renderer.setSize(width, height); //设置渲染区域尺寸
// renderer.setClearColor(0xffffff, 1); //设置背景颜色

//创建控件对象  控件可以监听鼠标的变化,改变相机对象的属性
let controls = new OrbitControls(camera, renderer.domElement);
controls.mouseButtons = {
	LEFT: THREE.MOUSE.PAN,
	MIDDLE: THREE.MOUSE.DOLLY,
	RIGHT: THREE.MOUSE.ROTATE,
};
//限制最大仰视角和俯视角  controls.minPolarAngle = 0; controls.maxPolarAngle = 1.5;
//禁止缩放 controls.enableZoom=false
//缩放限制 controls.minDistance = 50; controls.maxDistance = 450;
//是否使用键盘 controls.enableKeys = false;
//修改鼠标按键

// onresize 事件会在窗口被调整大小时发生
window.onresize = function () {
	// 重置渲染器输出画布canvas尺寸
	renderer.setSize(window.innerWidth, window.innerHeight);
	// 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
	camera.aspect = window.innerWidth / window.innerHeight;
	// 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
	// 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
	// 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
	camera.updateProjectionMatrix();
};
export { renderer, camera };

test/RenderLoop.js(渲染方法)

import { scene } from "./scene/index";
import { renderer, camera } from "./RendererCamera";
function render() {
	requestAnimationFrame(render);
	renderer.render(scene, camera);
	// console.log(camera.position);
}
render();
export { renderer };

test/index.vue(将渲染结果添加到结果容器内)

<script setup lang="ts">
	import { ref, onMounted } from "vue";
	import { renderer } from "./RenderLoop.js";
	// 场景容器
	const ThreeDom = ref(null);
	onMounted(() => {
		(ThreeDom as any)._value.appendChild(renderer.domElement);
	});
</script>

<template>
	<div id="ThreeContainer" ref="ThreeDom"></div>
</template>

<style scoped lang="less">
	#ThreeContainer {
		width: 100%;
		height: 100%;
	}
</style>

感想

个人觉得 此结构更加清晰 专注于业务逻辑的书写 而不是繁琐的参数传递
渲染效率比将参数赋予vue内的data里存储,再渲染的方式 要高些

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南185

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值