記錄--uniapp微信小程式引入threeJs並導入模型

来源:https://www.cnblogs.com/smileZAZ/archive/2022/11/28/16932638.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 我的需求是使用uniapp寫微信小程式,在小程式中使用threeJs就行了,目前暫不考慮相容app什麼的。 1.引入小程式版的threejs庫實現 2.使用webview實現(推薦) 重點 我的建議是使用這個庫https://git ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

前言

我的需求是使用uniapp寫微信小程式,在小程式中使用threeJs就行了,目前暫不考慮相容app什麼的。
1.引入小程式版的threejs庫實現
2.使用webview實現(推薦)

重點

我的建議是使用這個庫
https://github.com/deepkolos/three-platformize
為什麼?我試了uniapp推薦的和threejs-miniprogram這個小程式官方庫,都載入不出來我的obj模型。所有我推薦不要用obj模型最好,挺多都支持GLTF模型的,但是我不能改。

使用three-platformize載入obj模型的案例:

 核心代碼:

html:
<canvas type="webgl" id="webgl" style="width: 100vw; height: 100vh;" 
	@touchstart="touchStart" 
	@touchmove="touchMove" 
	@touchend="touchEnd"
/>
script:
<script>
	import * as THREE from 'three-platformize';
	import { WechatPlatform } from 'three-platformize/src/WechatPlatform';
	import { OBJLoader } from 'three-platformize/examples/jsm/loaders/OBJLoader';
	import { GLTFLoader } from 'three-platformize/examples/jsm/loaders/GLTFLoader';
	import {OrbitControls} from 'three-platformize/examples/jsm/controls/OrbitControls';
	export default {
		data() {
			return {
				canvas:null,
				camera:null,
				scene:null,
				renderer:null,
				model:null,
				controls:null,
				loopIndex:null
			}
		},
		onLoad() {

		},
		methods: {
			async init() { 
				const { canvas }= await this.getCanvas();
				this.canvas = canvas;
				const platform = new WechatPlatform(canvas); // webgl canvas
				platform.enableDeviceOrientation('game'); // 開啟DeviceOrientation
				THREE.PLATFORM.set(platform);
				this.platform = platform;
				this.renderModel();
		    },
			//獲取畫布
			async getCanvas(delay = 200) {
			  return new Promise((resolve, reject) => {
				const t = setTimeout(() => {
				  clearTimeout(t);
				  uni.createSelectorQuery().in(this)
					.select('#webgl')
					.fields({ node: true })
					.exec((res) => {
						console.log('res',res)
					  if (res && res[0] && res[0].node) {
						const canvas = res[0].node;
						resolve({ canvas });
					  } else {
						reject("獲取canvas失敗");
					  }
					});
				}, delay);
			  });
			},
			renderModel () {
				this.camera = new THREE.PerspectiveCamera(45, this.canvas.width / this.canvas.height, 0.25, 100);
				this.camera.position.set(- 5, 3, 10);
				this.camera.lookAt(new THREE.Vector3(0, 2, 0));
				this.scene = new THREE.Scene();
				this.scene.background = new THREE.Color(0xe0e0e0);
				this.scene.fog = new THREE.Fog(0xe0e0e0, 20, 100);
				this.clock = new THREE.Clock();
				// lights
				var light = new THREE.HemisphereLight(0xffffff, 0x444444);
				light.position.set(0, 20, 0);
				this.scene.add(light);
				// 改變外殼顏色
				var AmbientLight = new THREE.AmbientLight(0x815800); // 環境光
				this.scene.add(AmbientLight);
				// 平行光
				light = new THREE.DirectionalLight(0xffffff);
				light.position.set(0, 20, 10);
				this.scene.add(light);
				// // ground
				// var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2000, 2000), new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false }));
				// mesh.rotation.x = - Math.PI / 2;
				// this.scene.add(mesh);
				// var grid = new THREE.GridHelper(200, 40, 0x000000, 0x000000);
				// grid.material.opacity = 0.6;
				// grid.material.transparent = true;
				// this.scene.add(grid);
				// model
				var loader = new OBJLoader();
				loader.load('http://localhost:8888/obj3/file.obj', (obj) => {
					console.log("obj+=")
					console.log(obj)
					// console.log(this.model)
					obj.position.set(0, -2, 0);//模型擺放的位置
					obj.scale.set(0.2, 0.2, 0.2);
					// this.model = obj;
					this.scene.add(obj);
				}, undefined, function (e) {
					console.log("模型載入錯誤")
					console.error(e);
				});
				// var loader = new GLTFLoader();
				// 	loader.load('https://dtmall-tel.alicdn.com/edgeComputingConfig/upload_models/1591673169101/RobotExpressive.glb', (gltf) => {
				// 		this.model = gltf.scene;
				// 		this.scene.add(this.model);
				// 	}, undefined, function (e) {
				// 		console.error(e);
		  //       });
				// var geometry = new THREE.BoxGeometry( 5, 5, 5 );
				// var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
				// var mesh = new THREE.Mesh( geometry, material );
				// this.scene.add(mesh);
		
				this.renderer = new THREE.WebGLRenderer({antialias: true });
				this.renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
				this.renderer.setSize(this.canvas.width, this.canvas.height);
				//this.renderer.outputEncoding = true;
				this.renderer.gammaFactor = 2.2;
		
				this.controls = new OrbitControls(this.camera, this.renderer.domElement );
				this.camera.position.set( 5, 5, 10 );
				this.animate();
			},
		animate() {
		        this.loopIndex = this.canvas.requestAnimationFrame(this.animate);
		        this.renderer.render(this.scene, this.camera);
		        this.controls.update();
		    },
		
		    touchStart(e) {
		        this.platform.dispatchTouchEvent(e);
		    },
		    touchMove(e) {
		        this.platform.dispatchTouchEvent(e);
		    },
		    touchEnd(e) {
		        this.platform.dispatchTouchEvent(e);
		    }
		},
		mounted() {
			this.$nextTick(()=>  {
			      this.init();
			    });
		}
	}
