uniapp在手机端预览glb文件

javascript 复制代码
<template>
	<view class="content">
		<view id="threeView"></view>
		<!-- #ifdef APP-PLUS || H5 -->
		<view id="three" class="three" @click="three.onClick"></view>
		<!-- #endif -->
		<!-- #ifndef APP-PLUS || H5 -->
		<view>非 APP、H5 环境不支持</view>
		<!-- #endif -->
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			};
		},
	};
</script>

<script module="three" lang="renderjs">
	const THREE = require('static/three/build/three.min.js')
	import {
		OrbitControls
	} from 'static/three/examples/jsm/controls/OrbitControls.js'
	import {
		GLTFLoader
	} from 'static/three/examples/jsm/loaders/GLTFLoader.js'
	import {
		RGBELoader
	} from 'static/three/examples/jsm/loaders/RGBELoader.js';
	const ThreeBSP = require('static/three/build/ThreeBSP.js')(THREE)
	var renderer;
	var scene, GLTFloader;
	var camera;
	var controls;
	let pmremGenerator, envMap;
	let renderEnabled = false;
	let timeOut = null;
	export default {
		mounted() {
			this.initThree();
		},
		methods: {

			initThree() {
				let that = this
				// 如果返回的不是未定义,说明threejs成功引入
				console.log('打印场景API', THREE.Scene);
				/* 创建场景对象Scene */
				scene = new THREE.Scene();
				/*
				    相机设置
				 */
				var width = window.innerWidth; // 窗口宽度
				var height = window.innerHeight; // 高度
				camera = new THREE.PerspectiveCamera(20, width / height, 0.1, 10000);
				camera.position.set(0, 30, 100);
				scene.add(camera);
				/*
				    创建渲染器对象
				 */
				const element = document.getElementById('threeView')
				renderer = new THREE.WebGLRenderer({
					antialias: true,
					alpha: true
				});
				renderer.physicallyCorrectLights = true;
				renderer.outputEncoding = THREE.sRGBEncoding;
				renderer.setPixelRatio(window.devicePixelRatio);
				renderer.setSize(window.innerWidth, window.innerHeight);
				pmremGenerator = new THREE.PMREMGenerator(renderer);
				pmremGenerator.compileEquirectangularShader();
				element.appendChild(renderer.domElement); // body元素中插入canvas对象
				/*
				    光源设置
				 */
				// 半球光
				const hemiLight = new THREE.HemisphereLight();
				hemiLight.intensity = 0.3
				scene.add(hemiLight);
				// 环境光
				const ambientLight = new THREE.AmbientLight(0xffffff, 1);
				scene.add(ambientLight);
				//平行光
				const light = new THREE.DirectionalLight(0xffffff, 0.3);
				light.position.set(-10, -1, 100);
				scene.add(light);
				/*
				    控制器
				 */
				controls = new OrbitControls(camera, renderer.domElement);
				controls.enablePan = false; //滑动
				controls.enableDamping = true;
				controls.dampingFactor = 0.05;
				controls.screenSpacePanning = false;
				controls.autoRotate = true; //场景自动旋转
				controls.autoRotateSpeed = 5; //旋转的速度
				// controls.minDistance = 60;
				// controls.maxDistance = 100;
				controls.maxPolarAngle = Math.PI / 2; //2.8 1.8 Math.PI / 1
				// controls.minPolarAngle = Math.PI /2;//相同的角度禁止垂直旋转
				controls.addEventListener('change', function() {
					that.timeRender();
				});
				/*
				    环境纹理
				 */
				this.getfile("./static/images/venice_sunset_1k.hdr").then(res => {
					new RGBELoader()
						.setDataType(THREE.UnsignedByteType)
						.load(res, (texture) => {

							envMap = pmremGenerator.fromEquirectangular(texture).texture;
							pmremGenerator.dispose();
							scene.environment = envMap;
							// scene.background = envMap;
						}, );
				})
				/*
				    模型导入http://qiniu.3fwallet.com/Aries.glb
					./static/Soldier.glb
					可使用网络路径或者本地路径
				 */
				that.animate();
				GLTFloader = new GLTFLoader();
				this.getfile("http://tm.imtmeta.com:8091/profile/model/喷雾泵/喷雾泵/喷雾泵.glb").then(res => {
					GLTFloader.load(res, function(gltf) {
						const model1 = gltf.scene;
						model1.position.set(0, 0, 0);
						model1.scale.set(5, 5, 5);
						model1.name = 'model1';
						scene.add(model1);
						that.timeRender();
					}, undefined, function(e) {
						console.error(e);
					});
				})
				// 执行渲染操作,指定场景,相机作为参数
				renderer.render(scene, camera);
				console.log(1);
			},
			/*
				读取文件
			    在ios端会存在文件读取不到的问题,可以使用plus5+的方法读取到需要的文件
				如果不考虑ios端,可以不使用这个方法
			 */
			getfile(e) {
				// #ifdef APP-PLUS
				let url = plus.io.convertLocalFileSystemURL(e)
				return new Promise((resolve, reject) => {
					plus.io.resolveLocalFileSystemURL(url, entry => {
						var reader = null;
						entry.file(file => {
							reader = new plus.io.FileReader();
							reader.onloadend = (read) => {
								resolve(read.target.result)
							};
							reader.readAsDataURL(file);
						}, function(error) {
							alert(error.message);
						});
					}, err => {
						resolve(e)
					})
				})
				// #endif
				// #ifndef APP-PLUS
				return new Promise((resolve, reject) => {
					resolve(e)
				})
				// #endif
			},
			animate() {
				if (renderEnabled) {
					controls.update();
					this.render();
				}
				requestAnimationFrame(() => {
					this.animate()
				});
			},
			// 动画
			render() {
				renderer.render(scene, camera); //执行渲染操作
			},
			/*
				渲染判断
			    在没有动画的情况下,可以在有需要的时候渲染,提高性能
			 */
			timeRender() {
				//设置为可渲染状态
				renderEnabled = true;
				//清除上次的延迟器
				if (timeOut) {
					clearTimeout(timeOut);
				}
				//开启动画时需要一直渲染,不能暂停渲染操作
				// timeOut = setTimeout(function () {
				//     renderEnabled = false;
				// }, 3000);
			},
		}
	}
</script>

<style>
	.content {
		margin: 0;
	}

	.three {
		width: 100%;
	}

	#threeView {
		width: 100%;
		height: 60vh;
	}
</style>

npm install three下载three,把node_modules里的three文件里的内容移入到了static,然后按照threejs写法来展示3d模型

相关推荐
腾讯TNTWeb前端团队11 分钟前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom5 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom5 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom5 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom5 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试