跟随鼠标的粒子效果
a year ago(已编辑)
# 编程
125
0
使用canvas实现跟随鼠标的粒子效果,效果如下

代码实现
function randomInt(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
interface ParticleOptions {
originX: number
originY: number
size: number
radius: number
color: string
speed: number
angle: number
}
export class Particle {
public x: number
public y: number
public originX: number
public originY: number
public size: number
public radius: number
public color: string
public speed: number
public angle: number
constructor(options: ParticleOptions) {
this.x = options.originX
this.y = options.originY
this.originX = options.originX
this.originY = options.originY
this.size = options.size
this.radius = options.radius
this.color = options.color
this.speed = options.speed
this.angle = options.angle
}
public update() {
this.angle += this.speed
this.x = Math.cos(this.angle) * this.radius + this.originX
this.y = Math.sin(this.angle) * this.radius + this.originY
}
moveTo(x: number, y: number) {
const dx = Math.abs(x - this.originX)
const dy = Math.abs(y - this.originY)
const vx = dx / 40
const vy = dy / 40
if (this.originX < x)
this.originX += vx
if (this.originX > x)
this.originX -= vx
if (this.originY < y)
this.originY += vy
if (this.originY > y)
this.originY -= vy
}
}
export class ParticleEngine {
public particles: Particle[] = []
private originX = 0
private originY = 0
constructor(
public ctx: CanvasRenderingContext2D,
public count: number,
public radius: number,
private speed: number,
) {
this.speed = speed
this.count = count
this.init(count)
}
init(count: number, options?: Partial<ParticleOptions>) {
this.originX = options?.originX ?? this.ctx.canvas.width / 2
this.originY = options?.originY ?? this.ctx.canvas.height / 2
for (let i = 0; i < count; i++) {
const radius = this.radius + Math.random() * 3 * i
const angle = Math.random() * 2 * Math.PI
const particle = new Particle({
originX: this.originX,
originY: this.originY,
size: randomInt(1, 3),
radius,
color: `rgb(${Math.random() * 255},${Math.random() * 255},${Math.random() * 255})`,
speed: this.speed ?? Math.random() * 0.05 + 0.015,
angle,
})
this.particles.push(particle)
}
}
draw(particle: Particle) {
this.ctx.beginPath()
this.ctx.fillStyle = particle.color
this.ctx.arc(particle.x, particle.y, particle.size, 0, 2 * Math.PI)
this.ctx.fill()
this.ctx.closePath()
}
run() {
requestAnimationFrame(() => {
// this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height)
this.ctx.fillStyle = 'rgba(255,255,255,0.7)'
this.ctx.rect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height)
this.ctx.fill()
this.particles.forEach((particle) => {
this.draw(particle)
particle.moveTo(this.originX, this.originY)
particle.update()
})
this.run()
})
}
update(x: number, y: number) {
return
this.originX = x
this.originY = y
}
reload(count?: number) {
this.particles = []
this.init(count ?? this.count, {
originX: this.originX,
originY: this.originY,
})
}
}
文章标题:跟随鼠标的粒子效果
文章作者:灰色の青
最后修改时间: 2024 年 9 月 27 日 14:59
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
还没有人踏及此处,留下足迹吧