要过年啦,用canvas做了个烟火效果
声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢!
要过年了,过年想到的就是放烟火啦。。。。于是就用canvas写了个放烟火的效果,鼠标点击也会产生烟火,不过不要产生太多烟火哦,一个烟火散出的粒子是30到200个之间,当页面上的粒子数量达到一定的时候,页面就会很卡咯,我也没特意去优化神马的。以后有空再说吧。
直接上DEMO吧:放烟火
原理很简单。。。就写一个烟火类以及碎屑类,实例化后让它飞起来,然后到达某个点后,把这个烟火对象的dead属性置为true,然后再实例化出一定数量的碎屑对象,并且给与碎屑对象随机一个要到达的目标点,然后让所有碎屑对象飞过去就行了。
【烟火】
var Boom = function(x,r,c,boomArea,shape){ //烟火对象
this.booms = [];
this.x = x;
this.y = (canvas.height+r);
this.r = r;
this.c = c;
this.shape = shape || false;
this.boomArea = boomArea;
this.theta = 0;
this.dead = false;
this.ba = parseInt(getRandom(80 , 200));
}
Boom.prototype = {
_paint:function(){
ctx.save();
ctx.beginPath();
ctx.arc(this.x,this.y,this.r,0,2*Math.PI);
ctx.fillStyle = this.c;
ctx.fill();
ctx.restore();
},
_move:function(){
var dx = this.boomArea.x - this.x , dy = this.boomArea.y - this.y;
this.x = this.x+dx*0.01;
this.y = this.y+dy*0.01; if(Math.abs(dx)<=this.ba && Math.abs(dy)<=this.ba){
if(this.shape){
this._shapBoom();
}
else this._boom();
this.dead = true;
}
else {
this._paint();
}
},
_drawLight:function(){
ctx.save();
ctx.fillStyle = "rgba(255,228,150,0.3)";
ctx.beginPath();
ctx.arc(this.x , this.y , this.r+3*Math.random()+1 , 0 , 2*Math.PI);
ctx.fill();
ctx.restore();
},
_boom:function(){ //普通爆炸
var fragNum = getRandom(30 , 200);
var style = getRandom(0,10)>=5? 1 : 2;
var color;
if(style===1){
color = {
a:parseInt(getRandom(128,255)),
b:parseInt(getRandom(128,255)),
c:parseInt(getRandom(128,255))
}
} var fanwei = parseInt(getRandom(300, 400));
for(var i=0;i<fragNum;i++){
if(style===2){
color = {
a:parseInt(getRandom(128,255)),
b:parseInt(getRandom(128,255)),
c:parseInt(getRandom(128,255))
}
}
var a = getRandom(-Math.PI, Math.PI);
var x = getRandom(0, fanwei) * Math.cos(a) + this.x;
var y = getRandom(0, fanwei) * Math.sin(a) + this.y;
var radius = getRandom(0 , 2)
var frag = new Frag(this.x , this.y , radius , color , x , y );
this.booms.push(frag);
}
},
_shapBoom:function(){ //有形状的爆炸
var that = this;
putValue(ocas , octx , this.shape , 5, function(dots){
var dx = canvas.width/2-that.x;
var dy = canvas.height/2-that.y;
for(var i=0;i<dots.length;i++){
color = {a:dots[i].a,b:dots[i].b,c:dots[i].c}
var x = dots[i].x;
var y = dots[i].y;
var radius = 1;
var frag = new Frag(that.x , that.y , radius , color , x-dx , y-dy);
that.booms.push(frag);
}
})
}
}
【碎屑】
var Frag = function(centerX , centerY , radius , color ,tx , ty){ //烟火碎屑对象
this.tx = tx;
this.ty = ty;
this.x = centerX;
this.y = centerY;
this.dead = false;
this.centerX = centerX;
this.centerY = centerY;
this.radius = radius;
this.color = color;
} Frag.prototype = {
paint:function(){
ctx.save();
ctx.beginPath();
ctx.arc(this.x , this.y , this.radius , 0 , 2*Math.PI);
ctx.fillStyle = "rgba("+this.color.a+","+this.color.b+","+this.color.c+",1)";
ctx.fill()
ctx.restore();
},
moveTo:function(index){
this.ty = this.ty+0.3;
var dx = this.tx - this.x , dy = this.ty - this.y;
this.x = Math.abs(dx)<0.1 ? this.tx : (this.x+dx*0.1);
this.y = Math.abs(dy)<0.1 ? this.ty : (this.y+dy*0.1);
if(dx===0 && Math.abs(dy)<=80){
this.dead = true;
}
this.paint();
}
}
让碎屑产生虚影也很简单,就是每次刷新画布时,不是擦掉重绘,而是绘制透明度为0.1(如果想虚影更长,可以把这个值弄的更小)的背景颜色。然后虚影就可以做出来了。也就是:
ctx.save();
ctx.fillStyle = "rgba(0,5,24,0.1)";
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.restore();
让烟火形成自己想要的形状,比如字体,图片之类的,也很简单,就是可以通过离屏canvas以及canvas的getImageData这个方法就可以做出来。离屏canvas,顾名思义就是离开屏幕的,也就是不可见的canvas,直接在js里面用document.createElement("canvas")就可以生成一个canvas dom对象了,只要不把这个dom对象赋给body,这个canvas对象就相当于一个离屏对象了,我们就可以获取到这个离屏canvas的context对象,然后再用户看不到的地方做任何我们想做的事情了。
让烟火形成自己想要的形状就是先把文字或者图片画在离屏canvas上,然后用getImageData获取画布上的像素数组,然后遍历数组,获取有颜色的像素,也就是我们想要的内容,保存起来后,再放到主canvas对象中显示出来。
getImageData的像素处理我之前的博客上有讲过,如果不会用的,请戳:随便谈谈用canvas来实现文字图片粒子化
源码地址:https://github.com/whxaxes/canvas-test/tree/gh-pages/src/Funny-demo/shotFire
要过年啦,用canvas做了个烟火效果的更多相关文章
- 用HTML5 Canvas 做擦除及扩散效果
2013年的时候曾经使用canvas实现了一个擦除效果的需求,即模拟用户在模糊的玻璃上擦除水雾看到清晰景色的交互效果.好在2012年的时候学习HTML5的时候研究过canvas了,所以在比较短的时间内 ...
- 用 canvas 做个好玩的网站背景
不知不觉又好久没更过博客了,老调新弹一下,之前做的一个小效果,觉得蛮有意思的,也有朋友问是怎么做的,就分享一下,写个博文吧. 先上demo吧:http://whxaxes.github.io/canv ...
- 用Canvas做动画
之前看过不少HTML5动画的书,讲解的是如何去做,对于其中的数学原理讲解的不详细,常有困惑.最近看的<HTML5+JavaScript 动画基础>这个是译本,Keith Peters曾写过 ...
- 我们能用canvas做什么?
什么是Canvas? Canvas元素是HTML5的一部分,允许脚本语言动态渲染位图像.Canvas由一个可绘制地区HTML代码中的属性定义决定高度和宽度.JavaScript代码可以访问该地区,通过 ...
- html5 canvas做的图表插件
用highchart的时候发现它是用svg来画图的,那么用canvas来做怎么样的. 以前做AS图表插件的时候,绘制图画主要用容器的Graphics对象来绘制,而canvas的context和Grap ...
- canvas做动画
一.绘制图片 ①加载图片 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- canvas意料之外获得降龙十八掌的效果
瞎整本来是要点击编辑多张图片的,没想到弄成这样.这不是电视剧里的降龙十八掌吗 特此记录留着以后用,看来canvas做游戏特效都不错啊. <!DOCTYPE html><html la ...
- 使用JavaScript和Canvas打造真实的雨滴效果
使用JavaScript和Canvas打造真实的雨滴效果 寸志 · 1 年前 我最近搞了一个有趣的项目——rainyday.js .我认为这个项目并不怎么样,而且,事实上这是我第一次尝试接触一些比弹窗 ...
- HTML5在canvas中绘制复杂形状附效果截图
HTML5在canvas中绘制复杂形状附效果截图 一.绘制复杂形状或路径 在简单的矩形不能满足需求的情况下,绘图环境提供了如下方法来绘制复杂的形状或路径. beginPath() : 开始绘制一个新路 ...
随机推荐
- Just Oj 2017C语言程序设计竞赛高级组D: 字符串最大表示(next数组)
D: 字符串最大表示 时间限制: 1 s 内存限制: 128 MB 题目描述 有如下定义,abcnabcn表示字符串abc重复n次,例如abc2abc2表示abcabc. 给定一个字符串,求 ...
- net core 使用 rabbitmq
windows环境安装: https://www.cnblogs.com/ericli-ericli/p/5902270.html .NET Core 使用RabbitMQ https://www.c ...
- UE4 ShooterGame Demo的开火的代码
之前一直没搞懂按下鼠标左键开火之后,代码的逻辑是怎么走的,今天看懂了之前没看懂的部分,进了一步 ShooterCharacter.cpp void AShooterCharacter::OnStart ...
- (3).NET CORE微服务 Micro-Service ---- Consul服务治理
Consul是注册中心,服务提供者.服务提供者.服务消费者等都要注册到Consul中,这样就可以实现服务提供者.服务消费者的隔离. 除了Consul之外,还有Eureka.Zookeeper等类似软件 ...
- 【bzoj3717】[PA2014]Pakowanie 状压dp
题解: 自己在这一类问题上想到的总是3^n的枚举法 首先背包从大到小排序 f[i]表示搞出为i的状态至少要用几个背包,g[i]表示最大剩余容量 这样就可以2^n*n 因为这么做利用了状态之间的先后顺序 ...
- uva 11992
题意: 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x ...
- javascript小例子:實現四方向文本无缝滚动效果
实现一个文本无缝滚动的效果: <!DOCTYPE html> <!--[if lt IE 7 ]> <html lang="zh-CN" class= ...
- mysql查看变量/配置文件位置
//查看所有变量 show global variables //查看某个变量的值 show global variables where variable_name like '%innodb_fl ...
- NowCoder Wannafly 27E 黄魔法师 构造
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-Wannafly27E.html 题目传送门 - NowCoder Wannafly 27E 题 ...
- 关于用舞蹈链DLX算法求解数独的解析
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 描述 在做DLX算法题中,经常会做到数独类型的题目,那么,如何求解数独类型的题目?其实,学了数独的构建方法,那么DL ...