html5教程-HTML5 Canvas火焰效果 像火球发射一样

发布时间:2018-12-18 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了html5教程-HTML5 Canvas火焰效果 像火球发射一样脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。
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(&#39;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);

});

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);

});

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! html5教程,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的html5教程-HTML5 Canvas火焰效果 像火球发射一样全部内容,希望文章能够帮你解决html5教程-HTML5 Canvas火焰效果 像火球发射一样所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。