粒子特效

  效果:   

      先图

                         

python托尾粒子特效_初始化

      为了实现粒子在运动轨迹上所留下的尾巴效果,在网上看见有一位网友是在上一帧的基础之上,加上了一层半透明蒙层。也就是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会是一样的,将箭头函数放在回调函数的位置上也是一样的

 

      以上就是今天想分享的学习心得

 

 

                             

python托尾粒子特效_初始化_02

 

        上面为希望最终可以实现的效果 flaging!!!!!!!!!!!!!!