首先效果图。
飘落个数,速度,同时最多出现几个一起飘可以控制
代码
<canvas canvas-id="myCanvas" class="my-canvans" v-if='canvansShow'/>
// canvansShow 默认true
onShow () {
this.createStar(this.imgUrl)
},
mothods{
createStar (imgUrl) {
// #ifdef MP-WEIXIN
let starImage = ''
uni.getImageInfo({
src: imgUrl,
success: res => {
starImage = res.path
}
})
// #endif
let { requestAnimationFrame } = this
function Star (x, y, radius) {
this.x = x
this.y = y
this.sx = 0
this.sy = 0
this.deg = 0
this.radius = radius
this.ax = Math.random() < 0.5 ? 0.01 : -0.01
}
Star.prototype.update = function () {
const deltaDeg = Math.random() * 0.6 + 0.2
this.sx += this.ax
if (this.sx >= SPEED_LIMIT_X || this.sx <= -SPEED_LIMIT_X) {
this.ax *= -1
}
if (this.sy < SPEED_LIMIT_Y) {
this.sy += G
}
this.deg += deltaDeg
this.x += this.sx
this.y += this.sy
}
Star.prototype.draw = function () {
const { radius } = this
ctx.save()
ctx.translate(this.x, this.y)
ctx.rotate((this.deg * Math.PI) / 180)
// #ifdef MP-WEIXIN
ctx.drawImage(starImage, -radius, -radius * 1.8, radius * 5, radius * 5)
// #endif
// #ifdef MP-ALIPAY
ctx.drawImage(imgUrl, -radius, -radius * 1.8, radius * 5, radius * 5)
// #endif
ctx.restore()
}
const stars = []
// 下落的加速度
const G = 13
// 速度上限,避免速度过快
const SPEED_LIMIT_X = 1
const SPEED_LIMIT_Y = 1
const W = uni.getSystemInfoSync().windowWidth
const H = uni.getSystemInfoSync().windowHeight
const starCount = 10 // 星星总的数量
let starNum = 0 // 隔多少个设定的毫秒数生成一个星星
const deltaTime = 1 // 每次增加的星星数量
const ctx = uni.createCanvasContext('myCanvas')
let starAllBottom = 0 // 到达底部的星星数量
let trueStarCount = 0 // 真正生成的星星数量
const starLoop = () => {
requestAnimationFrame = setTimeout(() => {
starLoop()
}, 1000 / 60)
ctx.clearRect(0, 0, W, H)
starNum += deltaTime
if (starNum > starCount && trueStarCount < starCount) {
stars.push(new Star(Math.random() * W, 0, Math.random() * 5 + 5))
starNum %= starCount
trueStarCount += 1
}
// isEmpty是lodash库的方法
if (isEmpty(stars)) return
stars.forEach((s, i) => {
//重复绘制
s.update()
s.draw()
if (s.y >= H) {
//大于屏幕高度的就从数组里去掉
starAllBottom += 1
stars.splice(i, 1)
if (starAllBottom === starCount) {
// 星星全部到达底部,动画结束
clearTimeout(requestAnimationFrame)
this.canvansShow && (this.canvansShow = false)
// 后续操作
// xxxxx
}
}
})
ctx.draw()
}
starLoop()
},
}
借鉴大佬的代码,在原代码上进行修改
大佬代码链接奉上:https://developers.weixin.qq.com/community/develop/article/doc/000e443b1247a039fd99230b457013