最新项目中需要用到微信小程序(下文统称小程序)绘图相关的功能,今天就将小程序绘图相关的API学习和记录下。
说起绘图当然少不了我们的主角canvas。在小程序中使用canvas绘图时分为以下几个步骤:
// wxml文件
...
<canvas style="width:750rpx; height:300rpx;" canvas-id='canvas'></canvas>
...
// js文件
...
const ctx = wx.createCanvasContext('canvas')
...
// js文件
...
ctx.xxx()
...
最终会根据我们调用不同的api显示不同的绘制效果,接下啦就让我们一起来看下常用的这些API。
设置填充色,可以设置String类型和CanvasGradient类型颜色值
对当前路径进行填充
设置描边颜色
对当前路劲进行描边
以上两对API通常成对配合使用,用以辅助其他API来实现各种不同效果
创建一个矩形路径。需要用 fill 或者 stroke 方法将矩形真正的画到 canvas 中
参数含义:
number x:矩形路径左上角的横坐标
number y:矩形路径左上角的纵坐标
number width:矩形路径的宽度
number height:矩形路径的高度
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.rect(10, 10, 150, 75)
ctx.setFillStyle('red')
ctx.fill()
ctx.draw()
...
填充一个矩形。用 setFillStyle 设置矩形的填充色,如果没设置默认是黑色。
参数含义:同上
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.setFillStyle('red')
ctx.fillRect(10, 10, 150, 75)
ctx.draw()
...
效果同上
画一个矩形(非填充)。 用 setStrokeStyle 设置矩形线条的颜色,如果没设置默认是黑色。
参数含义:同上
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.setStrokeStyle('red')
ctx.strokeRect(10, 10, 150, 75)
ctx.draw()
...
通过使用rect()和stroke()这两个api也能实现同样效果哦
在给定的矩形区域内,清除画布上的像素
参数含义:同上
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.rect(10, 10, 150, 75)
ctx.setFillStyle('red')
ctx.fill()
ctx.clearRect(20, 20, 50, 30)
ctx.draw()
...
创建一条弧线
参数含义:
number x:圆心的 x 坐标
number y:圆心的 y 坐标
number r:圆的半径
number sAngle:起始弧度,单位弧度(在3点钟方向)
number eAngle:终止弧度
boolean counterclockwise:弧度的方向是否是逆时针
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.arc(100, 75, 50, 0, 1.5*Math.PI,false)
ctx.setStrokeStyle('#FF0000')
ctx.stroke()
ctx.draw()
ctx.arc(200, 75, 50, 0, 1.5 * Math.PI, true)
ctx.setFillStyle('#FF0000')
ctx.fill()
ctx.draw(true)//true表示保留之前绘制内容
...
开始创建一个路径。需要调用 fill 或者 stroke 才会使用路径进行填充或描边
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
// begin path
ctx.rect(10, 10, 100, 30)
ctx.setFillStyle('yellow')
ctx.fill()
// begin another path
ctx.beginPath()
ctx.rect(10, 40, 100, 30)
ctx.setFillStyle('blue')
ctx.fill()
ctx.draw()
...
把路径移动到画布中的指定点,不创建线条。用 stroke 方法来画线条
参数含义:
number x:目标位置的 x 坐标
number y:目标位置的 y 坐标
增加一个新点,然后创建一条从上次指定点到目标点的线。用 stroke 方法来画线条
参数含义:
number x:目标位置的 x 坐标
number y:目标位置的 y 坐标
关闭一个路径。会连接起点和终点。如果关闭路径后没有调用 fill 或者 stroke 并开启了新的路径,那之前的路径将不会被渲染
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.moveTo(10, 10)
ctx.lineTo(100, 10)
ctx.lineTo(100, 100)
ctx.closePath()
ctx.stroke()
ctx.draw()
...
创建二次贝塞尔曲线路径。曲线的起始点为路径中前一个点。
参数含义:
number cpx:贝塞尔控制点的 x 坐标
number cpy:贝塞尔控制点的 y 坐标
number x:结束点的 x 坐标
number y:结束点的 y 坐标
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
// Draw points
ctx.beginPath()
ctx.arc(20, 20, 2, 0, 2 * Math.PI)
ctx.setFillStyle('red')
ctx.fill()
ctx.beginPath()
ctx.arc(200, 20, 2, 0, 2 * Math.PI)
ctx.setFillStyle('lightgreen')
ctx.fill()
ctx.beginPath()
ctx.arc(20, 100, 2, 0, 2 * Math.PI)
ctx.setFillStyle('blue')
ctx.fill()
ctx.setFillStyle('black')
ctx.setFontSize(12)
// Draw guides
ctx.beginPath()
ctx.moveTo(20, 20)
ctx.lineTo(20, 100)
ctx.lineTo(200, 20)
ctx.setStrokeStyle('#AAAAAA')
ctx.stroke()
// Draw quadratic curve
ctx.beginPath()
ctx.moveTo(20, 20)
ctx.quadraticCurveTo(20, 100, 200, 20)
ctx.setStrokeStyle('black')
ctx.stroke()
ctx.draw()
...
针对 moveTo(20, 20) quadraticCurveTo(20, 100, 200, 20) 的三个关键坐标如下:
创建三次方贝塞尔曲线路径。
参数含义:
number cpx1:贝塞尔控制点1的 x 坐标
number cpy1:贝塞尔控制点1的 y 坐标
number cpx2:贝塞尔控制点3的 x 坐标
number cpy3:贝塞尔控制点3的 y 坐标
number x:结束点的 x 坐标
number y:结束点的 y 坐标
示例
// js文件
...
// Draw points
ctx.beginPath()
ctx.arc(20, 20, 2, 0, 2 * Math.PI)
ctx.setFillStyle('red')
ctx.fill()
ctx.beginPath()
ctx.arc(200, 20, 2, 0, 2 * Math.PI)
ctx.setFillStyle('lightgreen')
ctx.fill()
ctx.beginPath()
ctx.arc(20, 100, 2, 0, 2 * Math.PI)
ctx.arc(200, 100, 2, 0, 2 * Math.PI)
ctx.setFillStyle('blue')
ctx.fill()
ctx.setFillStyle('black')
ctx.setFontSize(12)
// Draw guides
ctx.beginPath()
ctx.moveTo(20, 20)
ctx.lineTo(20, 100)
ctx.lineTo(150, 75)
ctx.moveTo(200, 20)
ctx.lineTo(200, 100)
ctx.lineTo(70, 75)
ctx.setStrokeStyle('#AAAAAA')
ctx.stroke()
// Draw quadratic curve
ctx.beginPath()
ctx.moveTo(20, 20)
ctx.bezierCurveTo(20, 100, 200, 100, 200, 20)
ctx.setStrokeStyle('black')
ctx.stroke()
ctx.draw()
...
针对 moveTo(20, 20) bezierCurveTo(20, 100, 200, 100, 200, 20) 的三个关键坐标如下:
实际项目中我们能通过贝塞尔曲线实现更加复杂和炫酷的效果
在画布上绘制被填充的文本
参数含义:
string text:在画布上输出的文本
number x:绘制文本的左上角 x 坐标位置
number y:绘制文本的左上角 y 坐标位置
number maxWidth:需要绘制的最大宽度,可选
设置字体的字号
设置文字的竖直对齐
参数含义:
textBaseline取值
top 顶部对齐
bottom 底部对齐
middle 居中对齐
normal 默认值
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.setStrokeStyle('red')
ctx.moveTo(5, 75)
ctx.lineTo(295, 75)
ctx.stroke()
ctx.setFontSize(20)
ctx.setTextBaseline('top')
ctx.fillText('top', 5, 75)
ctx.setTextBaseline('middle')
ctx.fillText('middle', 50, 75)
ctx.setTextBaseline('bottom')
ctx.fillText('bottom', 120, 75)
ctx.setTextBaseline('normal')
ctx.fillText('normal', 200, 75)
ctx.draw()
...
设置文字的对齐
参数含义:
align取值
left 左对齐
center 居中对齐
right 右对齐
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.setStrokeStyle('red')
ctx.moveTo(150, 20)
ctx.lineTo(150, 170)
ctx.stroke()
ctx.setFontSize(15)
ctx.setTextAlign('left')
ctx.fillText('textAlign=left', 150, 60)
ctx.setTextAlign('center')
ctx.fillText('textAlign=center', 150, 80)
ctx.setTextAlign('right')
ctx.fillText('textAlign=right', 150, 100)
ctx.draw()
...
测量文本尺寸信息。目前仅返回文本宽度。同步接口。
参数含义:
string imageResource:所要绘制的图片资源
number sx:源图像的矩形选择框的左上角 x 坐标
number sy:源图像的矩形选择框的左上角 y 坐标
number sWidth:源图像的矩形选择框的宽度
number sHeight:源图像的矩形选择框的高度
number dx:图像的左上角在目标 canvas 上 x 轴的位置
number dy:图像的左上角在目标 canvas 上 y 轴的位置
number dWidth:在目标画布上绘制图像的宽度,允许对绘制的图像进行缩放
number dHeight:在目标画布上绘制图像的高度,允许对绘制的图像进行缩放
有三个版本的写法:
这里不做代码示例,调用时按需传入对应参数即可
在调用后,之后创建的路径其横纵坐标会被缩放。多次调用倍数会相乘
参数含义:
number scaleWidth:横坐标缩放的倍数 (1 = 100%,0.5 = 50%,2 = 200%)
number scaleHeight:纵坐标轴缩放的倍数 (1 = 100%,0.5 = 50%,2 = 200%)
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.strokeRect(10, 10, 25, 15)
ctx.scale(2, 2)
ctx.strokeRect(10, 10, 25, 15)
ctx.scale(2, 2)
ctx.strokeRect(10, 10, 25, 15)
ctx.draw()
...
以原点为中心顺时针旋转当前坐标轴。多次调用旋转的角度会叠加。原点可以用 translate 方法修改
参数含义:
number rotate:旋转角度,以弧度计 degrees * Math.PI/180;degrees 范围为 0-360
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.strokeRect(100, 10, 150, 100)
ctx.rotate(20 * Math.PI / 180)
ctx.strokeRect(100, 10, 150, 100)
ctx.rotate(20 * Math.PI / 180)
ctx.strokeRect(100, 10, 150, 100)
ctx.draw()
...
对当前坐标系的原点 (0, 0) 进行变换。默认的坐标系原点为页面左上角。
参数含义:
number x:水平坐标平移量
number y:竖直坐标平移量
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.strokeRect(10, 10, 150, 100)
ctx.translate(20, 20)
ctx.strokeRect(10, 10, 150, 100)
ctx.translate(20, 20)
ctx.strokeRect(10, 10, 150, 100)
ctx.draw()
...
设置线条的宽度
设置线条的端点样式
参数含义:
lineCap 的合法值
butt 向线条的每个末端添加平直的边缘。
round 向线条的每个末端添加圆形线帽。
square 向线条的每个末端添加正方形线帽。(和butt效果差不多,会比butt效果略长)
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.beginPath()
ctx.setLineCap('butt')
ctx.setLineWidth(10)
ctx.moveTo(10, 30)
ctx.lineTo(150, 30)
ctx.stroke()
ctx.beginPath()
ctx.setLineCap('round')
ctx.setLineWidth(10)
ctx.moveTo(10, 50)
ctx.lineTo(150, 50)
ctx.stroke()
ctx.beginPath()
ctx.setLineCap('square')
ctx.setLineWidth(10)
ctx.moveTo(10, 70)
ctx.lineTo(150, 70)
ctx.stroke()
ctx.draw()
...
设置线条的交点样式
参数含义:
lineJoin 的合法值
bevel 斜角
round 圆角
miter 尖角
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.beginPath()
ctx.setLineJoin('bevel')
ctx.setLineWidth(10)
ctx.moveTo(50, 10)
ctx.lineTo(140, 50)
ctx.lineTo(50, 90)
ctx.stroke()
ctx.beginPath()
ctx.setLineJoin('round')
ctx.setLineWidth(10)
ctx.moveTo(90, 10)
ctx.lineTo(180, 50)
ctx.lineTo(90, 90)
ctx.stroke()
ctx.beginPath()
ctx.setLineJoin('miter')
ctx.setLineWidth(10)
ctx.moveTo(130, 10)
ctx.lineTo(220, 50)
ctx.lineTo(130, 90)
ctx.stroke()
ctx.draw()
...
设置最大斜接长度。斜接长度指的是在两条线交汇处内角和外角之间的距离。当 CanvasContext.setLineJoin() 为 miter 时才有效。超过最大倾斜长度的,连接处将以 lineJoin 为 bevel 来显示。
参数含义:
number miterLimit:最大斜接长度
设定阴影样式。
参数含义:
number offsetX:阴影相对于形状在水平方向的偏移,默认值为 0。
number offsetY:阴影相对于形状在竖直方向的偏移,默认值为 0。
number blur:阴影的模糊级别,数值越大越模糊。范围 0- 100。,默认值为 0。
string color:阴影的颜色。默认值为 black。
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
ctx.setFillStyle('red')
ctx.setShadow(10, 50, 50, 'blue')
ctx.fillRect(10, 10, 150, 75)
ctx.draw()
...
设置全局画笔透明度。
保存绘图上下文。
恢复之前保存的绘图上下文。
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
// save the default fill style
ctx.save()
ctx.setFillStyle('red')
ctx.fillRect(10, 10, 150, 100)
// restore to the previous saved state
ctx.restore()
ctx.fillRect(50, 50, 150, 100)
ctx.draw()
...
从原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。可以在使用 clip 方法前通过使用 save 方法对当前画布区域进行保存,并在以后的任意时间通过restore方法对其进行恢复。
示例
// js文件
...
const ctx = wx.createCanvasContext('canvas')
wx.downloadFile({
url: 'http://is5.mzstatic.com/image/thumb/Purple128/v4/75/3b/90/753b907c-b7fb-5877-215a-759bd73691a4/source/50x50bb.jpg',
success: function (res) {
ctx.save()
ctx.beginPath()
ctx.arc(50, 50, 25, 0, 2 * Math.PI)//先画一个圆形
ctx.clip()//裁剪圆形
ctx.drawImage(res.tempFilePath, 25, 25)//绘制图片只能在裁剪的圆形范围内
ctx.restore()
ctx.drawImage(res.tempFilePath, 100,25,50, 50)//未调用clip方法
ctx.draw()
}
})
...
以上就上小程序绘图中常用到的API,本文参考了微信小程序官方文档进行归总,文章中有出现错误,欢迎指正。如果你喜欢我的文章,欢迎给我留言点赞,谢谢!