编辑
2025-04-19
(灵机一线)前端小项目
00
请注意,本文编写于 41 天前,最后修改于 41 天前,其中某些信息可能已经过时。

目录

开始创建一个简单的xr组件

最近在做一个ar小程序项目,需要调用摄像头,需要将glb模型放置到平面上,并分享出去。为了满足这个需求,接触到微信小程序新的ar-frame框架。框架地址:https://developers.weixin.qq.com/miniprogram/dev/framework/xr-frame/

开始创建一个简单的xr组件

index.wxml

wxml
<!--index.wxml--> <scroll-view class="scrollarea" scroll-y type="list"> <xr-scene ar-system="modes:Plane" bind:ready="handleReady" bind:tick="handleTick"> <xr-assets bind:loaded="handleAssetsLoaded"> <xr-asset-load type="gltf" asset-id="anchor" src="https://mmbizwxaminiprogram-1258344707.cos.ap-guangzhou.myqcloud.com/xr-frame/demo/ar-plane-marker.glb" /> </xr-assets> <xr-env env-data="xr-frame-team-workspace-day" /> <xr-light type="ambient" color="1 1 1" intensity="1" /> <xr-light type="directional" rotation="40 70 0" color="1 1 1" intensity="3" cast-shadow /> <xr-ar-tracker mode="Plane"> <xr-node wx:if="{{isShowAnchor}}"> <xr-gltf model="anchor"></xr-gltf> </xr-node> </xr-ar-tracker> <xr-node wx:if="{{gltfLoaded}}"> <xr-node wx:for="{{gltfIdList}}" wx:for-item="gltfItem" node-id="{{gltfItem.id}}" visible="false" wx:key="index"> <xr-gltf model="gltf-{{gltfItem.id}}" anim-autoplay scale="{{gltfItem.scale}}" rotation="{{gltfItem.rotation}}" /> </xr-node> </xr-node> <xr-camera clear-color="0.4 0.8 0.6 1" background="ar" is-ar-camera /> </xr-scene> </scroll-view>

其中主要代码为:

wxml
<xr-ar-tracker mode="Plane"> <xr-node wx:if="{{isShowAnchor}}"> <xr-gltf model="anchor"></xr-gltf> </xr-node> </xr-ar-tracker> <xr-node wx:if="{{gltfLoaded}}"> <xr-node wx:for="{{gltfIdList}}" wx:for-item="gltfItem" node-id="{{gltfItem.id}}" visible="false" wx:key="index"> <xr-gltf model="gltf-{{gltfItem.id}}" anim-autoplay scale="{{gltfItem.scale}}" rotation="{{gltfItem.rotation}}" /> </xr-node> </xr-node>

ts动态加载资源

ts
// gltfList的数据结构为[{name: '老虎', icon: "", material: "https://smart-patrol.oss-cn-beijing.aliyuncs.com/files/20250414/174461236814516950.glb", id: 1, scale: "1 1 1", rotation: "0 0 0" }] async loadGLTF(gltfList: any) { const scene = this.scene; const gltfIdList: any = []; wx.showLoading({ title: '模型加载中', }) const gltfModel = await Promise.all(gltfList.map((gltfItem: any, index: number) => { gltfIdList.push(gltfItem) return scene.assets.loadAsset({ type: 'gltf', assetId: 'gltf-' + gltfItem.id, src: gltfItem.material, }) })) // console.log(gltfModel, 'glTF asset loaded') this.setData({ gltfIdList: gltfIdList, gltfLoaded: true }) wx.hideLoading() } // 清除资源 releaseGLTF() { if (this.data.gltfIdList && this.data.gltfIdList.length > 0) { const scene = this.scene this.data.gltfIdList.map((item) => { // 释放加载过的资源 scene.assets.cancelAsset('gltf', `gltf-${item.id}`); scene.assets.releaseAsset('gltf', `gltf-${item.id}`); }) this.setData({ gltfIdList: [] }) } } // 拍照分享保存 handleShare: function () { // 分享时清除底部模型 this.setData({ isShowAnchor: false, }) this.scene.share.captureToFriends().then((res: any) => { this.setData({ isShowAnchor: true }) }); }

提示

动态加载glb资源需要展示的时候加载,不展示时清除资源。 模型scale属性不可设置为0 0 0 ,模型会缩放到0。 加载xr-node时要外层加入gltfLoaded控制资源加载成功后加载节点。

本文作者:lsq_137

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!