当前位置: 移动技术网 > IT编程>网页制作>Html5 > HTML5 Canvas火焰效果 像火球发射一样

HTML5 Canvas火焰效果 像火球发射一样

2018年11月01日  | 移动技术网IT编程  | 我要评论
canvas是html5中非常重要而且有用的东西,我们可以在canvas上绘制任意的元素,就像你制作flash一样。今天我们就在canvas上来制作一款火焰发射的效果。就像古代的火球炮一样,而且可以在边缘反弹,感觉会比较屌。来看看效果图:

 

 

 

我们可以在这里查看火焰球的demo演示

 

当然,我们要来分析一下源代码,主要是一些js代码。

 

首先很简单地在页面上放一个canvas标签,并且给它点简单的样式:

 

<canvas></canvas>

复制代码

canvas{

  position: absolute;

  height: 100%;

  width: 100%;

  left: 0;

  top: 0;

  cursor: crosshair;

}

复制代码

接下来就来分析一下js代码。我们来逐步分解js。

 

由于这个是二维动画,所以我们利用canvas的getcontext方法来返回一个对象,这个对象包含我们对二维动画操作的api,代码如下:

 

canvas = document.queryselector('canvas');

ctx = canvas.getcontext('2d');

下面我们来定义粒子:

 

复制代码

particles = {};

newparticle = (function(){

  var nextindex = 0;

  return function(x,y,r,o,c,xv,yv,rv,ov){

    particles[++nextindex] = {

      index: nextindex,

      x: x,

      y: y,

      r: r,

      o: o,

      c: c,

      xv: xv,

      yv: yv,

      rv: rv,

      ov: ov

    };

  };

})();

复制代码

然后我们来定义火球:

 

复制代码

fireballs = {};

newfireball = (function(){

  var nextindex = 0;

  return function(x,y,xv,yv,life){

    fireballs[++nextindex] = {

      index: nextindex,

      x: x,

      y: y,

      xv: xv,

      yv: yv,

      life: life

    };

  };

})();

复制代码

这里life表示火球的生命周期,下面我们可以看到,life值会随着火球发射力度的改变而改变。

 

接下来是定义鼠标拖动弹弓,准备发射火球:

 

复制代码

mouse = {x:0,y:0,d:0};

onmousemove = function(e){

  mouse.x = e.clientx-o.x;

  mouse.y = e.clienty-o.y;

  var dx = mouse.x - pos1.x,

      dy = mouse.y - pos1.y;

  mouse.d = math.sqrt(dx*dx+dy*dy);

};

 

charging = false;

pos1 = {x:0,y:0};

showinstructions = true;

onmousedown = function(e){

  pos1.x = mouse.x;

  pos1.y = mouse.y;

  charging = true;

  showinstructions = false;

};

 

onmouseup = function(){

  if(charging){

    newfireball(

      mouse.x,

      mouse.y,

      (pos1.x-mouse.x)*0.03,

      (pos1.y-mouse.y)*0.03,

      600

    );

    charging = false;

  }

};

复制代码

可以看到,当鼠标按键弹起时,新建一个火球,并初始化life值。

 

下面是火球运动时的动画执行代码,包括碰到浏览器边缘时的反射效果:

 

复制代码

time = 0;

requestanimationframe(loop = function(){

  ctx.settransform(1,0,0,1,0,0);

  ctx.globalcompositeoperation = 'source-over';

  ctx.globalalpha = 1;

  ctx.fillstyle = bgcolor;

  ctx.fillrect(0,0,width,height);

  

  ctx.translate(o.x,o.y);

  

  if(charging){

    var c = math.floor(30+mouse.d/2);

    ctx.strokestyle = 'rgba('+c+','+c+','+c+',1)';

    ctx.linewidth = 4;

    ctx.beginpath();

    ctx.moveto(pos1.x,pos1.y);

    ctx.lineto(mouse.x,mouse.y);

    ctx.linecap = 'round';

    ctx.stroke();

  }

  

  if(showinstructions){

    pos1.x = -70;

    pos1.y = -35;

    

    if(time<10){

      var x = -70,

          y = -35,

          r = 30-time*2,

          a = time/10;

    }else if(time<80){

      var x = (time-10)*2-70,

          y = (time-10)-35,

          r = 10,

          a = 1;

    }else if(time<90){

      var x = 70,

          y = 35,

          r = 10+(time-80)*2,

          a = 1-(time-80)/10;

    }else if(time<140){

      var x = 70,

          y = 35,

          r = 30,

          a = 0;

    }

    var dx = pos1.x-x,

        dy = pos1.y-y,

        d = math.sqrt(dx*dx+dy*dy);

    if(time<80&&time>10){

      ctx.globalcompositeoperation = 'source-over';

      ctx.globalalpha = 1;

      var c = math.floor(30+d/2);

      ctx.strokestyle = 'rgba('+c+','+c+','+c+',1)';

      ctx.linewidth = 4;

      ctx.beginpath();

      ctx.moveto(pos1.x,pos1.y);

      ctx.lineto(x,y);

      ctx.linecap = 'round';

      ctx.stroke();

    }

    if(time<140){

      ctx.globalcompositeoperation = 'source-over';

      ctx.globalalpha = a;

      ctx.beginpath();

      ctx.arc(x,y,r,0,math.pi*2);

      ctx.linewidth = 2;

      ctx.strokestyle = '#aaa';

      ctx.stroke();

    }

    if(time==80){

      newfireball(

        x,

        y,

        dx*0.03,

        dy*0.03,

        240

      );

    }

    time = (time+1)%180;

  }

  

  ctx.globalcompositeoperation = 'lighter';

  for(var i in particles){

    var p = particles[i];

    ctx.beginpath();

    ctx.arc(p.x,p.y,p.r,0,math.pi*2);

    ctx.globalalpha = p.o;

    ctx.fillstyle = p.c;

    ctx.fill();

  }

  

  for(var i in particles){

    var p = particles[i];

    p.x += p.xv;

    p.y += p.yv;

    p.r += p.rv;

    p.o += p.ov;

    if(p.r<0)delete particles[p.index];

    if(p.o<0)delete particles[p.index];

  }

  

  for(var i in fireballs){

    f = fireballs[i];

    var numparticles = math.sqrt(f.xv*f.xv+f.yv*f.yv)/5;

    if(numparticles<1)numparticles=1;

    var numparticlesint = math.ceil(numparticles),

        numparticlesdif = numparticles/numparticlesint;

    for(var j=0;j<numparticlesint;j++){

      newparticle(

        f.x-f.xv*j/numparticlesint,

        f.y-f.yv*j/numparticlesint,

        7,

        numparticlesdif,

        particlecolor,

        math.random()*0.6-0.3,

        math.random()*0.6-0.3,

        -0.3,

        -0.05*numparticlesdif

      );

    }

    f.x += f.xv;

    f.y += f.yv;

    f.yv += gravity;

    var boundary;

    if(f.y<(boundary = edge.top+7)){

      f.y = boundary;

      f.yv *= -1;

    }else if(f.y>(boundary = edge.bottom-7)){

      f.y = boundary;

      f.yv *= -1;

    }

    if(f.x>(boundary = edge.right-7)){

      f.x = boundary;

      f.xv *= -1;

    }else if(f.x<(boundary = edge.left+7)){

      f.x = boundary;

      f.xv *= -1;

    }

    if(--f.life<0)delete fireballs[f.index];

  }

  

  requestanimationframe(loop);

});

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网