1. 概述
微信小程序 canvas 是指在微信小程序中使用 canvas 组件进行绘图操作。帮助开发者可以实现在小程序中绘制各式各样的图形和动画效果。canvas 组件提供了丰富的接口,支持画布的绘制、修改、清除、设置样式等操作。
1.1 canvas 组件的基本用法
要在小程序中使用 canvas 组件,只需要在 wxml 文件中添加一个 canvas 标签即可:
<canvas id="myCanvas"></canvas>
然后在对应的 js 文件中获取 canvas 对象进行绘制操作:
const ctx = wx.createCanvasContext('myCanvas')
ctx.rect(0, 0, 100, 100)
ctx.setFillStyle('red')
ctx.fill()
ctx.beginPath()
ctx.arc(60, 60, 30, 0, 2*Math.PI)
ctx.setStrokeStyle('blue')
ctx.stroke()
ctx.draw()
以上代码绘制了一个红色的矩形和一个蓝色的圆形。其中,createCanvasContext 方法用于获取 canvas 绘图上下文,setFillStyle 和 setStrokeStyle 用于设置填充色和描边色,fill 和 stroke 用于填充和描边图形。
1.2 canvas 组件的局限性
在小程序中使用 canvas 组件也存在一些局限性。例如,canvas 绘制的图形不能使用 CSS 属性进行样式控制,也不能进行事件监听。因此,如果需要在小程序中实现一些比较复杂的图形和动画效果,建议使用第三方组件库或者使用原生小程序的 animation、image 等组件进行实现。
2. canvas 绘制基本图形
canvas 组件提供了许多接口可以用于绘制基本的图形,如 fillRect、strokeRect、clearRect、arc、bezierCurveTo、quadraticCurveTo 等。下面我们分别说明这些接口的使用方法。
2.1 绘制矩形
绘制矩形可以使用 fillRect、strokeRect、clearRect 方法。其中,fillRect 方法用于绘制实心矩形,strokeRect 方法用于绘制空心矩形,clearRect 方法用于清除矩形区域内的内容。
const ctx = wx.createCanvasContext('myCanvas')
ctx.fillRect(0, 0, 100, 100) // 绘制实心矩形
ctx.strokeRect(20, 20, 60, 60) // 绘制空心矩形
ctx.clearRect(30, 30, 40, 40) // 清除矩形区域内的内容
ctx.draw()
以上代码执行后的效果如下:
const ctx1 = wx.createCanvasContext('canvas-rect')
ctx1.fillRect(0, 0, 100, 100)
ctx1.strokeRect(20, 20, 60, 60)
ctx1.clearRect(30, 30, 40, 40)
ctx1.draw()
2.2 绘制圆形
绘制圆形可以使用 arc 方法。该方法需要传入圆心坐标、半径、起始角度(以弧度为单位)和结束角度(以弧度为单位)等参数。
const ctx = wx.createCanvasContext('myCanvas')
ctx.arc(60, 60, 30, 0, 2*Math.PI)
ctx.setFillStyle('red')
ctx.fill()
ctx.draw()
以上代码执行后的效果如下:
const ctx2 = wx.createCanvasContext('canvas-arc')
ctx2.arc(60, 60, 30, 0, 2*Math.PI);
ctx2.setFillStyle('red')
ctx2.fill()
ctx2.draw()
2.3 绘制曲线
绘制曲线可以使用 bezierCurveTo 和 quadraticCurveTo 方法。其中,bezierCurveTo 方法用于绘制三次贝塞尔曲线,quadraticCurveTo 方法用于绘制二次贝塞尔曲线。
const ctx = wx.createCanvasContext('myCanvas')
ctx.beginPath()
ctx.moveTo(20, 20)
ctx.bezierCurveTo(20, 100, 200, 100, 200, 20)
ctx.closePath()
ctx.setFillStyle('red')
ctx.fill()
ctx.beginPath()
ctx.moveTo(40, 40)
ctx.quadraticCurveTo(40, 120, 160, 80)
ctx.closePath()
ctx.setStrokeStyle('blue')
ctx.stroke()
ctx.draw()
以上代码执行后的效果如下:
const ctx3 = wx.createCanvasContext('canvas-curve')
ctx3.beginPath()
ctx3.moveTo(20, 20)
ctx3.bezierCurveTo(20, 100, 200, 100, 200, 20)
ctx3.closePath()
ctx3.setFillStyle('red')
ctx3.fill()
ctx3.beginPath()
ctx3.moveTo(40, 40)
ctx3.quadraticCurveTo(40, 120, 160, 80)
ctx3.closePath()
ctx3.setStrokeStyle('blue')
ctx3.stroke()
ctx3.draw()
3. canvas 绘制图片
如果我们需要在 canvas 中绘制图片,可以使用 drawImage 方法将图片绘制到画布上。该方法需要传入图片的 URL 或者在 onLoad 回调函数中返回的图片对象(Image 或 Canvas)。
const ctx = wx.createCanvasContext('myCanvas')
wx.getImageInfo({
src: 'https://example.com/your-image.jpg',
success: function (res) {
console.log(res.width)
console.log(res.height)
ctx.drawImage(res.path, 0, 0, res.width, res.height)
ctx.draw()
}
})
以上代码下载了一张图片并将其绘制到 canvas 上。
4. canvas 绘制动画
在 canvas 中实现动画效果可以使用 requestAnimationFrame 方法进行绘制操作。该方法每秒钟会执行 60 次,用于实现流畅的动画效果。在每次绘制完成后需要再次调用 requestAnimationFrame 方法来触发下一次绘制。
下面是一个简单的动画代码示例,实现了小球的运动效果:
const ctx = wx.createCanvasContext('myCanvas')
const x1 = 10
let x = x1
let y = 10
let vx = 1
function drawFrame() {
ctx.clearRect(0, 0, 300, 150)
ctx.beginPath()
ctx.arc(x, y, 10, 0, 2 * Math.PI)
ctx.setFillStyle('blue')
ctx.fill()
x += vx
if (x + 10 >= 300 || x - 10 <= 0) {
vx = -vx
}
requestAnimationFrame(drawFrame)
}
drawFrame()
以上代码实现了一个简单的小球运动效果,小球会在画布中左右移动,并且碰到边界后会反弹。效果如下:
const ctx4 = wx.createCanvasContext('canvas-animation')
const x1 = 10
let x = x1
let y = 10
let vx = 1
function drawFrame() {
ctx4.clearRect(0, 0, 300, 150)
ctx4.beginPath()
ctx4.arc(x, y, 10, 0, 2 * Math.PI)
ctx4.setFillStyle('blue')
ctx4.fill()
x += vx
if (x + 10 >= 300 || x - 10 <= 0) {
vx = -vx
}
requestAnimationFrame(drawFrame)
}
drawFrame()
5. canvas 组件的优化
canvas 组件的性能较差,因此在实际开发中需要进行优化。以下是一些常见的优化方法:
5.1 外部缓存
为了减少 canvas 绘制时的计算量,可以将绘制好的图形缓存在外部。这样当页面再次切换到该 canvas 时,可以直接将缓存的图形绘制到画布上,而不需要重新计算绘制。
5.2 适时清空画布
当频繁地进行 canvas 绘制操作时,可以考虑适时清空画布,减少 canvas 绘制的计算量。例如,我们可以在 requestAnimationFrame 函数中适时调用 clearRect 方法清空画布。
5.3 优化绘制顺序
将绘制耗时较多的图形放在后面进行绘制,可以避免canvas重复绘制。
5.4 支持离屏绘制
在一些场景中,我们需要对多个 canvas 元素进行复杂的绘制操作,但多次调用画布对象的操作对性能影响较大。为了提高绘制效率,我们可以考虑使用离屏绘制技术,将多个图层合成为一个图层后一次性进行绘制。
5.5 其他优化方法
还有一些其他优化方法,例如采用单独的线程进行绘制操作、取消全局脏矩形计算等。这些优化方法需要根据具体场景进行考虑,可以通过不断地实践和优化来提高小程序的画面渲染效率。
6. 总结
本文介绍了在小程序中使用 canvas 组件进行绘图操作的基本用法,包括绘制基本图形、绘制图片和绘制动画;同时也介绍了一些常见的 canvas 组件的优化方法,帮助开发者提高小程序的画面渲染效率。