1. 先看效果图:
2. 实现思路:
2-1. 先获取canvas的context,设置画布大小;
2-2. 计算半径,设置圆半径放到数组中,当上一个圆半径大于初始半径10px的时候就往数组里面新加一个圆,最外面的圆大于等于半径的时候就从数组中删除;
2-3. 通过canvas的requestAnimationFrame方法使每一次屏幕刷新的时候更新动画;
3. 代码实现:
3-1 demo.wxml
<canvas type="2d" id="myCanvas" />
3-2 demo.js
wx.createSelectorQuery().select("#myCanvas").fields({
node: true,
size: true
}).exec(res => this.init(res));
init(res) {
const width = res[0].width
const height = res[0].height
// 设置画布宽高
const canvas = res[0].node
const ctx = canvas.getContext('2d')
canvas.width = width
canvas.height = height
/** 半径 */
let rArr = [];
/** 透明度 */
let alpha = [];
const renderLoop = () => {
/** 最小半径 */
const circleStartR = width / 2 - 40;
/** 最大半径 */
const circleEndR = width / 2 - 8;
/** 动画时间 */
let animationTime = 500;
/** 每次增大的宽度 */
let speed = (circleEndR - circleStartR) / animationTime;
rArr = rArr.map(item => item + speed);
alpha = alpha.map(item => item + 1 / animationTime);
// 如果数组为空|| 最小圆半径-最小半径>圆间隔
if (!rArr[0] || rArr[0] - circleStartR > 10) {
rArr.unshift(circleStartR);
alpha.unshift(0);
}
// 如果最大圆半径>=最大半径
if (rArr[rArr.length - 1] >= circleEndR) {
rArr.pop();
}
this.render(width, ctx, rArr, alpha)
canvas.requestAnimationFrame(renderLoop)
}
canvas.requestAnimationFrame(renderLoop)
},
render(width, ctx, rArr, alpha) {
ctx.clearRect(0, 0, width, width);
const center = width / 2;
function ball(r, a) {
// 设置渐变
let grd = ctx.createLinearGradient(0, 0, 100, 0);
grd.addColorStop(0, 'rgba(132, 251, 251, ' + a + ')') //渐变颜色的添加
grd.addColorStop(0.5, 'rgba(118, 133, 254, ' + a + ')');
grd.addColorStop(1, 'rgba(2545, 4, 255, ' + a + ')');
ctx.beginPath();
// 画圆
ctx.arc(center, center, r, 0, 2 * Math.PI);
// 描边样式设置
ctx.strokeStyle = grd;
ctx.closePath();
// 描边
ctx.stroke();
}
for (let i = 0; i < rArr.length; i++) {
let r = rArr[i];
let a = alpha[i];
ball(r, a);
}
},