微信小程序实现圣诞节星星飘落效果
圣诞节快到啦~🎄🎄🎄🎄咱们也试着做做小程序版本的星星✨飘落效果吧~
先来个效果图:
484听起来很叼,看起来也就那样。
来咱们上手开始撸
页面内容wxml,先简单切个图吧。
<view class="container">
<image src="https://image.wxopen.club/content_1b297d02-2ea4-11ea-8abd-a0999b08aadb.jpg" mode="widthFix"/>
<image src="https://image.wxopen.club/content_1b60d7fc-2ea4-11ea-8abd-a0999b08aadb.jpg" alt="" mode="widthFix"/>
<image src="https://image.wxopen.club/content_1b8c448c-2ea4-11ea-8abd-a0999b08aadb.jpg" alt="" mode="widthFix"/>
<image src="https://image.wxopen.club/content_1bbb9494-2ea4-11ea-8abd-a0999b08aadb.jpg" alt="" mode="widthFix"/>
<image src="https://image.wxopen.club/content_1c389ad4-2ea4-11ea-8abd-a0999b08aadb.jpg" alt="" mode="widthFix"/>
<image src="https://image.wxopen.club/content_1c6ce014-2ea4-11ea-8abd-a0999b08aadb.jpg" alt="" mode="widthFix"/>
<image src="https://image.wxopen.club/content_1c95dfbe-2ea4-11ea-8abd-a0999b08aadb.jpg" alt="" mode="widthFix"/>
</view>
<canvas canvas-id="myCanvas" />
页面样式wxss,因为切片用的不太熟练,图片之间有个2rpx的空隙。
.container {
height: 100%;
box-sizing: border-box;
min-height: 100vh;
}
image {
width: 100%;
display: block;
margin-top: -2rpx; //不会切图造的孽
}
canvas {
width: 100%;
min-height:100vh;
position: fixed;
top: 0;
z-index: 888;
}
重点JS:
//获取应用实例
const app = getApp()
// 存储所有的星星
const stars = []
// 下落的加速度
const G = 0.01
const stime = 60
// 速度上限,避免速度过快
const SPEED_LIMIT_X = 1
const SPEED_LIMIT_Y = 1
const W = wx.getSystemInfoSync().windowWidth
const H = wx.getSystemInfoSync().windowHeight
var starImage = '' //星星素材
wx.getImageInfo({
src: 'https://qiniu-image.qtshe.com/WechatIMG470.png',
success: (res)=> {
starImage = res.path
}
})
Page({
onLoad() {
this.setAudioPlay()
},
onShow() {
this.createStar()
},
createStar() {
let starCount = 350 //星星总的数量
let starNum = 0 //当前生成星星数
let deltaTime = 0
let ctx = wx.createCanvasContext('myCanvas')
let requestAnimationFrame = (() => {
return (callback) => {
setTimeout(callback, 1000 / stime)
}
})()
starLoop()
function starLoop() {
requestAnimationFrame(starLoop)
ctx.clearRect(0, 0, W, H)
deltaTime = 20 //每次增加的星星数量
starNum += deltaTime
if (starNum > starCount) {
stars.push(
new Star(Math.random() * W, 0, Math.random() * 5 + 5)
);
starNum %= starCount
}
stars.map((s, i) => { //重复绘制
s.update()
s.draw()
if (s.y >= H) { //大于屏幕高度的就从数组里去掉
stars.splice(i, 1)
}
})
ctx.draw()
}
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.005 : -0.005
}
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.radius
ctx.save()
ctx.translate(this.x, this.y)
ctx.rotate(this.deg * Math.PI / 180)
ctx.drawImage(starImage, -radius, -radius * 1.8, radius * 2, radius * 2)
ctx.restore()
}
},
setAudioPlay() {
let adctx = wx.createInnerAudioContext()
adctx.autoplay = true
adctx.loop = true
adctx.src = 'https://dn-qtshe.qbox.me/Jingle%20Bells.mp3'
adctx.onPlay(() => {
console.log('开始播放')
adctx.play()
})
}
})
以上只是简单实现了一个星星飘落的效果,预览的时候需要开启不校验合法域名哦~
目前还有更优的h5版本,使用Three.js实现的,在小程序内使用Three.js对于我来说有点打脑壳,先把效果分享出来吧。
h5版本,手机看效果最佳
如果有需要的可以留言,我可以整理下发源码给你。