在canvas上画图
所有在<canvas/>中的画图必须使用js实现
<!--wxml-->
<canvas canvas-id="myCanvas" style="border:1px solid;">
<!--js-->
const ctx = wx.createCanvasContext("myCanvas");
ctx.setFillStyle("red");
ctx.fillRect(10,10,150,75);
ctx.draw()
第一步:创建一个Canvas绘图上下文
首先,我们需要创建一个Canvas绘图上下文CanvasContext.
CanvasContext是一个小程序内创建的一个对象,会有一些绘图的方法.
const ctx = wx.createCanvasContext("myCanvas")
第二步,使用canvas绘图上下文进行绘图描述
接着,我们来描述要在canvas中绘制什么内容.
设置绘图上下文的填充色为红色:
ctx.setFillStyle("red")
用fillRect(x,y,width,height)方法画一个矩形,填充为刚刚设置的红色:
ctx.fillRect(10,10,150,75)
第三步:画图
告诉<canvas/>组件你要将刚刚的描述绘制上去:
ctx.draw();
结果:

微信小程序API gradient(如何绘制渐变效果)
渐变能用于填充一个矩形,圆形,线,文字等.填充色可以不固定定位固定的一种颜色,我们提供两种颜色渐变的方法:
- createLinerGradient(x,y,x1,y1) -创建一个线性的渐变
- createCircularGradient(x,y,r) -创建一个圆心开始的渐变
一旦我们创建了一个渐变对象,我们必须添加两个颜色渐变点.
addColorStop(positon.color)方法用于制定颜色渐变点的位置和颜色,位置必须位于0到1之间.可以用setFillStyle()和setStrokeStyle()方法设置渐变,然后进行画图描述.
使用createLinearGradient()
const ctx = wx.createCanvasContext('myCanvas');
//create linear gradient
const grd = ctx.createLiearGradient(0,0,200,0);
grd.addStopColorStop(0,'red');
grd.addStopColorStop(1,'white');
//Fill with gradient
ctx.setFillStyle(grd);
ctx.fillRect(10,10,150,80);
ctx.draw()

使用createCircularGradient()
const ctx = wx.createCanvasContext('myCanvas');
//create circular gradient
const grd = ctx.createCircularGradient(75, 50, 50)
grd.addColorStop(0, 'red')
grd.addColorStop(1, 'white')
//Fill with gradient
ctx.setFillStyle(grd)
ctx.fillRect(10,10,150,80);
ctx.draw()

绘图导出图片
wx.canvasToTempFilePath(OBJECT)
把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径.
OBJECT参数说明:
属性名 | 类型 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|
x | Number | 否 | 画布x轴起点(默认0) | 1.2.0 |
y | Number | 否 | 画布y轴起点(默认为0) | 1.2.0 |
width | Number | 否 | 画布宽度(默认为canvas宽度-x) | 1.2.0 |
height | Number | 否 | 画布高度(默认为canvas高度-y) | 1.2.0 |
destWidth | Number | 否 | 输出图片宽度(默认为width) | 1.2.0 |
destHeight | Number | 否 | 输出图片高度(默认为height) | 1.2.0 |
canvasId | String | 是 | 画布标识,传入<canvas/>的canvas-id | |
fileType | String | 否 | 目标文件的类型,只支持'jpg'或'png'.默认为'png' | 1.7.0 |
quality | Number | 否 | 图片的质量,取值范围为(0,1],不在范围内时当做1.0处理 | 1.7.0 |
success | Function | 否 | 接口调用成功的回调 | |
fail | Function | 否 | 接口调用失败的回调 | |
complete | Function | 否 | 接口调用结束的回调函数(调用成功或者失败都会执行) |
示例代码
wx.canvasToTempFilePath({
x: 100,
y: 200,
width: 50,
height: 50,
destWidth: 100,
destHeight: 100,
canvasId: 'myCanvas',
success: function(res) {
console.log(res.tempFilePath)
}
})
绘图设置阴影setShadow
canvasContext.setShadow
定义:设置阴影样式.
TIPS:如果没有设置.offsetX默认值为0,offsetY默认值为0,blur默认值为0,color默认值为black.
参数
参数 | 类型 | 范围 | 定义 |
---|---|---|---|
offsetX | Number | 阴影相对于形状在水平方向的偏移 | |
offsetY | Number | 阴影相对于形状在竖直方向的偏移 | |
blur | Number | 0~100 | 阴影的模糊级别,数值越大越模糊 |
color | color | 阴影的颜色 |
示例代码
const ctx = wx.createCanvasContext("myCanvas");
ctx.setFillStyle("red");
ctx.setShadow(10,50,50,"blue");
ctx.fillRect(10,10,150,75);
ctx.draw();
绘制线条端点样式
canvasContext.setLineCap
定义:设置线条的端点样式
参数:
参数 | 类型 | 范围 | 说明 |
---|---|---|---|
lineCap | String | 'butt','round','square' | 线条结束端点样式 |
示例代码
const ctx = wx.createCanvasContext("myCanvas");
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(150, 10);
ctx.stroke();
ctx.beginPath()
ctx.setLineCap('butt')
ctx.setLineWidth(10)
ctx.moveTo(10, 30)
ctx.lineTo(150, 30)
ctx.stroke()
ctx.beginPath();
ctx.setLineCap('square');
ctx.setLineWidth(10);
ctx.moveTo(10, 70);
ctx.lineTo(150, 70);
ctx.stroke();
ctx.beginPath();
ctx.setLineCap('round');
ctx.setLineWidth(10);
ctx.moveTo(10, 50);
ctx.lineTo(150, 50);
ctx.stroke();
ctx.draw();

绘图setLineJoin,设置线条交点样式
canvasContext.setLineJoin
定义
设置线条的交点样式.
参数:
参数 | 类型 | 范围 | 说明 |
---|---|---|---|
lineJoin | String | 'bevel','round','miter' | 线条结束交点样式 |
示例代码
const ctx = wx.createCanvasContext('myCanvas')
ctx.beginPath()
ctx.moveTo(10, 10)
ctx.lineTo(100, 50)
ctx.lineTo(10, 90)
ctx.stroke()
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.arc
定义:画一条弧线
TIPS:创建一个圆可以用arc()方法指定起始弧度为0,终止弧度为2*Math.PI.
TIPS:用stroke()或者fill()方法来在canvas中画弧线.
参数:
参数 | 类型 | 说明 |
---|---|---|
x | Number | 圆的x坐标 |
y | Number | 圆的y坐标 |
r | Number | 圆的半径 |
sAngle | Number | 起始弧度,单位弧度(在三点钟方向) |
eAngle | Number | 终止弧度 |
counterclockwise | Boolean | 可选,指定弧度的方向是逆时针还是顺时针.默认是false,即顺时针. |
示例代码:
const ctx = wx.createCanvasContext("myCanvas");
//画圆
ctx.arc(100, 75, 50, 0, 2 * Math.PI);
ctx.setFillStyle("pink");
ctx.fill();
//画坐标轴
ctx.beginPath();
ctx.moveTo(40, 75);
ctx.lineTo(160, 75);
ctx.moveTo(100, 15);
ctx.lineTo(100, 135);
ctx.setStrokeStyle("#AAAAAA")
ctx.stroke();
//标注区间
ctx.beginPath();
ctx.setFillStyle('black');
ctx.fillText("0", 165, 78);
ctx.fillText("0.5*PI", 83, 145);
ctx.fillText("1*PI", 15, 78);
ctx.fillText("1.5*PI", 83, 10);
//画点
ctx.beginPath();
ctx.arc(100, 75, 2, 0, 2 * Math.PI);
ctx.setFillStyle("green");
ctx.fill();
ctx.beginPath();
ctx.arc(100, 25, 2, 0, 2 * Math.PI);
ctx.setFillStyle("blue");
ctx.fill();
ctx.beginPath();
ctx.arc(150, 75, 2, 0, 2 * Math.PI);
ctx.setFillStyle("red");
ctx.fill();
ctx.beginPath();
ctx.arc(50, 75, 2, 0, 2 * Math.PI);
ctx.setFillStyle("yellow");
ctx.fill();
ctx.beginPath();
ctx.arc(100, 125, 2, 0, 2 * Math.PI);
ctx.setFillStyle("blue");
ctx.fill();
// 画弧线
ctx.beginPath();
ctx.arc(100,75,50,0,1.5*Math.PI);
ctx.setStrokeStyle('purple');
ctx.stroke();
ctx.draw();

属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
canvas-id | String | canvas组件的唯一标识符 | |
disable-scroll | Boolean | false | 当在 canvas 中移动时且有绑定手势事件时,禁止屏幕滚动以及下拉刷新 |
bindtouchstart | EventHandle | 手指触摸动作开始 | |
bindtouchmove | EventHandle | 手指触摸后移动 | |
bindtouchend | EventHandle | 手指触摸动作结束 | |
bindtouchcancel | EventHadle | 手指触摸动作被打断,如来电提醒,弹窗 | |
bindlongtap | EventHandle | 手指长按500ms之后触发,触发了长按事件后进行移动不会触发屏幕的滚动 | |
binderror | EventHandle | 当发生错误时触发error事件,detail={errMsg:"something wrong"} |
注:
- canvas标签默认宽度为300px,高度为225px;
- 同一页面中的canvas-id不可以重复,如果使用一个已经出现过的canvas-id,该canvas标签对应的画布将被隐藏并不再正常工作.
<!-- canvas.wxml -->
<canvas style="width: 300px; height: 200px;" canvas-id="firstCanvas"></canvas>
<!-- 当使用绝对定位时,文档流后边的canvas的显示层级高于前边的canvas-->
<canvas style="width: 400px; height: 500px;" canvas-id="secondCanvas"></canvas>
<!-- 因为canvas-id与前一个canvas重复,该canvas不会显示,并会发送一个错误事件到AppService -->
<canvas style="width: 400px; height: 500px;" canvas-id="secondCanvas" binderror="canvasIdErrorCallback"></canvas>
<!-- canvas.js -->
Page({
canvasIdErrorCallback: function (e) {
console.error(e.detail.errMsg)
},
onReady: function (e) {
//使用wx.createContext获取绘图上下文context
var context = wx.createCanvasContext('firstCanvas')
context.setStrokeStyle("#00ff00")
context.setLineWidth(5)
context.rect(0,0,200,200)
context.stroke()
context.setStrokeStyle ("#ff0000")
context.setLineWidth(2)
context.moveTo(160,100)
context.arc(100,100,60,0,2*Math.PI,true)
context.moveTo(140,100)
context.arc(100,100,40,0,Math.PI,false)
context.moveTo(85,80)
context.arc(80,80,5,0,2*Math.PI,true)
context.moveTo(125,80)
context.arc(120,80,5,0,2*Math.PI,true)
context.stroke()
context.draw()
}
})

网友评论