Here comes the red envelope rain plug-in you asked for
Effect one, effect two
Development background
Double 11 company to do a down the effect of red envelope rain, double 12 and from the bottom of the effect of spray, arrangement! After some hard work, I packaged it into an NPM package that can be used flexibly in various businesses in the future. Today, the author discusses the effect of falling down the process.
Analysis of the
- To manipulate data frequently, you can use canvas’s drawImage method
- The effect of red envelope drop can be calculated as follows: current position = previous position + this frame movement distance, that is, the calculation formula of free fall s=s0+1/2*gt^2;
- We need to create three classes, a global controller stage, a dropBox for dropping red envelopes, and a add effect
In the code
export default class Stage {
constructor(opt: StageOpt){}/** * Event monitor * gameOver game end callback * clickBox click callback * coundownTime countdown monitor ** /
on(name: eventName, fn: Function){}// Start the game
startGame(){}/ / update the UI
upData(){}/ / click
onClick(e: any){}// Create a red envelope
creatDropBox(){}/ / destroy
destory(){}}Copy the code
The Update method in the stage is used to update the UI and does these things:
1. Clear the canvas this.ctx.clearRect(0, 0, this.width, this.height)
This.creatdropbox ()
3. Filter the active object, call the updata method of the current object to update the data, and call ctx.drawImage() to draw the current object to the canvas
4. Destroy useless objects
/ / update the UI
upData() {
// Clear the canvas
if (this.ctx) this.ctx.clearRect(0.0.this.width, this.height)
// Create a red envelope and add it to this.pool
this.creatDropBox()
const arr: Array<any> = []
// Filter active objects
this.pool.forEach((v: any) = > {
if(! v.isDestory) {// Update each object
v.updata()
// Draw a picture
if (this.ctx) {
this.ctx.drawImage(v.img, v.x, v.y, v.w, v.h)
}
arr.push(v)
}
})
// Assign an uncollected object
this.pool = [...arr]
this.timer && window.cancelAnimationFrame(this.timer)
this.timer = window.requestAnimationFrame(this.upData.bind(this))}Copy the code
The dropBox and Add classes, which are responsible for updating data, have three methods
1. Updata Updates data
2. GetStep Obtains the current move distance
3. Destory destroy function
export default class AddScore {
private w: number = 40
private h: number = 40
private x: number
private y: number
private img: any
private id: number
private v: number = 0
private type: string = 'AddScore'
private isDestory: boolean = false
constructor(opt: AddScoreOpt) {
this.id = idNum += 1
this.x = opt.x || 20
this.y = opt.y || 20
this.img = opt.img
}
// Update data
updata() {
this.y = this.y - this.getStep()
this.x = this.x + this.getStep()
this.w -= 1
this.h -= 1
this.isDestory = this.v > 8
}
getStep(): number {
return (this.v += 0.1)}destory() {
this.img = null}}Copy the code
OnClick in the stage class does these things:
1. Determine whether the current click position is on the red envelope
2. Delete the clicked red packets from the pool
3. Add a plus one effect
onClick(e: any) {
e.preventDefault && e.preventDefault()
// Click the position
const pos = {
x: e.clientX,
y: e.clientY,
}
// Click on the middle object
let maxIndex = -1
let creatTime = 0
this.pool.forEach((e: any, i: number) = > {
if (this.isIntersect(pos, e)) {
if (e.creatTime >= creatTime) {
creatTime = e.creatTime
maxIndex = i
}
}
})
// Click on the object
if (maxIndex > -1) {
consttarget = { ... this.pool[maxIndex],gameTime: this.gameTime }
// The callback listens for click events
this.events.clickBox.forEach((e: Function) = > e(target))
/ / recycling box
this.pool.splice(maxIndex, 1)
/ / add + 1
this.pool.push(
new AddScore({ x: target.x, y: target.y, img: this.addIcon })
)
}
}
Copy the code
conclusion
The above is the simple implementation of red envelope rain, the code I put here, but some mobile phone experience is not good. After optimization, Redpacket-core has successfully experienced the test of tens of millions of users. I share it with you and hope it can be useful to you.