当前位置:   article > 正文

uniapp小程序展示3D模型_uniapp 3d模型展示

uniapp 3d模型展示

小程序展示3D模型-使用three.js 进行渲染

在开发的期间查阅了大量的资料、案例,大多都是无稽之谈…经过摸索…终于开发出来了适合本项目的3D模型案例
为了帮助有需要的同学 少走弯路 特地记录了一下哦

在开发期间 也找到了 较好的微信端3d模型渲染 有需要的可以留言

效果如图所示:(进行了配置,这里也加了手势滑动,自动旋转 3d的类型是obj格式)

在这里插入图片描述

配置项目需要的依赖

安装依赖
npm i

npm i dhtml-weixin
npm i three-weixin

小程序开发工具顶部菜单->工具->构建npm (如果有效果也可以不构建)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

html

<template>
	<view class="three_3d">
		<canvas disable-scroll="true" @touchcancel="webgl_touch" @touchend="webgl_touch" @touchmove="webgl_touch"
			@touchstart="webgl_touch" id="canvas_webgl" canvas-id="canvas_webgl" type="webgl"
			style="width:750rpx;height:800rpx;"></canvas>
	</view>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

项目依赖

	import {
		document,
		window,
		requestAnimationFrame,
		cancelAnimationFrame,
		Event
	} from 'dhtml-weixin';
	import * as THREE from 'three-weixin';
	// import Stats from '../../jsm/libs/stats.module.js';
	// import {
	// 	GUI
	// } from '../../jsm/libs/lil-gui.module.min.js';
	import {
		OrbitControls
	} from '../../jsm/controls/OrbitControls.js';
	import {
		OBJLoader
	} from '../../jsm/loaders/OBJLoader.js';

	var renderer;
	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

js

<script>
	export default {
		name: "threeA",
		data() {
			return {
				// renderer: null


			};
		},
		methods: {
			beforeDestroy() {
				getApp().worker && getApp().worker.terminate()

				cancelAnimationFrame()
				if (this.renderer) {
					this.renderer.dispose()
					this.renderer.forceContextLoss()
					this.renderer.context = null
					this.renderer.domElement = null
					this.renderer = null
				}
			},

			webgl_touch(e) {
				const web_e = Event.fix(e)
				document.dispatchEvent(web_e)
				window.dispatchEvent(web_e)
				this.renderer && this.renderer.dispatchEvent(web_e)
			},
		},
		async onLoad() {
			getApp().canvas = await document.createElementAsync("canvas", "webgl");
			renderer = new THREE.WebGLRenderer({
				antialias: true
			});
		},

		async mounted() {
			// 模型加载需要时间  添加提示 3秒钟后关闭提示正好数据加载出来
			uni.showLoading({
				title: '加载中',
				duration: 3000
			});

			var that = this;
			getApp().canvas = await document.createElementAsync("canvas", "webgl", this);
			let container;

			let camera, scene, renderer, stats;

			let mouseX = 0,
				mouseY = 0;

			let windowHalfX = window.innerWidth / 2;
			let windowHalfY = window.innerHeight / 2;

			let object;

			init();
			animate();


			function init() {

				container = document.createElement('div');
				document.body.appendChild(container);

				camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 2000);
				camera.position.z = 250;

				// scene

				scene = new THREE.Scene();

				const ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
				scene.add(ambientLight);

				const pointLight = new THREE.PointLight(0xffffff, 0.8);
				camera.add(pointLight);
				scene.add(camera);

				// manager

				function loadModel() {

					object.traverse(function(child) {

						//	if ( child.isMesh ) child.material.map = texture;

					});

					object.position.y = -50;
					scene.add(object);

				}

				const manager = new THREE.LoadingManager(loadModel);

				// texture

				const textureLoader = new THREE.TextureLoader(manager);
				//	const texture = textureLoader.load( 'http://localhost:8080/examples/textures/uv_grid_opengl.jpg' );

				// model

				function onProgress(xhr) {

					if (xhr.lengthComputable) {

						const percentComplete = xhr.loaded / xhr.total * 100;
						console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');

					}

				}

				function onError() {}

				const loader = new OBJLoader(manager);
				loader.load('http://youkejingpin.oss-cn-beijing.aliyuncs.com/Digital/static/pic/product/toukui.obj',
					function(obj) {

						object = obj;

					}, onProgress, onError);

				//原始事件
				// renderer = that.renderer = new THREE.WebGLRenderer();
				// renderer.setPixelRatio(window.devicePixelRatio);
				// renderer.setSize(window.innerWidth, window.innerHeight);
				// container.appendChild(renderer.domElement);

				// document.addEventListener('mousemove', onDocumentMouseMove);
				// window.addEventListener('resize', onWindowResize);
				// 鼠标点击事件
				renderer = that.renderer = new THREE.WebGLRenderer({
					antialias: true
				});
				renderer.setPixelRatio(window.devicePixelRatio);
				renderer.setSize(window.innerWidth, window.innerHeight);
				renderer.outputEncoding = THREE.sRGBEncoding;
				renderer.shadowMap.enabled = true;
				container.appendChild(renderer.domElement);

				//控制模型触动事件
				camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 2000);
				camera.position.set(160, 40, 160);

				const controls = new OrbitControls(camera, renderer.domElement);
				controls.enablePan = false;
				controls.enableZoom = true;
				controls.target.set(0, 1, 0);
				controls.update();

				// stats = new Stats();
				// container.appendChild(stats.dom);
				window.addEventListener('resize', onWindowResize);


			}

			function onWindowResize() {

				windowHalfX = window.innerWidth / 2;
				windowHalfY = window.innerHeight / 2;

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize(window.innerWidth, window.innerHeight);

			}

			function onDocumentMouseMove(event) {

				mouseX = (event.clientX - windowHalfX) / 2;
				mouseY = (event.clientY - windowHalfY) / 2;

			}

			//

			function animate() {

				requestAnimationFrame(animate);
				render();

			}

			function render() {

				//camera.position.x += ( mouseX - camera.position.x ) * .05;
				// mera.position.y += ( - mouseY - camera.position.y ) * .05;
				// mera.lookAt( scene.position );
				renderer.render(scene, camera);

				//	console.error(new Date().getTime())
				if (object) {
					object.rotation.set(0, object.rotation.y + 0.007, 0)
				}


			}

		}
	}
</script>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209

整体代码可直接使用(js+html)

<!-- 模型地址线上地址
http://youkejingpin.oss-cn-beijing.aliyuncs.com/Digital/static/pic/product/toukui.obj
 -->
<template>
	<view class="three_3d">
		<canvas disable-scroll="true" @touchcancel="webgl_touch" @touchend="webgl_touch" @touchmove="webgl_touch"
			@touchstart="webgl_touch" id="canvas_webgl" canvas-id="canvas_webgl" type="webgl"
			style="width:750rpx;height:800rpx;"></canvas>
	</view>
</template>
<script>
	import {
		document,
		window,
		requestAnimationFrame,
		cancelAnimationFrame,
		Event
	} from 'dhtml-weixin';
	import * as THREE from 'three-weixin';
	import {
		OrbitControls
	} from '../../jsm/controls/OrbitControls.js';
	import {
		OBJLoader
	} from '../../jsm/loaders/OBJLoader.js';

	var renderer;
	
	export default {
		name: "threeA",
		data() {
			return {
				// renderer: null


			};
		},
		methods: {
			beforeDestroy() {
				getApp().worker && getApp().worker.terminate()

				cancelAnimationFrame()
				if (this.renderer) {
					this.renderer.dispose()
					this.renderer.forceContextLoss()
					this.renderer.context = null
					this.renderer.domElement = null
					this.renderer = null
				}
			},

			webgl_touch(e) {
				const web_e = Event.fix(e)
				document.dispatchEvent(web_e)
				window.dispatchEvent(web_e)
				this.renderer && this.renderer.dispatchEvent(web_e)
			},
		},
		async onLoad() {
			getApp().canvas = await document.createElementAsync("canvas", "webgl");
			renderer = new THREE.WebGLRenderer({
				antialias: true
			});
		},

		async mounted() {
			// 模型加载需要时间  添加提示 3秒钟后关闭提示正好数据加载出来
			uni.showLoading({
				title: '加载中',
				duration: 3000
			});

			var that = this;
			getApp().canvas = await document.createElementAsync("canvas", "webgl", this);
			let container;

			let camera, scene, renderer, stats;

			let mouseX = 0,
				mouseY = 0;

			let windowHalfX = window.innerWidth / 2;
			let windowHalfY = window.innerHeight / 2;

			let object;

			init();
			animate();


			function init() {

				container = document.createElement('div');
				document.body.appendChild(container);

				camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 2000);
				camera.position.z = 250;

				// scene

				scene = new THREE.Scene();

				const ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
				scene.add(ambientLight);

				const pointLight = new THREE.PointLight(0xffffff, 0.8);
				camera.add(pointLight);
				scene.add(camera);

				// manager

				function loadModel() {

					object.traverse(function(child) {

						//	if ( child.isMesh ) child.material.map = texture;

					});

					object.position.y = -50;
					scene.add(object);

				}

				const manager = new THREE.LoadingManager(loadModel);

				// texture

				const textureLoader = new THREE.TextureLoader(manager);
				//	const texture = textureLoader.load( 'http://localhost:8080/examples/textures/uv_grid_opengl.jpg' );

				// model

				function onProgress(xhr) {

					if (xhr.lengthComputable) {

						const percentComplete = xhr.loaded / xhr.total * 100;
						console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');

					}

				}

				function onError() {}

				const loader = new OBJLoader(manager);
				loader.load('http://youkejingpin.oss-cn-beijing.aliyuncs.com/Digital/static/pic/product/toukui.obj',
					function(obj) {

						object = obj;

					}, onProgress, onError);

				//原始事件
				// renderer = that.renderer = new THREE.WebGLRenderer();
				// renderer.setPixelRatio(window.devicePixelRatio);
				// renderer.setSize(window.innerWidth, window.innerHeight);
				// container.appendChild(renderer.domElement);

				// document.addEventListener('mousemove', onDocumentMouseMove);
				// window.addEventListener('resize', onWindowResize);
				// 鼠标点击事件
				renderer = that.renderer = new THREE.WebGLRenderer({
					antialias: true
				});
				renderer.setPixelRatio(window.devicePixelRatio);
				renderer.setSize(window.innerWidth, window.innerHeight);
				renderer.outputEncoding = THREE.sRGBEncoding;
				renderer.shadowMap.enabled = true;
				container.appendChild(renderer.domElement);

				//控制模型触动事件
				camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 2000);
				camera.position.set(160, 40, 160);

				const controls = new OrbitControls(camera, renderer.domElement);
				controls.enablePan = false;
				controls.enableZoom = true;
				controls.target.set(0, 1, 0);
				controls.update();

				// stats = new Stats();
				// container.appendChild(stats.dom);
				window.addEventListener('resize', onWindowResize);


			}

			function onWindowResize() {

				windowHalfX = window.innerWidth / 2;
				windowHalfY = window.innerHeight / 2;

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize(window.innerWidth, window.innerHeight);

			}

			function onDocumentMouseMove(event) {

				mouseX = (event.clientX - windowHalfX) / 2;
				mouseY = (event.clientY - windowHalfY) / 2;

			}
			function animate() {

				requestAnimationFrame(animate);
				render();

			}

			function render() {
				//camera.position.x += ( mouseX - camera.position.x ) * .05;
				// mera.position.y += ( - mouseY - camera.position.y ) * .05;
				// mera.lookAt( scene.position );
				renderer.render(scene, camera);

				//	console.error(new Date().getTime())
				if (object) {
					object.rotation.set(0, object.rotation.y + 0.007, 0)
				}


			}

		}
	}
</script>

<style lang="scss">
	.three_3d {
		width: 750rpx;
		height: 800rpx;
	}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239

完整项目地址gitee:https://gitee.com/sun-icon/uniapp3D

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/833196
推荐阅读
相关标签
  

闽ICP备14008679号