最近应公司项目需求要在微信小程序上进行3D模型渲染,还要调用微信摄像头所以不能直接上webview只能使用微信的WebglCanvas来做。过程中踩了一些坑,现在功能基本达到所以打算记录下遇到的问题与解决办法思路,希望对自己和也在微信WebglCanvas上踩坑的小伙伴所有帮助,也希望官方可以及时填坑。
在开发中遇到的问题大致如下:
- 动态调整画布的大小,位置。
- ThreeJs的引入与使用。
- 透明混合的问题
问题描述与解决方案
- 所谓工欲善其事必先利其器,在使用ThreeJs进行3D渲染之前我们需要向ThreeJs提供Webgl的绘制上下文。在原生H5中我们可以轻松用的dom操作获取,而在小程序我们只能使用SelectorQuery的方法来获得
<canvas type="webgl" id="webgl" ></canvas>
// 先声明一个canvas并将其类型设为webgl
wx.createSelectorQuery()
.select('#webgl')
.node()
.exec(res=> {
let canvas = res[0].node;
let ctx = canvas.getContext("webgl");
ctx.clearColor(1, 0, 0, 1);
ctx.clear(ctx.COLOR_BUFFER_BIT);
})
// 通过SelectorQuery获取canvas组件,获取绘制上下文,简单将画布渲染为红色
通过上面的代码我们获得一个这样的画面
这时如果你想设置画布的大小可以通过wxss或者style属性来设定,这里我们通过style来设定
<canvas type="webgl" id="webgl"
style=" position:fixed;width:{{cavansWidth}}px;height:{{cavansHeight}}px;top:{{canvasTop}}px;left:{{canvasLeft}}px;"
></canvas>
Page({
data: {
cavansWidth: 150,
cavansHeight: 150,
canvasTop: 0,
canvasLeft: 0,
},
})
如果要动态修改画布大小比如改成300*300的尺寸, 一般会直接用setData来做,但这样并不能在开发者工具中正确的修改canvas尺寸。
从上图可以发现canvas的样式其实已经修改成功了但是绘制区域并没有修改成功,这是一个很奇怪的问题,这个问题也困扰我很久。万事不决用console。打印了ctx(绘制上下文)后,发现ctx中canvas属性的css样式并没有修改
抱着试一试的心态我手动修改了其属性的值。
ctx.canvas.style.left = 20 + 'px';
ctx.canvas.style.top = 20 + 'px';
ctx.canvas.style.width = 300 + 'px';
ctx.canvas.style.height = 300 + 'px';
居然就得到想要的画布,但你以为这样就结束了吗,并没有。让我们掏出我们的手机来试试预览吧。如果你是安卓机,恭喜你你获得了一个报错,如果你是苹果机你会发现修改不生效。
至于什么会这样只能问官方了。那么如何在手机上正常的修改,其实也很简单就使用setData修改,不使用style属性修改就可以了。为了方便起见,在修改前判定下是否为开发工具即可。
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
cavansWidth: 150,
cavansHeight: 150,
canvasTop: 0,
canvasLeft: 0,
},
onReady: function () {
this.setData({
cavansWidth: 300,
cavansHeight: 300,
canvasTop: 20,
canvasLeft: 20,
})
wx.createSelectorQuery()
.select('#webgl')
.node()
.exec(res => {
let canvas = res[0].node;
let ctx = canvas.getContext("webgl");
wx.getSystemInfo({
success: function (res) {
if (res.platform == 'devtools') {
ctx.canvas.style.left = 20 + 'px';
ctx.canvas.style.top = 20 + 'px';
ctx.canvas.style.width = 300 + 'px';
ctx.canvas.style.height = 300 + 'px';
}
}
})
console.log(ctx);;
ctx.clearColor(1, 0, 0, 1);
ctx.clear(ctx.COLOR_BUFFER_BIT);
})
},
})
总结起来就一句话移动端用setData修改,开发工具用ctx.canvas.style属性修改。
另外在设置画布初始大小的时候最好设置大一点,如果你修改的尺寸比原始大小大太多会造成渲染模糊的问题,其中具体原因就要问官方了。。。。。。。
好了,第一部分就到这了,有什么问题可以私信或者发表评论,我保证尽量都看都回。