5.动画
5.1 动画实例
使用wx.createAnimation(OBJECT)可以创建一个动画实例animation,参数说明如下:
timingFunction的有效值:
示例代码如下:
wx.createAnimation({
duration: 5000, //持续5秒
timingFunction: '"ease-in"', //低速开始
delay: 0,
transformOrigin: '"50% 50% 0"',
})
5.2 动画的描述
动画实例可调用animation对象的相关方法来描述动画,调用结束后会返回自身。animation对象的方法可分为6类,分别用于控制组件的样式、旋转、缩放、偏移、倾斜和矩阵变形。
控制组件样式的方法如表:
控制组件缩放的方法:
控制组件偏移的方法如下:
控制组件倾斜的方法如下:
控制组件矩阵变形的方法如下:
animation对象允许用户将任意多个动画方法追加在同一行代码中,表示同时开始这一组动画内容,在调用动画操作方法后还需要调用step()来表示一组动画完成。
5.3 动画的导出
声明完animation对象并描述了动画方法后,还需要使用export()将该对象导出到组件的animation属性中,这样才可以使组件具有动画效果。
小程序也允许多次调用export()方法导出不同的动画描述方法,刚才的js代码可更新为:
综合应用示例代码:
5.动画
animation的用法
这是动画组件
/*wxss*/
.animation-view{
width: 220rpx;
height: 220rpx;
background-color: lightgreen;
margin: 20rpx auto;
line-height: 220rpx;
}
button{
margin: 10rpx;
}
//js
Page({
//旋转
rotate:function(){
this.animation.rotate(45).step()
this.setData({
animation:this.animation.export()
})
},
//缩放
scale:function(){
this.animation.scale(0.5).step()
this.setData({
animation: this.animation.export()
})
},
//偏移
translate:function(){
this.animation.translate(100,50).step()
this.setData({
animation: this.animation.export()
})
},
//倾斜
skew:function(){
this.animation.skewX(45).step()
this.setData({
animation: this.animation.export()
})
},
//同时动画
sync:function(){
this.animation.rotate(45).scale(0.5).translate(100,50).skewX(45).step()
this.setData({
animation: this.animation.export()
})
},
//依次动画
queue:function(){
this.animation.rotate(45).step().scale(0.5).translate(100,50).step().skewX(45).step()
this.setData({
animation: this.animation.export()
})
},
//还原
reset:function(){
this.animation.rotate(0).scale(1).translate(0,0).skewX(0).step()
this.setData({
animation: this.animation.export()
})
},
onReady:function(){
this.animation = wx.createAnimation({
duration:3000
})
}
})
7.绘图
7.1 准备工作
1)画布坐标系
原理:画布坐标系中原点位置在画布矩形框的左上角,即(0,0)坐标位置,水平方向为X轴,其正方向为向右延伸,垂直方向为Y轴,其正方向为向下延伸,
2)创建空白画布
使用
画布的默认尺寸是宽度为300px、高度为225px,用户可根据实际需要在wxss中重新定义。
3)创建画布上下文对象
使用wx.createCanvasContext(canvasId)创建画布上下文对象,然后使用该对象的方法进行画笔设置和绘图工作。
示例代码如下:
Page({
onLoad:function(options){
const ctx = wx.createCanvasContext("myCanvas")
}
})
7.2 绘制矩形
1)创建矩形
使用画布对象的rect()方法创建矩形,然后使用fill()或stroke()方法在画布上填充实心矩形或描边空心矩形,其语法格式如下:
ctx.rect(x,y,width,height)
参数说明如下:
示例代码:
Page({
onLoad:function(options){
const ctx = wx.createCanvasContext("myCanvas")
ctx.rect(50,50,200,200)
ctx.setFillStyle("orange") //填充颜色
ctx.fill() //描述填充矩形动作
ctx.draw() //在画布上执行全部描述
}
})
2)填充矩形
使用画布对象的fillRect()方法直接在画布上填充实心矩形,语法格式如下:
ctx.fillRect(x,y,width,height)
3)描边矩形
使用画布对象的strokeRect()方法直接在画布上描边空心矩形,语法格式如下:
ctx.strokeRect(x,y,width,height)
4)清空矩形区域
使用画布对象的clearRect()方法清空矩形区域,语法格式如下:
ctx.clearRect(x,y,width,height)
综合应用示例代码:
7.绘制
绘制矩形
button{
margin: 10rpx;
}
//js
Page({
fillRect:function(){
let ctx = this.ctx;
ctx.rect(50,50,200,200)
ctx.setFillStyle("orange")
ctx.fill()
ctx.draw()
},
strokeRect:function(){
let ctx = this.ctx;
ctx.rect(100,100,100,100)
ctx.setFillStyle("purple")
ctx.stroke()
ctx.draw()
},
clearRect:function(){
let ctx = this.ctx
ctx.clearRect(0,0,300,300)
ctx.draw()
},
onLoad:function(options){
this.ctx = wx.createCanvasContext("myCanvas")
}
})
7.3 绘制路径
路径是绘制图形轮廓时画笔留下的轨迹,也可理解成画笔画出的像素点组成的线条。多个点形成线段或曲线,不同线段或曲线相连接又形成了各种形状效果。绘制路径主要有四种方法:
1.绘制线段
两种方法:
1)moveTo(x,y)
将当前画笔直线移动到指定坐标上,并且不留下移动痕迹,可定义线段的初始位置。
2)lineTo(x,y)
将当前画笔直线移动到指定坐标上,并且画出移动痕迹,可进行线段的绘制。
简单应用示例:
7.绘制
7.3.1 绘制线段
//js
Page({
//绘制基本图形
drawSample:function(){
let ctx = this.ctx;
//绘制三角形
ctx.beginPath()
ctx.moveTo(150,75)
ctx.lineTo(225,225)
ctx.lineTo(75,225)
ctx.closePath()
},
//描边路径
strokePath:function(){
let ctx = this.ctx
this.drawSample()
ctx.setStrokeStyle("red")
ctx.stroke()
ctx.draw()
},
//填充路径
fillPath:function(){
let ctx = this.ctx
this.drawSample()
ctx.setFillStyle("blue")
ctx.fill()
ctx.draw()
},
onLoad:function(options){
this.ctx = wx.createCanvasContext("myCanvas")
console.log(this.ctx)
}
})
2.绘制圆弧
使用arc()方法绘制圆弧路径,基本语法格式如下:
ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise)
参数说明如下:
ps:角度单位是弧度,转换公式:弧度=n/180*度数,radians=Math.PI/180*degrees
简单应用示例:
7.绘制
7.3.2 绘制圆弧
//js
Page({
onLoad:function(){
const ctx = wx.createCanvasContext("myCanvas")
ctx.setFillStyle("yellow")
//绘制圆形的脸
ctx.beginPath()
ctx.arc(150,150,80,0,Math.PI*2,true)
ctx.stroke() //勾勒脸的轮廓
ctx.fill()
//填充黑色的左眼
ctx.setFillStyle("black")
ctx.beginPath()
ctx.arc(190,130,10,0,Math.PI*2,true)
ctx.fill()
//填充黑色的右眼
ctx.beginPath()
ctx.arc(110, 130, 10, 0, Math.PI * 2, true)
ctx.fill()
//绘制带有弧度的笑容
ctx.beginPath()
ctx.arc(150, 160, 50, 0, Math.PI, false)
ctx.stroke()
ctx.draw()
}
})
3.绘制曲线
原理:来自贝塞尔曲线,又称为贝兹曲线或贝济埃曲线。由曲线和节点组成,节点上有控制线和控制点可以拖动,曲线在节点控制下可以伸缩,一些矢量图形软件用它来精确绘制曲线。
1)二次方贝塞尔曲线
ctx.quadraticCurveTo(cplx,cply,x,y) //控制点坐标 结束点坐标
2)三次方贝塞尔曲线
ctx.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y) //控制点1的坐标 控制点2坐标 结束点坐标
简单应用示例:
7.绘制
7.3.3 使用三次贝塞尔曲线绘制爱心
//js
Page({
onLoad: function () {
const ctx = wx.createCanvasContext("myCanvas")
ctx.setFillStyle("red")
//三次贝塞尔曲线
ctx.beginPath()
ctx.moveTo(90,55)
ctx.bezierCurveTo(90,52,85,40,65,40)
ctx.bezierCurveTo(35,40,35,77.5,35,77.5)
ctx.bezierCurveTo(35,95,55,117,90,135)
ctx.bezierCurveTo(125,117,145,95,145,77.5)
ctx.bezierCurveTo(145,77.5,145,40,115,40)
ctx.bezierCurveTo(100,40,90,52,90,55)
ctx.fill()
ctx.draw()
}
})
7.4 绘制文本
1.填充文本
使用fillText()方法用于在画布上绘制实心文本内容,语法结构如下:
ctx.fillText(text,x,y,maxWidth)
参数说明如下:
2.设置字体大小
使用setFontSize()方法用于设置字体大小,其语法结构如下:
ctx.setFontSize(fontsize) //fontsize是Number类型,表字体字号大小
3.设置文本基准线
使用setTextBaseline()方法用于设置文本的水平方向基准线,语法结构如下:
ctx.setTextBaseline(textBaseline) //textBaseline值可为top bottom middle normal
//或
ctx.textBaseline=textBaseline //试的时候报错了
4.设置文本对齐方式
ctx.setTextAlign(align) //align值可为left right center
//或
ctx.textAlign=align //也不可用
5.设置字体风格
可使用画布对象的font属性自定义字体风格,语法结构如下:
ctx.font=value
value的默认值10px sans-serif 支持属性如下:
综合应用示例:
7.绘制
7.4 绘制文本
//js
Page({
onLoad: function () {
const ctx = wx.createCanvasContext("myCanvas")
ctx.setFontSize(40)
ctx.setTextBaseline('bottom')
ctx.fillText('你好',30,150)
ctx.setFillStyle("green")
ctx.setTextBaseline('top')
ctx.fillText("微信小程序",80,150) //y坐标相同,但一个在水平基准线上方,一个在下方
ctx.draw()
}
})
7.5 绘制图片
1.绘制原图
使用drawImage()方法绘制图片,语法结构如下:
ctx.drawImage(src,dx,dy) //src 路径 dx dy Number类型 绘制图片左上角在画布此坐标上
2.缩放图片
语法结构如下:
ctx.drawImage(src,dx,dy,dWidth,dHeight) //dWidth dHeight 规定缩放后的宽度和高度
3.图片的切割
ctx.drawImage(src,sx,sy,sWidth,sHeight,dx,dy,dWidth,dHeight)
//sx sy原图的(x,y)坐标位置进行切割截图 sWidth sHeight是截图的矩形的宽高 dx dy切割后图片显示在画布的(dx,dy)位置上
综合应用示例:
7.绘制
7.5 绘制图片
//js
Page({
drawImage01:function(){
let ctx = this.ctx
ctx.drawImage("/images/images01.jpg",0,0)
ctx.draw()
},
drawImage02: function (){
let ctx = this.ctx
ctx.drawImage("/images/images01.jpg", 50, 50,200,200)
ctx.draw()
},
drawImage03: function (){
let ctx = this.ctx
ctx.drawImage("/images/images01.jpg", 210, 90,160,160,50,50,200,200)
ctx.draw()
},
onLoad: function () {
this.ctx = wx.createCanvasContext("myCanvas")
}
})
7.6 颜色与样式
1.颜色透明度
使用setGlobalAlpha()生成半透明色作为画布上的图形轮廓或填充颜色,其语法结构为:
ctx.setGlobalAlpha(alpha) //alpha属性范围0.0~1.0
ps:GlobalAlpha()适合批量设置图形颜色
简单应用示例:
7.绘制
7.6.1 颜色透明度
//js
Page({
drawBox:function(){
let ctx = this.ctx;
ctx.setFillStyle("green");
ctx.fillRect(75,75,150,150)
ctx.draw()
},
setAlpha01:function(){
let ctx = this.ctx
ctx.setGlobalAlpha(1)
this.drawBox()
},
setAlpha02: function () {
let ctx = this.ctx
ctx.setGlobalAlpha(0.5)
this.drawBox()
},
setAlpha03: function () {
let ctx = this.ctx
ctx.setGlobalAlpha(0)
this.drawBox()
},
onLoad: function () {
this.ctx = wx.createCanvasContext("myCanvas")
}
})
2.线条样式
1)设置线条宽度
使用setLineWidth()设置线条宽度,语法格式为:
ctx.setLineWidth(lineWidth) //lineWidth默认单位为px
2)设置线条端点样式
使用setLineCap()设置线条端点样式,语法格式如下:
ctx.setLineCap(lineCap) //lineCap表示线段两边顶端的形状
参数lineCap属性说明如下:
3)设置线条交点样式
使用setLineJoin()设置线条端点样式,语法格式如下:
ctx.setLineJoin(lineJoin) //lineJoin表示线段之间连接处的拐角样式
参数lineJoin属性说明如下:
4)设置虚线效果
使用setLineDash()设置线条为虚线效果,语法格式为:
ctx.setLineDash(pattern,offset)
参数说明如下:
ps:当数组元素为奇数时所有数组元素会自动重复一次,如setLineDash([5,10,5])方法设置线条样式,系统会认为是[5,10,5,5,10,5]的形式
5)设置最大倾斜
使用setMiterLimit()设置最大斜接长度,斜接长度是指两条线交汇处内角和外角之间的距离,仅当setLineJoin()参数值为miter时才有效。语法格式如下:
ctx.setMiterLimit(miterlimit) //miterlimit是Number类型,表示最大斜接长度
简单应用示例:
7.绘制
7.6.2 线条样式
//js
Page({
drawSample: function () {
let ctx = this.ctx;
ctx.beginPath()
ctx.moveTo(150,75)
ctx.lineTo(225,225)
ctx.lineTo(75,225)
ctx.closePath()
ctx.stroke()
ctx.draw()
},
setLineWidth: function () {
this.ctx.setLineWidth(20)
this.drawSample()
},
setLineJoin:function(){
this.ctx.setLineJoin("round")
this.drawSample()
},
setLineDash:function(){
this.ctx.setLineDash([10,10],2)
this.drawSample()
},
//还原
reset:function(){
let ctx = this.ctx
ctx.lineWidth = 10
ctx.lineJoin="miter"
ctx.setLineDash([0],0)
this.drawSample()
},
onLoad: function () {
this.ctx = wx.createCanvasContext("myCanvas")
this.ctx.lineWidth=10
this.drawSample()
console.log(this.ctx)
}
})
3.渐变样式
使用颜色渐变效果来设置图形的轮廓或填充颜色,分为线性渐变与圆形渐变。首先创建具有指定渐变区域的canvasGradient对象
创建线性渐变canvasGradient对象的语法格式如下:
const grd = ctx.createLinearGradient(x0,y0,x1,y1) //渐变的初始位置坐标 渐变的结束位置坐标
创建圆形渐变canvasGradient对象的语法格式如下:
const grd = ctx.createLinearGradient(x,y,r) //渐变起点在圆心,终点在外围圆环
ps:这两种渐变方法创建canvasGradient对象后均可使用addColorStop()方法为渐变效果定义颜色与渐变点,语法格式如下:
grid.addColorStop(position,color)
//position 0~1数值,表渐变点的相对位置,0.5在渐变区域中间 color 有效的颜色值
以上两种方法创建出来的颜色渐变效果都可当作一种特殊颜色值予以画笔
简单应用示例代码:
7.绘制
7.6.3 渐变样式
//js
Page({
linear:function(){
let ctx = this.ctx
//创建渐变
var grd = ctx.createLinearGradient(0,0,200,200)
grd.addColorStop(0,"blue")
grd.addColorStop(1,"lightblue") //这颜色好看!
//画图形
ctx.setFillStyle(grd)
ctx.fillRect(50,50,200,200)
ctx.draw()
},
circular:function(){
let ctx = this.ctx
var grd = ctx.createCircularGradient(0, 0, 200, 200)
grd.addColorStop(0, "purple")
grd.addColorStop(1, "white")
//画图形
ctx.setFillStyle(grd)
ctx.fillRect(50, 50, 200, 200)
ctx.draw()
},
onLoad: function () {
this.ctx = wx.createCanvasContext("myCanvas")
}
})
4.阴影样式
使用setShadow()方法为画布中的图形或文本设置阴影效果,其语法格式如下:
ctx.setShadow(offsetX,offsetY,blur,color) //前三个默认0 color默认black
//offset 阴影相对于图形在水平/垂直方向的偏移 blur 阴影的模糊程度0~100 越大越模糊 color 阴影颜色
还有四个属性用于设置阴影单项样式,如下:
简单应用示例:
7.绘制
7.6.4 阴影样式
//js
Page({
onLoad: function () {
const ctx = wx.createCanvasContext("myCanvas")
ctx.setFillStyle("lightgreen")
ctx.setShadow(10,10,50,"gray")
ctx.fillRect(75,75,150,150)
ctx.draw()
}
})
5.图案填充
使用createPattern()对指定区域进行图案填充,其语法格式如下:
ctx.createPattern(image,repetition)
//image 图案来源,仅支持包内路径和临时路径 repetition 图案重复方向repeat repeat-x repeat-y no-repeat
简单应用示例:
7.绘制
7.6.5 图案填充
//js
Page({
onLoad: function () {
const ctx = wx.createCanvasContext("myCanvas")
const pattern = ctx.createPattern('/images/images01.jpg','repeat')
ctx.setFillStyle(pattern)
ctx.beginPath()
ctx.arc(150,150,100,0,2*Math.PI,true)
ctx.fill()
ctx.draw()
}
})
7.7 保存与恢复
在小程序中save()和restore()方法是绘制复杂图形的快捷方式,用于记录或恢复画布的绘画状态。在绘制复杂图形时有可能临时需要进行多个属性的设置更改(如画笔粗细、填充颜色等效果),在绘制完成后又要重新恢复初始设置进行后续的操作。
7.8 变形与剪裁
1.图像的变形
1)移动
使用translate()方法对图形进行移动处理,其基本格式如下:
ctx.translate(x,y)
ps:每次调用translate()方法都是在上一个translate()方法的基础上继续移动原点的位置,每次都要考虑当前原点位置才能正确移动,如果不希望translate()方法影响每一次移动,可使用save()和restore()方法恢复原状。
2)旋转
小程序中可以使用rotate()方法对图形进行旋转处理,其基本格式如下:
ctx.rotate(angle) //angle 需填顺时针旋转的角度,需换算成弧度单位,负值逆时针旋转
ps:默认情况下,以画布原点坐标为参照点进行图形的旋转,如需指定其他参照点,也可事先使用translate()移动参照点坐标的位置
3)缩放
使用scale()方法对图形进行缩放处理,基本格式如下:
ctx.scale(x,y) //1.0为正常显示
4)矩阵变形
在小程序中transform()方法使用矩阵多次叠加形成更复杂的变化,基本格式如下:
ctx.transform((scaleX,skewX,skewY,scaleY,translateX,translateY)
//scale 水平/垂直缩放 skew 水平/垂直倾斜 translate 水平/垂直移动
如需覆盖原先的矩阵变化效果,可使用setTransform()方法,其语法格式如下:
ctx.setTransform(scaleX,skewX,skewY,scaleY,translateX,translateY)
简单应用示例代码:
7.绘制
7.8.1 图案变形
//js
Page({
drawBox:function(){
let ctx = this.ctx
ctx.setFillStyle("lightgreen")
ctx.fillRect(75,75,150,150)
ctx.draw()
},
translate: function () {
this.ctx.translate(75,75)
this.drawBox()
},
rotate: function () {
this.ctx.rotate(20*Math.PI/180)
this.drawBox()
},
scale: function () {
this.ctx.scale(0.5,0.5)
this.drawBox()
},
transform: function () {
this.ctx.transform(1.25,20*Math.PI/180,0,0.5,50,50)
this.drawBox()
},
onLoad: function (options) {
this.ctx = wx.createCanvasContext("myCanvas")
this.drawBox()
}
})
2.图像的剪裁
使用clip()方法对图形进行剪裁处理,该方法一旦执行,前面的绘制图形代码将起到剪裁画布的作用,超过该图形所覆盖部分的其他区域都将无法进行绘制。
ps:剪裁是不可逆的,下一次使用clip()方法也只能在当前的保留区域继续进行剪裁。
简单应用示例:
7.绘制
7.8.2 图案剪裁
//js
Page({
drawImage: function () {
let ctx = this.ctx
ctx.drawImage('/images/images01.jpg',50,50)
ctx.draw()
},
clip: function () {
let ctx = this.ctx
ctx.save()
ctx.beginPath()
ctx.arc(150,150,100,0,2*Math.PI)
ctx.clip()
ctx.drawImage('/images/images01.jpg',50,50)
ctx.draw()
ctx.restore()
},
onLoad: function (options) {
this.ctx = wx.createCanvasContext("myCanvas")
this.drawImage()
}
})
7.9 图像的导出
使用wx.canvasToTempFilePath(OBJECT,this)把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径,参数说明如下:
ps:在自定义组件下,第二个参数传入组件实例this,以操作组件内
简单应用示例代码:
7.绘制
7.9 图案导出
//js
Page({
previewImage: function () {
//保存画布内容到临时图片路径
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success: function(res) {
//图片的路径地址
var src = res.tempFilePath;
console.log(src)
//预览图片
wx.previewImage({
current: src, //当前显示图片的http链接
urls: [src], //需要预览的图片http链接列表
})
}
})
},
onLoad: function (options) {
const ctx = wx.createCanvasContext("myCanvas")
ctx.setFillStyle("lightgreen")
ctx.fillRect(75,75,150,150)
ctx.draw()
}
})