之前提到过组件,再组件中画图必须通过本小结介绍的API实现,中存在一个二维坐标体系,左上角的坐标为(0,0)所有绘图API都会基于这个坐标体系进行绘制。绘图过程大致可以分为3步:
示例代码如下:
Page({
onReady:function(){
//第1步,创建执行上下文
var canvasContext = wx.createCanvasContext('myCanvas');
//第2步,设置绘制描述
canvasContext.setFillStyle('red');
canvasContext.fillRect(10,10,110,110);
//第3步,绘图
canvasContext.draw();
}
});
执行结果如下:
1.基础API
1)wx.createCanvasContext(canvasId)
在绘图时我们需要调用wx.createCanvasContext()创建一个绘图上下文context对象,一个canvasContext通过canvasId与一一绑定,canvasContext仅作用于对应的,通过调用绘图上下文相关方法实现绘图功能,示例代码如下:
var context = wx.createCanvasContext('myCanvas');
2)wx.canvasToTempFilePath(Object)
将当前画布内容导出生成图片,并返回文件路径,Obeject参数的属性如下:
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
x | number | 0 | 否 | 指定的画布区域的左上角横坐标 | 1.2.0 |
y | number | 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-id |
||
fileType | string | png | 否 | 目标文件的类型 | 1.7.0 |
quality | number | 是 | 图片的质量,目前仅对 jpg 有效。取值范围为 (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(res){
//打印出图片路径
console.log(res.tempFilePatj)
}
});
2.canvasContext对象方法
所有绘图行为都需要调用上下文相关方法实现,这些方法整体可以分为10类:样式、渐变、线条样式、矩阵、路径、变形、文字、图片、混合、其他。
1)样式
样式设置会全局作用于全局,如果没有覆盖,后续绘图的颜色将沿用之前的设置,样式设置相关方法如下:
示例代码如下:
Page({
onReady:function(){
//创建执行上下文
var canvasContext = wx.createCanvasContext('myCanvas');
//填充方形
canvasContext.setFillStyle('red');
canvasContext.fillRect(10,10,50,50);
//绘制方框
canvasContext.setStrokeStyle('#0000ff');
canvasContext.strokeRect(70,10,50,50);
//绘制带阴影方形
canvasContext.setShadow(10,10,60,'rgb(255,255,30)');
//这里填充的方形受第一句代码影响也为红色
canvasContext.fillRect(130,10,50,50);
canvasContext.draw();
}
});
2)渐变
渐变相关方法用于创建渐变对象,渐变对象可作为参数传入绘图相关方法,创建渐变的坐标是基于的坐标,而不是被填充图形的坐标,在使用渐变填充图像时一定要注意坐标的转换,创建渐变相关方法如下:
示例代码如下:
Page({
onReady:function(){
var canvasContext = wx.createCanvasContext('myCanvas'),
linearGradient,circularGradient,colorStop;
//需要根据图形对渐变坐标进行换算
linearGradient = canvasContext.createLinearGradient(0,0,100,0);
//创建渐变时,至少创建两个渐变点,开始和结束
linearGradient.addColorStop(0,'black');
linearGradient.addColorStop(1,'red');
//填充方形
canvasContext.setFillStyle(linearGradient);
canvasContext.fillRect(10,10,100,100);
//需要根据图形对渐变坐标进行换算
circularGradient = canvasContext.createCircularGradient(170,60,50);
//可以创建多个渐变点
circularGradient.addColorStop(0,'red');
circularGradient.addColorStop(0.16,'orange');
circularGradient.addColorStop(0.35,'yellow');
circularGradient.addColorStop(0.5,'green');
circularGradient.addColorStop(0.66,'cyan');
circularGradient.addColorStop(0.83,'blue');
circularGradient.addColorStop(1,'purple');
//填充方形
canvasContext.setFillStyle(circularGradient);
canvasContext.fillRect(120,10,100,100);
canvasContext.draw();
}
});
执行结果如下:
3)线条样式
和样式设置一样,线条样式设置会全局作用于全局,如果没有覆盖,后续绘图的设置将延用之前的设置,线条样式方法如下:
示例代码如下:
var _fn;
Page({
onReady:function(){
var canvasContext = wx.createCanvasContext('myCanvas');
//设置线宽度
canvasContext.setLineWidth(10);
//端点样式为正方形,不会截取线条宽度
canvasContext.setLineCap('square');
_fn.drawLine(canvasContext,[10,20],[150,20]);
//端点样式为正方形,但会截取线条宽度
canvasContext.setLineCap('butt');
_fn.drawLine(canvasContext,[10,40],[150,40]);
//端点样式为圆形,不会截取线条宽度
canvasContext.setLineCap('round');
_fn.drawLine(canvasContext,[10,60],[150,60]);
//恢复为默认线条边界
canvasContext.setLineCap('square');
//交叉处为平角
canvasContext.setLineJoin('bevel');
_fn.drawAngle(canvasContext,[10,80]);
//交叉处为圆角
canvasContext.setLineJoin('round');
_fn.drawAngle(canvasContext,[50,80]);
//交叉处为尖角
canvasContext.setLineJoin('miter');
_fn.drawAngle(canvasContext,[90,80]);
//设置交叉处为尖角
canvasContext.setLineJoin('miter');
canvasContext.setMiterLimit(1);
_fn.drawAngle(canvasContext,[10,140]);
canvasContext.setMiterLimit(2);
_fn.drawAngle(canvasContext,[50,140]);
canvasContext.setMiterLimit(3);
_fn.drawAngle(canvasContext,[90,140]);
canvasContext.draw();
}
})
_fn= {
drawLine:function(canvasContext,start,end){
canvasContext.beginPath()
canvasContext.moveTo(start[0],start[1])
canvasContext.lineTo(end[0],end[1])
canvasContext.stroke();
},
drawAngle:function(canvasContext,beginPoint){
canvasContext.beginPath()
canvasContext.moveTo(beginPoint[0],beginPoint[1]);
canvasContext.lineTo(beginPoint[0]+40,beginPoint[1]+20)
canvasContext.lineTo(beginPoint[0],beginPoint[1]+40)
canvasContext.stroke()
}
}
执行结果如下:
4)矩形
矩形相关方法如下:
示例代码如下:
Page({
onReady:function(){
var canvasContext = wx.createCanvasContext('myCanvas');
//绘制线框矩形
canvasContext.rect(10,10,30,30);
canvasContext.stroke();
canvasContext.draw();
//绘制填充矩形
canvasContext.rect(50,10,30,30);
canvasContext.fill();
canvasContext.draw(true);//传入参数true,表示接着上次继续绘制
//绘制填充矩形
canvasContext.fillRect(10,50,30,30);
canvasContext.draw(true);
//绘制线框矩形
canvasContext.strokeRect(50,50,30,30);
canvasContext.draw(true);
//清除矩形区域
canvasContext.clearRect(25,25,40,40);
canvasContext.draw(true);
}
});
5)路径
路径绘制并不会在画布上绘制形状,而是创建一个线条路径,创建的路径可被stroke()绘制线条,也可被fill()填充区域,绘制路径开始时需要调用beginPath()方法,结束时需要调用closePath()方法,上文rect()方法可认为是绘制矩形路径的一个快截方法,调用路径方法组合,我们可以绘制任何形状图形,路径方法如下:
示例代码如下:
var _fn;
Page({
onReady:function(){
var canvasContext = wx.createCanvasContext('myCanvas');
//绘制三家乡线条
_fn.drawTrianglePath(canvasContext,[10,60]);
canvasContext.stroke();
canvasContext.draw();
//绘制扇形
_fn.drawSectorPath(canvasContext,[60,10],55,0,60);
canvasContext.setStrokeStyle('black');
canvasContext.setLineWidth(5);
canvasContext.setFillStyle('yellow');
canvasContext.stroke();
canvasContext.fill();
canvasContext.draw(true);//若不加true则无法显示前一项内容
//绘制二次贝塞尔曲线
canvasContext.setLineWidth(1);
_fn.drawQuadraticCurve(canvasContext,[10,70],[10,170],[100,70]);
canvasContext.stroke();
canvasContext.draw(true);
//绘制贝塞尔三次曲线
_fn.drawBezierCurve(canvasContext,[110,70],[110,150],[210,150],[210,70]);
canvasContext.stroke();
canvasContext.draw(true);
}
});
_fn ={
//绘制三角形
drawTrianglePath:function(canvasContext,beginPos){
canvasContext.moveTo(beginPos[0],beginPos[1]);
//开始路径
canvasContext.beginPath();
//绘制3条边
canvasContext.lineTo(beginPos[0]+30,beginPos[1]-50);
canvasContext.lineTo(beginPos[0]+60,beginPos[1]);
canvasContext.lineTo(beginPos[0],beginPos[1]);
//关闭路径
canvasContext.closePath();
},
//绘制扇形
drawSectorPath:function(canvasContext,beginPos,radius,startAngle,endAngle){
canvasContext.moveTo(beginPos[0],beginPos[1]);
//开始路径
canvasContext.beginPath();
canvasContext.lineTo(beginPos[0]+radius,beginPos[1]);//绘制边线
canvasContext.arc(beginPos[0],beginPos[1],radius,startAngle*Math.PI/180,endAngle*Math.PI/180); /*绘制弧线*/
canvasContext.lineTo(beginPos[0],beginPos[1]);//绘制边线
//关闭路径
canvasContext.closePath();
},
//绘制二次贝塞尔曲线路径
drawQuadraticCurve:function(canvasContext,startPoint,controlPoint,endPoint){
canvasContext.beginPath();
canvasContext.moveTo(startPoint[0],startPoint[1]);
canvasContext.quadraticCurveTo(controlPoint[0],controlPoint[1],endPoint[0],endPoint[1]);
//这里不需要关闭路径,否则路径将自动首尾相连
},
//绘制三次贝塞尔曲线路径
drawBezierCurve:function(canvasContext,startPoint,controlPoint1,controlPoint2,endPoint){
canvasContext.beginPath();
canvasContext.moveTo(startPoint[0],startPoint[1]);
canvasContext.bezierCurveTo(controlPoint1[0],controlPoint1[1],controlPoint2[0],controlPoint2[1],endPoint[0],endPoint[1]);
//这里不需要关闭路径,否则路径将自动首尾相连
}
}
6)变形
变形相关方法会整体影响之后绘图方法的坐标体系,每个方法之前可以互相迭代,可以认为变形是对整体坐标体系的变形。变形相关方法如下:
示例代码如下:
Page({
canvasContext:null,
onReady:function(){
this.canvasContext = wx.createCanvasContext('myCanvas');
},
translate:function(){
this.canvasContext.translate(10,10);//横纵坐标均移动10px
},
rotate:function(){
this.canvasContext.rotate(30*Math.PI/180);/*旋转30度 */
},
scale:function(){
this.canvasContext.scale(2,2);//x,y均放大2倍,放大后线条也相应放大
},
drawReact:function(){
var context = this.canvasContext;
context.restore();//恢复绘制条件,并弹栈
context.rect(0,0,15,15);
context.stroke();
context.draw(true);//基于上次图形继续绘制
}
});
执行结果如下:
7)文字
文字相关方法能将文字输出到画布中,字体颜色能通过setFillStyle()方法修改,其方法包括fillText(text,x,y):在画布上绘制被填充的文本,参数说明如下:text:在画布上输出的文本;x:绘制文本的左上角x坐标位置;y:绘制文本的左上角y坐标位置
setFontSize(fontSize):设置字体的字号,参数包括fontSize:字体的字号
示例代码如下:
Page({
onReady:function(){
var canvasContext = wx.createCanvasContext('myCanvas');
canvasContext.fillText('中文',10,20)
//设置字体大小
canvasContext.setFontSize(24);
//改变字体颜色
canvasContext.setFillStyle('red');
canvasContext.fillText('English',100,20)
canvasContext.draw();
}
});
8)图片
图片方法只有一个drawimage(imageResource,x,y,width,height):用户在画布上绘制图片,方法如下:imageResource:所要绘制的图片资源,可以是网络资源,也可以是本地资源相对路径;x:图像左上角的x坐标;y:图形左上角的y坐标;width:图形宽度;height:图形高度
示例代码如下:
Page({
onReady:function(){
var canvasContext = wx.createCanvasContext('myCanvas');
canvasContext.drawImage('../../images/dog.png',1,1,100,100);
canvasContext.draw();
}
});
执行结果如下:
9)混合
混合方法只有一个setGlobalAlpha(alpha):设置全局画笔透明度。参数包括alpha:透明度,o表示完全透明,1表示完全不透明
示例代码如下:
Page({
onReady:function(){
var canvasContext = wx.createCanvasContext('myCanvas');
canvasContext.setFillStyle('blue');
canvasContext.fillRect(10,10,100,100);
canvasContext.setGlobalAlpha(0.5);
canvasContext.fillRect(50,50,100,100);
//对图片也生效
canvasContext.drawImage('../../images/dog.png',80,80,100,100);
canvasContext.draw();
}
});
执行结果如下:
10)其他
其余一些方法主要涉及绘画步骤和绘制方式,涉及的方法如下:
Page({
onReady:function(){
var canvasContext = wx.createCanvasContext('myCanvas');
canvasContext.setFillStyle('red');
canvasContext.save();
canvasContext.setFillStyle('blue');
canvasContext.fillRect(10,10,100,100);
//恢复到之前红色设置
canvasContext.restore();
canvasContext.fillRect(120,10,100,100);
canvasContext.draw();
}
});
执行结果如下: