• 炒鸡简单的canvas粒子(山东数漫江湖)


    位图的canvas一直不会被svg比下去的原因了。 俗话说,须弥芥子,是大小之说,也有以小见大之说,颗颗粒子,足以构建宏大效果。 这是一篇炒鸡简单的canvas粒子教程,主要是讲如何粒子特效的原理,一点运动中的公式。

    有所准备

    首先,当我们知道要做粒子的效果的时候,我们要思考我们如何来实现,而且还要尽可能的面对我们亲爱的对象,于是便有了如下的思考。

    1. 要有粒子
    2. 粒子在运动,运动就需要速度
    3. 匀速运动/变速运动
    4. 运动之外还需要哪些处理

    全局中的永恒

    这里我定义了时间与粒子生成的数量,还有一个粒子池。

    也许会很奇怪,我们在运动的过程中每一帧都是时间,为什么还要再设置这个时间,浏览器的渲染可以被看作正常流逝的时间,这里的time则是相对时间 如果感觉晕晕的,

    这里可以举个小李子:

    光在世界中沿直线传播,你现在所能看到的月光是很久之前的月光,这就说明很久之前的月光一直在传播,同时也意味着你的一切动作都还在传播的过程中,只要你的速度足够快,就可以追上你的过去。

    开个小玩笑了,其实time的意思就是你的1s对于小球而言是2s,浏览器渲染设置的时间只是为了让你的视觉上看不出图像的卡顿

    const time=2;
    const num=20;
    var dots=[];
    

    粒子类

    function dot(x,y,vx,vy){
      //接收粒子点的坐标与方向速度量
      this.x=x;
      this.y=y;
      this.vx=vx;
      this.vy=vy;
      //随机粒子大小
      this.size=Math.ceil(Math.random()*3+2);
      this.ctx={};
    }
      //粒子渲染
    dot.prototype.render = function(ctx) {
      ctx.save();
      this.ctx=ctx;
      this.ctx.beginPath();
      this.ctx.fillStyle='lightgray';
      this.ctx.arc(this.x-this.size/2,this.y-this.size/2,this.size,0,Math.PI*2);
      this.ctx.closePath();
      this.ctx.fill();
      ctx.restore();
    };
      //对当前粒子属性做逻辑计算
    dot.prototype.update = function() {
      this.ctx.clearRect(0,0,canvas.width,canvas.heihgt);
      this.x=this.x+this.vx*time;
      this.y=this.y+this.vy*time;
      this.vx = (this.x < canvas.width && this.x > 0) ? this.vx : (-this.vx);
      this.vy = (this.y < canvas.height && this.y > 0) ? this.vy : (-this.vy);
      this.render(this.ctx);
    };
    

    在当前粒子类中,我只给了速度的方向量,因为我们只要求粒子做匀速运动,这里的计算公式则是x=vt(x:位移 v:平均速度 t:运动时间)

    如果要对粒子施加力或者变速运动,则需要this.a=a来添加一个加速度的属性。然后根据加速度的方向做水平与垂直的分解,并且对速度的方向量产生作用,从而进行变速运动,这里的公式如下

    1. v=at
    2. x=(v0+at/2)*t
      v0为初速度,a为加速度的方向量,x为方向上的位移

    祸乱世界的粒子

    for(let i=0;i<num;i++){
      var x=Math.ceil(Math.random()*canvas.width);
      var y=Math.ceil(Math.random()*canvas.height);
      var vx=Math.ceil(Math.random()*2);
      var vy=Math.ceil(Math.random()*2);
      var d=new dot(x,y,vx,vy);
      d.render(ctx);
      dots.push(d);
    }
    

    通过对canvas的宽高进行随机取整来获取随机的坐标点。并且实例化我们的粒子。并且推入粒子池中。 这里因为我们在update方法中会直接调用render,所以我们只需要在实例化的时候执行一次renderctx环境传入,后面就可以全部交给update来完成了。

    躁动吧 粒子球

    requestAnimFrame(anim);
    function anim(){
      for(let i=0;i<dots.length;i++){
          dots[i].update();
      }
      requestAnimFrame(anim);
    }
    

    这里我们只需要对粒子池中的粒子进行数据持续更新,就可以让粒子们跑起来了。

    粒子的教程比较简单,但确是几乎所有粒子效果的依托,粒子已经可以生成,那么只需要让粒子在我们的规定路径上运动,就可以达到我们所需要的效果了。

    拓展思维

    1. 知乎背景的网状效果

      遍历所有粒子点,如果在范围内,则使用moveTo与llineTo来生成连接线。

    2. 粒子成字

      将文字先绘制在离屏canvas上,然后返回所有不透明像素点的坐标,遍历时可以直接遍历,也可以使用widthheight来计算,如果当前点需要绘制,就生成粒子。

      这里说到像素点不透明,是因为在canvas上,你只要不设置,默认是不存在背景色,也就说,所有绘制的所有像素都可以通过判断其alpha值是否为0来判断,也可以通过设置alpha的阈值来将一些填充度不够的点给扔除。比如说当alpha对应为128的时候,透明度约为0.5,这也是为什么很多人的博客里都用到了128这个判断值。

      还有很多的效果,粒子特效是一个很大的话题,如AE Unity等软件中都会有内置的粒子插件与外置的大量粒子效果插件。

    后面还会写一些有些高度的粒子效果

    不定期更新canvas与svg的相关技术教程,有实战型,也会有主原理型的,2d 2.5d 3d都会包含到,同时涉及的有 线性代数 物理 图形学等相关的基础知识。

    本次demo源码:粒子效果



  • 相关阅读:
    批量管理增量日志(seek、tell)
    字符串和编码
    5.activiti--完成任务
    4.activiti--代理任务Claiming the task
    3.activiti--待办任务
    2.activiti-启动流程实例
    1.activiti-流程图
    html 各种高度
    redis-过期时间、访问限制与缓存
    spring mvc controller 接收参数
  • 原文地址:https://www.cnblogs.com/kkdn/p/8963255.html
Copyright © 2020-2023  润新知