吴化吉的博客

专注Web开发

发布时间:2018-09-29

微信小程序踩坑之:canvas

这是2018/3月记录的文章,但如今微信小程序进化很快,我也没有继续太关注这块内容,可能我写的这些有点过时,仅供参考

最近在公司做一个小程序的项目,要说小程序和传统前端开发很类似,而且和Vue很像,都是数据来驱动视图,没有DOM操作,概念上并不难接受(特别是有Vue/React等开发经验下)。

我所做的应用,有一个需求:需要画图表,也就是涉及到canvas这部分内容。实践下来踩坑不少,浪费了不少时间!记录一下。

主要坑点:

没有很好的图表库支持

因为小程序和传统Web开发不一样(主要是没有了DOM操作),所以在Web上大名鼎鼎的图标库如:highcharts,echarts 并不能直接使用。找来找去只有一个叫wx-charts的库是做的比较好的:https://github.com/xiaolin3303/wx-charts 。试用了一下,倒是也挺实用,但可定制的配置项较少(相较于echarts/highcharts)。说来也巧,就在前几天(二月底),恰逢echarts 推出了小程序,第一时间试用了一下,发现也并不够完美,小bug还有一些(我反馈的bug: https://github.com/ecomfe/echarts-for-weixin/issues/6 ),而且有兼容性的问题(我的兼容性疑问: https://github.com/ecomfe/echarts-for-weixin/issues/2 )。

长度单位问题

在小程序中,使用了新的长度单位px,也就是一个屏幕的宽度是750rpx,配合flex布局可以方便地解决不同机型的布局问题。但是在canvas中,长度单位还是px。也就是说,想要实现不同机型一样的效果,需要将canvas中所有设定的长度将对应的rpx转换成px。

也就是首先需要拿到手机的实际像素,可通过:wx.getSystemInfoSync().windowWidth,拿到,将此长度分成750份得到每个1rpx对应的px值,再乘以要设定的rpx长度。参考:https://segmentfault.com/a/1190000011805262

功能的缺失和差异

小程序提供的canvas组件,并不是一个完整的canvas,一些API没有实现。我之前对canvas也不是太熟悉,没有完全对比,但至少发现measureText()这个方法是没有的,需要自己想办法实现。而且部分内容也有所区别,比如 fillStyle/strokeStyle/lineWidth 这些属性,在小程序中,则是以方法的形式来使用:setFillStyle()/setStrokeStyle()/setLineWidth()。总之每用到一个东西,到先要到文档中确认下能不能用。

不能通过z-index 设置层级

文档中描述:

canvas 组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。

测试了发现也确实如此,任何定位到canvas上面的元素,无论z-index设多大,都无法遮住canvas。这是很坑的一点,如果页面上有个canvas,又想做一个弹出层遮罩的效果,是无法实现的!