最近在做一个ar小程序项目,需要调用摄像头,需要将glb模型放置到平面上,并分享出去。为了满足这个需求,接触到微信小程序新的ar-frame框架。框架地址:https://developers.weixin.qq.com/miniprogram/dev/framework/xr-frame/
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 许可协议。转载请注明出处!