博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HTML5 Canvas火焰效果 像火球发射一样
阅读量:6695 次
发布时间:2019-06-25

本文共 4483 字,大约阅读时间需要 14 分钟。

Canvas是HTML5中非常重要而且有用的东西,我们可以在Canvas上绘制任意的元素,就像你制作Flash一样。今天我们就在Canvas上来制作一款火焰发射的效果。就像古代的火球炮一样,而且可以在浏览器边缘反弹,感觉会比较屌。来看看效果图:

我们可以在这里

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

首先很简单地在页面上放一个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
(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 Canvas火球动画就到这里了,js代码比较多,最终的源码可以到这里下载,

转载地址:http://hlpoo.baihongyu.com/

你可能感兴趣的文章
【Codevs 2630】宝库通道
查看>>
hibernate延迟加载(get和load的区别)
查看>>
TYVJ P1081 最近距离 Label:这不是分治!!!
查看>>
为什么要使用索引?
查看>>
pycharm 基础教程
查看>>
appium界面运行过程(结合日志截图分析)
查看>>
WCF REST 工作总结
查看>>
Java - 数组排序 -- 浅析稳定性与复杂度
查看>>
bzoj3689
查看>>
Dreamweaver 制作图片热点之后,点击热点部分会有个提示框,怎么去掉
查看>>
Codeforces Round #545 (Div. 1) 简要题解
查看>>
购物商城---页面缓存oscached
查看>>
java基础--理论2
查看>>
2017.12.14工程工艺问题
查看>>
2018.6.21 HOLTEK HT49R70A-1 Source Code analysis
查看>>
服务器设计笔记(4)-----客户端通信模块
查看>>
cf595d
查看>>
IntelliJ IDEA运行eclipse的web项目报错的问题
查看>>
PHP之省事儿的封装
查看>>
洛谷3812:【模板】线性基——题解
查看>>