three-platformize 微信小程序 uniapp 使用截图功能

最近需要将3d场景进行截图,但是网上的各种各样,看的我一团乱麻,因此在解决完后就将这些简单的分享一下;

原理:将3维场景的那个canvas中的像素提取出来,找一个空的canvas二维画布放上去,然后用二维画布的那个进行截图

实际操作:

saveImage(){
			const [data, w, h] = screenshot(renderer, scene, camera, WebGLRenderTarget);
			const ctx = helperCanvas.getContext('2d')
			const imgData = helperCanvas.createImageData(data, w, h);
			helperCanvas.height = imgData.height;
			helperCanvas.width = imgData.width;
			ctx.putImageData(imgData, 0, 0);
			const imgDataFromCanvas = ctx.getImageData(0, 0, w, h)
			const hasPixel = imgDataFromCanvas.data.some(i => i !== 0)
			wx.canvasToTempFilePath({
				// @ts-ignore
				canvas: helperCanvas,
				success(res) {
					wx.previewImage({
						urls: [res.tempFilePath],
					})
				}
			})
		},

说一下代码部分

import { screenshot } from 'three-platformize/tools/screenshot'

import { WebGLRenderTarget } from 'three';

是直接从three-platformize中导入进来的

然后放入场景、相机、渲染器、以及一个WebGLRenderTarget

然后当执行saveImage这个方法时就能够将当前相机看到的变成一个图片临时保存,也就是那个res.tempFilePath,

然后就是我通过this. 的方式一直获取不到data中的方法,因此呢就把渲染器什么的都放入到了全局变量中

注意:代码是在uniapp vue3中使用的,微信小程序原生的当然也是可以用的了

