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

我们可以在这里查看火焰球的DEMO演示
当然,我们要来分析一下源代码,主要是一些JS代码。
首先很简单地在页面上放一个canvas标签,并且给它点简单的样式:
<canvas></canvas>
canvas{
  position: absolute;
  height: 100%;
  width: 100%;
  left:;
  top:;
  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 Canvas火球动画就到这里了,js代码比较多,最终的源码可以到这里下载,下载地址>>
HTML5 Canvas火焰效果 像火球发射一样的更多相关文章
- [js高手之路]html5 canvas动画教程 - 边界判断与小球粒子模拟喷泉,散弹效果
		备注:本文后面的代码,如果加载了ball.js,那么请使用这篇文章[js高手之路] html5 canvas动画教程 - 匀速运动的ball.js代码. 本文,我们要做点有意思的效果,首先,来一个简单 ... 
- HTML5 Canvas 超炫酷烟花绽放动画教程
		这是一个很酷的HTML5 Canvas动画,它将模拟的是我们现实生活中烟花绽放的动画特效,效果非常逼真,但是毕竟是电脑模拟,带女朋友看就算了,效果还是差了点,呵呵.这个HTML5 Canvas动画有一 ... 
- HTML5 程序设计 - 使用HTML5 Canvas API
		请你跟着本篇示例代码实现每个示例,30分钟后,你会高喊:“HTML5 Canvas?!在哥面前,那都不是事儿!” 呵呵.不要被滚动条吓到,很多都是代码和图片.我没有分开写,不过上面给大家提供了目录,方 ... 
- 赠书:HTML5 Canvas 2d 编程必读的两本经典
		赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ... 
- 如何开发一个简单的HTML5 Canvas 小游戏
		原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ... 
- html5 canvas常用api总结(一)
		1.监听浏览器加载事件. window.addEventListener("load",eventWindowLoaded,false); load事件在html页面加载结束时发生 ... 
- HTML5 Canvas绘制转盘抽奖
		新项目:完整的Canvas转盘抽奖代码 https://github.com/givebest/GB-canvas-turntable 演示 http://blog.givebest.cn/GB-ca ... 
- html5 canvas首屏自适应背景动画循环效果代码
		模板描述:html5 canvas首屏自适应背景动画循环效果代码 由于动态图太大,怕以后服务器受不了,所以现在都改为静态图了,大家点击演示地址一样的,希望大家喜欢,你们的支持就是小海的动力!! 欢迎大 ... 
- 自己写的HTML5 Canvas + Javascript五子棋
		看到一些曾经只会灌水的网友,在学习了前端之后,已经能写出下载量几千几万的脚本.样式,帮助大众,成为受欢迎的人,感觉满羡慕的.我也想学会前端技术,变得受欢迎呀.于是心血来潮,开始学习前端知识,并写下了这 ... 
随机推荐
- django 利用PIL 保存图片
			在使用django时不知道怎么保存图片,又不想用它的form ,在网上找了许久,终于找到个解决方案,利用PIL.image 将POST上来的图片保存到media目录下,然后再修改models from ... 
- 使用 libvirt创建和管理KVM虚拟机
			1. libvirt介绍 Libvirt是一个软件集合,便于使用者管理虚拟机和其他虚拟化功能,比如存储和网络接口管理等等.Libvirt概括起来包括一个API库.一个 daemon(libv ... 
- STM32——项目需求之低功耗的停机模式
			在说低功耗之前,先要明白一个东西,那就是stm32中的事件和中断. 事件是中断的触发源,开放了对应的中断屏蔽位,则事件可以触发相应的中断.在STM32中,中断与事件不是等价的,一个中断肯定对应一个事件 ... 
- C# Dictionary通过value获取对应的key值
			1:最直白的循环遍历方法,可以分为遍历key--value键值对以及所有的key两种表现形式 2:用Linq的方式去查询(当然了这里要添加对应的命名空间 using System.Linq) 如下为一 ... 
- 命令行todo神器taskwarrior使用简介
			简介 taskwarrior是一个命令行的任务管理神器,同时也有服务端,支持同步. 语法规则为 安装 Linux上可以直接软件包管理器安装 Window可以用cygwin Mac可以用homebrew ... 
- [转]为Kindeditor控件添加图片自动上传功能
			原文地址:http://www.cnblogs.com/jaxu/p/3824583.html Kindeditor是一款功能强大的开源在线HTML编辑器,支持所见即所得的编辑效果.它使用JavaSc ... 
- 几种经典的Hash算法的实现(源代码)
			来源声明: http://blog.minidx.com/2008/01/27/446.html 先保存下来,以备后面研究,现在还看不懂! 哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这 ... 
- 如何在CentOS或者RHEL上启用Nux Dextop仓库 安装shutter截图工具
			Nux Dextop是一个面对CentOS.RHEL.ScientificLinux的含有许多流行的桌面和多媒体相关的包的第三方RPM仓库(比如:Ardour,Shutter等等).目前,Nux De ... 
- <漫步华尔街——股市历久弥新的成功投资策略>读书笔记
			书在这里 随机游走是指基于过去的表现,无法预测将来的发展步骤和方向. 仅仅为了达到盈亏相抵点,你的投资回报率至少也要等于通货膨胀率 磐石理论认为,无论是普通股票还是不动产,每一种投资工具都具有被称为“ ... 
- MapReduce教程(一)基于MapReduce框架开发<转>
			1 MapReduce编程 1.1 MapReduce简介 MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算,用于解决海量数据的计算问题. MapReduce分成了两个部分: ... 
