粒子特效
效果:
先图
为了实现粒子在运动轨迹上所留下的尾巴效果,在网上看见有一位网友是在上一帧的基础之上,加上了一层半透明蒙层。也就是rgba(0,0,0,.1)。
下面开始实现拖尾的效果:
(1)需求分析:
1.粒子的生成 (绘制)
2.粒子的移动
3.粒子的拖尾完成
(2)代码实现
1.Dot类的实现,为了生成一个点,我简易封装了dot
Dot Class
class Dot {
constructor(canvas, context, r = 4) {
this.canvas = canvas //canvas 标签
this.ctx = context //canavs.getContext()
this.x = this.canvas.width * Math.random() //点的坐标
this.y = this.canvas.width * Math.random()
this.xa = (2 * Math.random() - 1) * 2 //点在每一帖在横向方向的距离跨度
this.ya = (2 * Math.random() - 1) * 2 //点在每一帧在纵向方向上跨度
this.r = r
}
draw() { //绘制一个Dot 返回一个Dot的实例,就是本身this的指向当前的Dot
this.ctx.beginPath()
let grap = this.ctx.createRadialGradient(this.x, this.y, 0, this.x + this.r, this.y + this.r, 10)
grap.addColorStop(0, "rgb(193,255,255)")
grap.addColorStop(1, 'rgb(1,1,1)')
this.ctx.fillStyle = grap
this.ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
this.ctx.fill()
this.ctx.closePath()
return this //返回自身
}
}
在Dot的原型中,有一个draw的方法是用于绘制一个点,调用时,可以这样,假设dot为实例 那么调用就是 dot.draw().move() move方法是用于dot的移动
move函数
move() {
this.x += this.xa //每绘制一个dot之后,就会更新dot的坐标和速度
this.y += this.ya
this.xa *= (this.x < 0 || this.x > this.canvas.width) ? -1 : 1 //碰壁了就会反弹
this.ya *= (this.y < 0 || this.y > this.canvas.height) ? -1 : 1
}
好了Dot类就基本完成了,下面是完成画布的封装CanvasDot
class DotCanvas {
constructor(id, num = 300) {
this.canvas = document.getElementById(id); // 我这里是在通过DOM操作获得canvas画布,需要自己在html自己加入canvas标签
this.ctx = this.canvas.getContext('2d') this.dots = null
this.dotnum = num //dot的数量 ,默认是300
this.initDot().render() //initDot 是dot的初始化,而render是画布的渲染
}
initDot() { //初始化dot集
this.dots = Array.from(Array(this.dotnum)).map((item, index, arr) => {
return new Dot(this.canvas, this.ctx)
})
return this
}
render() {
this.dots.forEach((item) => {
item ? item.draw().move() : null
})//遍历所有的dot 并绘制移动
//下面是重点,在绘制完dot后,为了完成拖尾的效果,所以需要我们去加上一层
this.ctx.fillStyle = 'rgb(0,0,0,.07)' //加上填充的颜色
this.ctx.rect(0, 0, this.canvas.width, this.canvas.height) //绘制的区域是整个canvas
this.ctx.fill() //填充
window.requestAnimationFrame(this.render.bind(this)) //requestAnimationFrame实现每秒60帧,为啥在this.render之后加上个bind方法呢》
//实际在render中,有使用this的方法,且this的指向明确是CanvasDot的实例,而在回调函数中,往往this的Binding就变得尤为的不同,如在setTimeout()中的回调函数就是
//绑定在window上,因为setTimeout就是在window下的函数,而requestAnimationnFrame同样也是。
}
}
最后来总结一下,学习的经验。
(1)实现拖尾,可以在绘制完点之后,加上一层半透明蒙层,在视觉上让人觉得是有拖尾,注:这里没有使用clearReact()方法清楚画布,而是加上一层,让原先点所在位置的那个点变得模糊,从而使用拖尾。
(2)关于回调函数的this绑定而言,可以通过bind方法将this显示绑定,或者也可以用箭头函数实现绑定父级this,在ES6中箭头函数的this绑定,是绑定父级的this.
如function add(x,y){
console.log(this)
()=>(console.log(this))}这两个this会是一样的,将箭头函数放在回调函数的位置上也是一样的
以上就是今天想分享的学习心得
上面为希望最终可以实现的效果 flaging!!!!!!!!!!!!!!