<think> 我们正在讨论在uniapp开发微信小程序项目中使用threejs-miniprogram的方法。 根据引用[1][2][3]的信息,我们知道: 1. threejs-miniprogram是微信官方提供的Three.js小程序适配版本。 2. 在uniapp中也可以使用,但注意它可能只支持gltf格式的模型(不支持obj等)。 3. 引用[2]提到使用官方版本时遇到材质设置无效的问题,因此作者转向了three-platformize(但用户这里明确询问的是threejs-miniprogram)。 用户问题:在uniapp开发微信小程序项目中使用threejs-miniprogram的方法。 步骤: 1. 安装threejs-miniprogram包: 我们可以通过npm安装,或者直接下载构建好的文件。 2. 在uniapp项目中引入: 由于小程序环境的特殊性,我们不能直接使用npm包,需要将threejs-miniprogram构建为小程序可用的文件。 3. 创建自定义组件(或直接在页面中使用): 通常,3D渲染需要在一个WebGL上下文环境中,因此我们需要使用一个canvas组件,并为其指定一个type="webgl"。 4. 编写Three.js代码: 在uniapp中,我们需要在合适的生命周期中初始化Three.js场景。 5. 加载模型(如gltf): 使用GLTFLoader加载模型。 注意:引用[2]提到官方版本可能只支持gltf模型,且设置材质可能无效(但用户可能还是想尝试官方版本)。 具体步骤: 步骤1:安装threejs-miniprogram 在项目根目录执行: ```bash npm install threejs-miniprogram ``` 步骤2:构建npm(因为微信小程序需要将node_modules中的模块构建成小程序可用的代码) 在微信开发者工具中,点击菜单栏“工具”->“构建npm”,或者使用uniapp的命令行工具构建。 步骤3:在页面中引入 在需要使用Three.js的页面的脚本中,引入threejs-miniprogram: ```javascript import * as THREE from 'threejs-miniprogram' // 如果需要使用GLTFLoader,则需要单独引入 import { GLTFLoader } from 'threejs-miniprogram/examples/jsm/loaders/GLTFLoader' ``` 步骤4:在页面的模板中添加canvas ```html <!--uni-app的vue文件中 --> <template> <view> <canvas type="webgl" id="canvas" canvas-id="canvas" :style="{width: canvasWidth + 'px', height: canvasHeight + 'px'}"></canvas> </view> </template> ``` 步骤5:在页面的js部分初始化Three.js 注意:由于小程序的canvas是原生组件,我们需要在节点挂载后获取canvas节点。在uniapp中,我们可以使用`this.$nextTick`或`setTimeout`确保节点已挂载,然后使用`uni.createSelectorQuery()`获取canvas节点。 ```javascript export default { data() { return { canvasWidth: 300, canvasHeight: 300 } }, mounted() { this.$nextTick(() => { // 获取canvas节点 const query = uni.createSelectorQuery().in(this); query.select('#canvas').fields({ node: true, size: true }).exec((res) => { const canvas = res[0].node; // 初始化Three.js this.initThree(canvas); }); }); }, methods: { initThree(canvas) { // 使用threejs-miniprogram导入的THREE const renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, }); // ... 创建场景、相机、灯光等 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, this.canvasWidth / this.canvasHeight, 0.1, 1000); // ... 其他代码 // 如果需要加载模型 const loader = new GLTFLoader(); loader.load('path/to/your/model.gltf', (gltf) => { scene.add(gltf.scene); // 渲染循环 const animate = () => { // 更新逻辑 // ... renderer.render(scene, camera); requestAnimationFrame(animate); }; animate(); }); } } } ``` 注意:由于小程序包大小限制,模型文件需要放在服务器上(通过网络加载)或放在小程序包内(注意大小限制)。 注意事项: - 小程序对包大小有严格限制,整个小程序包大小不能超过2MB,因此模型文件通常需要存放在服务器上,通过URL加载。 - 使用GLTFLoader时,注意检查模型路径是否正确,以及服务器是否允许跨域(如果模型在远程服务器上)。 - 引用[2]中提到的材质设置问题,可能是由于版本或使用方式的问题,需要仔细检查。 如果遇到材质设置无效的问题,可以尝试以下方法: - 确保在模型加载完成后,遍历模型的所有材质并重新设置属性。 - 检查Three.js版本和GLTFLoader的兼容性。 - 查看官方示例,确认使用方式是否正确。 引用[3]提供了一个GLTFLoader的示例链接,可以参考其用法。 相关引用: [^1]: threejs-example-for-miniprogram 是一个在微信小程序使用 Three.js 的示例项目。 [^2]: 微信小程序threejs的使用。 [^3]: uniapp使用threejs-miniprogram在微信小程序加载模型。 生成的相关问题: 1. 在微信小程序使用threejs-miniprogram加载gltf模型时,如何解决材质设置无效的问题? 2. 除了threejs-miniprogram,还有其他可以在uniapp微信小程序使用的3D渲染库吗? 3. 如何优化threejs-miniprogram在小程序中的性能? 4. 如何将3D模型转换为gltf格式并在小程序中加载? </think> ### 在 UniApp 微信小程序使用 threejs-miniprogram 的方法 以下是基于官方文档和引用内容的完整实现流程: #### 1. **环境准备** ```bash npm install threejs-miniprogram # 安装官方适配库[^2][^3] ``` #### 2. **Canvas 配置(Vue文件)** ```html <template> <view> <!-- 必须声明canvas-id和type="webgl" --> <canvas canvas-id="threeCanvas" type="webgl" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }" /> </view> </template> <script> import * as THREE from 'threejs-miniprogram'; export default { data() { return { canvasWidth: 300, // 画布宽度 canvasHeight: 400 // 画布高度 } } } </script> ``` #### 3. **Three.js 初始化(核心代码)** ```javascript methods: { async initThree() { // 获取Canvas节点 const { node: canvas } = await new Promise(resolve => { uni.createSelectorQuery() .in(this) .select('#threeCanvas') .node(resolve) .exec() }); // 创建渲染器 const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, // 抗锯齿 alpha: true // 透明背景 }); // 创建场景和相机 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, this.canvasWidth / this.canvasHeight, 0.1, 1000 ); // 添加立方体示例 const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); camera.position.z = 5; // 渲染循环 const render = () => { cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); requestAnimationFrame(render); }; render(); } }, mounted() { this.$nextTick(this.initThree); } ``` #### 4. **模型加载(仅支持GLTF格式)** ```javascript import { GLTFLoader } from 'threejs-miniprogram/examples/jsm/loaders/GLTFLoader'; // 在initThree方法内添加: const loader = new GLTFLoader(); loader.load( '/static/model.gltf', // 模型路径(需放在static目录) (gltf) => { scene.add(gltf.scene); console.log("模型加载成功"); }, undefined, (error) => { console.error("模型加载失败:", error); } ); ``` #### ⚠️ 关键注意事项: 1. **格式限制** 官方版本仅支持 GLTF 格式模型(不支持 OBJ/FBX 等)[^2][^3] 2. **包体积优化** 小程序主包需 ≤ 2MB: - GLTF 模型压缩使用 `gltf-pipeline` - 纹理尺寸 ≤ 1024x1024 3. **路径规范** 模型文件必须放在 `static/` 目录下 4. **真机调试** 需开启「调试基础库」> 2.16.0 并勾选「开启自动化性能监控」 #### 问题排查指南 | 常见问题 | 解决方案 | |---------|----------| | 黑屏无渲染 | 检查 `canvas-id` 命名一致性 | | 模型加载失败 | 确认模型为 GLTF 2.0 格式 | | 材质不生效 | 使用 `MeshStandardMaterial` 替代基础材质 | | 内存溢出 | 调用 `dispose()` 销毁未使用的几何体和材质 | [^1]: threejs-example-for-miniprogram 是微信小程序Three.js 示例项目 [^2]: 官方 threejs-miniprogram 仅支持 GLTF 格式模型 [^3]: GLTFLoader 使用示例需参考 GitHub 官方仓库 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值