</script>

上面的案例中使用了兩個模型,一個obj模型,obj模型的地址是自己寫的本地伺服器地址,需要自己配置,GLTF模型地址是網路地址,可以把註釋解開查看。

註意點

1.載入外部模型與threeJs官網api是一致的
2.使用此方法載入外部模型,可能在真機調試時遇到模型不展示,或者微信閃退的情況(原因未知)

webview實現引入threejs庫

效果圖

實現:
1.使用vue實現threejs導入obj模型(pc端可完美實現),
2.在webview中引入相應的模型展示地址,

完結,就這兩步即可,但是我是動態載入,所以在載入模型的時候,你需要在小程式端傳值給pc端,讓pc端載入相應的模型,這裡就只需要用get在地址欄中傳參就行了。

以下兩個方法可能會用到:
1.模型大小自適應

setScaleToFitSize (obj) {
      const boxHelper = new THREE.BoxHelper(obj);
      boxHelper.geometry.computeBoundingBox();
      const box = boxHelper.geometry.boundingBox;
      const maxDiameter = Math.max((box.max.x - box.min.x), (box.max.y - box.min.y), (box.max.z - box.min.z));
      const scaleValue = camera.position.z / maxDiameter;
      obj.position.set(0, -10, 0);//模型擺放的位置
      obj.scale.set(scaleValue, scaleValue, scaleValue);
      scene.add(obj);
    },

2.禁止小程式展示webview時候向下拉動:
mounted中添加:

document.body.addEventListener('touchmove', function (e) {
        e.preventDefault();
      }, { passive: false });

本文轉載於:

https://blog.csdn.net/hzqzzz/article/details/126428029

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首發微信公眾號:SQL資料庫運維 原文鏈接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1&sn=450e9e94fa709b5eeff0de371c62072b&chksm=ea37536cdd40da7 ...
  • 導語 VPN是一種通過公網連接兩個或多個私網站點的專用網路,使得這些站點仿佛是通過專線連接在一起。IPSec是一套協議框架,用於保證數據傳輸的私密性,完整性,真實性。但是VPN網路經常會帶來一些連通性上的問題,通常與MTU設置的不合理有關。本文通過一個實際案例,來具體分析解決這個問題。 作者:陸信宇 ...
  • 作者:vivo 互聯網存儲技術團隊- Qiu Sidi 在企業大數據體系建設過程中,數據採集是其中的首要環節。然而,當前行業內的相關開源數據採集組件,並無法滿足企業大規模數據採集的需求與有效的數據採集治理,所以大部分企業都採用自研開發採集組件的方式。本文通過在vivo的日誌採集服務的設計實踐經驗,為 ...
  • 版權聲明:原創不易,本文禁止抄襲、轉載,侵權必究! 一、DBeaver簡介 DBeaver是一個通用的資料庫管理工具和 SQL 客戶端,社區版的DBeaver只能連接關係型資料庫,比如MySQL、Oracle等,只有企業版以上才能連接非關係型資料庫,比如MongoDB、Redis等;DBeaver ...
  • 原文:Jitpack發佈Android庫出現Direct local .aar file dependencies are not supported when building an AAR - Stars-One的雜貨小窩 問題描述 由於我項目中某個Module引用了本地的aar文件,導致出現了 ...
  • 文章主要闡述了優先順序反轉的一些概念和解決思路,並結合iOS平臺的幾種鎖進行了詳細的調研。通過深入的理解,可以去規避一些不必要的優先順序反轉,從而進一步避免卡死異常。 ...
  • ...
  • 前言 由於工作需要,要抓取tb上某個介面的文案資源,用來分析借鑒。 本來想著,無非就是驗證一下當前用戶信息之類的,但在研究過後,發現並沒那麼簡單。 1,查看請求相關參數 比如下圖,發現請求中攜帶的參數不少,然後其中隨時變化的就有t、sign、data, 很明顯,這就是tb判斷請求是否合法的參數,其中 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...