文章来源https://juejin.cn/post/6910857740327845901#heading-8
先看看大佬效果
基础代码
class Snow{
constructor(opt={}){
this.width = 0
this.height = 0
this.minWidth = 2
this.maxWidth = opt.maxWidth || 80
this.x = 0
this.y = 0
this.speed = 0
this.opacity = 1
this.minSpeed = opt.minSpeed || 1
this.maxSpeed = opt.maxSpeed || 4
this.windowWidth = window.innerWidth
this.windowHeight = window.innerHeight
this.init()
}
init(){
this.width = Math.random() * this.maxWidth + this.minWidth
this.height = this.width
this.opacity = Math.random()
this.speed = Math.random() * this.maxSpeed + this.minSpeed
this.x = Math.random() * this.windowWidth
this.y = Math.random() * this.windowHeight
}
setStyle(){
this.el.style.cssText =
`
position: fixed;
left:0;
top:0;
display: block;
width: ${this.width}px;
height: ${this.height}px;
background-image: radial-gradient(#fff 0%, rgba(255, 255, 255, 0) 60%);
border-radius: 50%;
transform: translate(${this.x}px,${this.y}px);
`
}
render(){
this.el = document.createElement('div')
this.setStyle()
document.body.appendChild(this.el)
}
move(){
this.x = (this.x + this.speed)>this.windowWidth? 0 : (this.x + this.speed)
this.y = (this.y + this.speed)>this.windowHeight? 0 : (this.y + this.speed)
this.el.style.left = this.x +'px'
this.el.style.top = this.y +'px'
}
}
let snowList = []
for (let i = 0; i < 100; i++) {
let snow = new Snow()
snow.render()
snowList.push(snow)
}
function moveShow(){
window.requestAnimationFrame(()=>{
snowList.forEach((item,i)=>{
snowList[i].move()
})
moveShow()
})
}
moveShow()
window.requestAnimationFrame()
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()