微信小程序: canvas 2d 接口支持同层渲染且性能更佳,建议切换使用

更新日期: 2023-06-15 阅读次数: 10784 字数: 750 分类: 微信小程序

使用微信小程序的 canvas demo 代码绘制了一个矩形之后,发现小程序开发工具的 console 中有警告提示:

canvas 2d 接口支持同层渲染且性能更佳,建议切换使用。详见文档: https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html#Canvas-2D-%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81

文档里说,基础库 2.9.0 起支持一套新 Canvas 2D 接口(需指定 type 属性),同时支持同层渲染,原有接口不再维护。

是否有必要使用 canvas 2d

我觉得是有必要的,虽然原来的代码也能执行。但是 canvas 2d 带来的好处非常吸引人:

  • 性能更好
  • 原 canvas 接口不再维护。也就是说 canvas 2d 坑会少很多
  • canvas 2d 的接口与 h5 的接口一致,可以不用来回查看微信小程序 canvas 的特殊接口了。例如,stroke 必须跟 draw 一起使用这样的无厘头用法。
  • 支持同层渲染。虽然目前对我来说没啥用,但是可以避免未来踩坑

canvas 2d 的 hello world

将原来的 demo 进行一下改造:

wxml

<canvas id="demo" type="2d" style="width: 300px; height: 200px;"></canvas>

注意,这里有两处显著的改动

  • 属性 canvas-id 换成了 id
  • 增加了 type 属性

js

const query = wx.createSelectorQuery()  // 创建一个dom元素节点查询器
query.select('#demo')
	.fields({   			// 需要获取的节点相关信息
		node: true,       // 是否返回节点对应的 Node 实例
		size: true         // 是否返回节点尺寸(width height)
	}).exec((res) => {
		const canvas = res[0].node                // canvas就是我们要操作的画布节点
		const ctx = canvas.getContext('2d')   // 以2d模式,获取一个画布节点的上下文对象
                
                // 不加这段,矩形底部会显示不全,我还没看懂
		const dpr = wx.getSystemInfoSync().pixelRatio
		canvas.width = res[0].width * dpr
		canvas.height = res[0].height * dpr
		ctx.scale(dpr, dpr)

		ctx.strokeStyle = "#00ff00"
		ctx.lineWidth = 5
		ctx.rect(0, 0, 200, 200)
		ctx.stroke()
	})

这里与原 demo 差异巨大

  • 原来的 setStrokeStyle 换成了 strokeStyle 直接赋值的方式
  • 奇怪的 draw 函数没有了,大快人心
  • 为何要重新计算宽高,我实在没看懂

什么是同层渲染

  • 原生组件同层渲染:同层渲染是为了解决原生组件的层级问题,在支持同层渲染后,原生组件与其它组件可以随意叠加,有关层级的限制将不再存在。但需要注意的是,组件内部仍由原生渲染,样式一般还是对原生组件内部无效。当前 video, map, live-player, live-pusher, canvas(2d) 组件已支持同层渲染。
  • 原生组件相对层级:为了可以调整原生组件之间的相对层级位置,小程序在 v2.7.0 及以上版本支持在样式中声明 z-index 来指定原生组件的层级。该 z-index 仅调整原生组件之间的层级顺序,其层级仍高于其他非原生组件。

从文档的解释来看,主要是针对多个原生组件的层级处理。而 canvas 2d 也是原生组件。

继续阅读 🌳

微信小程序中显示关注公众号按钮

参考

https://www.cnblogs.com/alpiny/p/12574017.html

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式