js烟花特效
<!DOCTYPE html>
<html>
<head>
<style>
body{background:#000;margin:0;}
canvas{cursor:crosshair;display:block;}
</style>
</head>
<body>
<canvas id="canvas">Canvas is not supported in your browser.</canvas>
<script>
window.requestAnimFrame=(function(){
return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(callback){
window.setTimeout(callback,1000/60)
}
})();
var canvas=document.getElementById("canvas"),ctx=canvas.getContext("2d"),cw=window.innerWidth,ch=window.innerHeight,fireworks=[],particles=[],hue=120,limiterTotal=5,limiterTick=0,timerTotal=80,timerTick=0,mousedown=false,mx,my;canvas.width=cw;canvas.height=ch;
function random(min,max){return Math.random()*(max-min)+min}
function calculateDistance(p1x,p1y,p2x,p2y){
var xDistance=p1x-p2x,yDistance=p1y-p2y;
return Math.sqrt(Math.pow(xDistance,2)+Math.pow(yDistance,2))
}
function Firework(sx,sy,tx,ty){
this.x=sx;
this.y=sy;
this.sx=sx;
this.sy=sy;
this.tx=tx;
this.ty=ty;
this.distanceToTarget=calculateDistance(sx,sy,tx,ty);
this.distanceTraveled=0;
this.coordinates=[];
this.coordinateCount=3;
while(this.coordinateCount--)
{
this.coordinates.push([this.x,this.y])
}
this.angle=Math.atan2(ty-sy,tx-sx);
this.speed=2;
this.acceleration=1.05;
this.brightness=random(50,70);
this.targetRadius=1
}
Firework.prototype.update=function(index){
this.coordinates.pop();
this.coordinates.unshift([this.x,this.y]);
if(this.targetRadius<8){
this.targetRadius+=0.3
}
else{
this.targetRadius=1
}
this.speed*=this.acceleration;
var vx=Math.cos(this.angle)*this.speed,vy=Math.sin(this.angle)*this.speed;
this.distanceTraveled=calculateDistance(this.sx,this.sy,this.x+vx,this.y+vy);
if(this.distanceTraveled>=this.distanceToTarget){
createParticles(this.tx,this.ty);
fireworks.splice(index,1)
}else{
this.x+=vx;this.y+=vy
}
};
Firework.prototype.draw=function(){
ctx.beginPath();
ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][1]);
ctx.lineTo(this.x,this.y);
ctx.strokeStyle="hsl("+hue+", 100%, "+this.brightness+"%)";
ctx.stroke();
ctx.beginPath();
ctx.arc(this.tx,this.ty,this.targetRadius,0,Math.PI*2);
ctx.stroke()
};
function Particle(x,y){
this.x=x;this.y=y;
this.coordinates=[];
this.coordinateCount=5;
while(this.coordinateCount--){
this.coordinates.push([this.x,this.y])
}
this.angle=random(0,Math.PI*2);
this.speed=random(1,10);
this.friction=0.95;
this.gravity=1;
this.hue=random(hue-20,hue+20);
this.brightness=random(50,80);
this.alpha=1;
this.decay=random(0.015,0.03)
}
Particle.prototype.update=function(index){
this.coordinates.pop();
this.coordinates.unshift([this.x,this.y]);
this.speed*=this.friction;
this.x+=Math.cos(this.angle)*this.speed;this.y+=Math.sin(this.angle)*this.speed+this.gravity;this.alpha-=this.decay;
if(this.alpha<=this.decay){
particles.splice(index,1)
}
};
Particle.prototype.draw=function(){
ctx.beginPath();
ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][1]);
ctx.lineTo(this.x,this.y);
ctx.strokeStyle="hsla("+this.hue+", 100%, "+this.brightness+"%, "+this.alpha+")";
ctx.stroke()
};
function createParticles(x,y){
var particleCount=30;
while(particleCount--){
particles.push(new Particle(x,y))
}
}
function loop(){
requestAnimFrame(loop);
hue+=0.5;
ctx.globalCompositeOperation="destination-out";
ctx.fillStyle="rgba(0, 0, 0, 0.5)";
ctx.fillRect(0,0,cw,ch);
ctx.globalCompositeOperation="lighter";
var i=fireworks.length;
while(i--){
fireworks[i].draw();fireworks[i].update(i)
}
var i=particles.length;
while(i--){
particles[i].draw();particles[i].update(i)
}
if(timerTick>=timerTotal){
if(!mousedown){
fireworks.push(new Firework(cw/2,ch,random(0,cw),random(0,ch/2)));
timerTick=0
}
}
else{ timerTick++}
if(limiterTick>=limiterTotal){
if(mousedown){
fireworks.push(new Firework(cw/2,ch,mx,my));
limiterTick=0
}
}
else{ limiterTick++}
}
canvas.addEventListener("mousemove",function(e){
mx=e.pageX-canvas.offsetLeft;
my=e.pageY-canvas.offsetTop
});
canvas.addEventListener("mousedown",function(e){
e.preventDefault();mousedown=true
});
canvas.addEventListener("mouseup",function(e){
e.preventDefault();mousedown=false
});
window.onload=loop;
</script>
</body>
</html>
js烟花特效的更多相关文章
- 未封装的js放大镜特效
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>j ...
- 第五章 JS典型特效
注意: 1.JS在HTML中从上到下依次执行,所以获取元素的结果与JS的位置有关 <!DOCTYPE html> <html> <head> <title&g ...
- CSS3实现烟花特效 --web前端
烟花特效,比较简单,直接贴代码了…… <!DOCTYPE html><html lang="en"><head> <meta charse ...
- Three.js粒子特效,shader渲染初探(一篇非常详细的介绍)
Three.js粒子特效,shader渲染初探 转载来源:https://juejin.im/post/5b0ace63f265da0db479270a 这大概是个序 关于Three.js,网上有不多 ...
- js 时钟特效
时钟特效 CreateTime--2018年2月24日15:11:23 Author:Marydon 实现方式:都是基于HTML5的canvas标签实现的 款式一 借助jQuery插件实现 < ...
- 墙裂推荐4款js网页烟花特效
以下是几款网页特效和一款软件: http://keleyi.com/keleyi/phtml/jstexiao/1.htm http://keleyi.com/keleyi/phtml/jstexi ...
- 原生JS投票特效
效果:http://hovertree.com/texiao/js/24/ 效果图: 代码如下: <!DOCTYPE html> <html lang="en"& ...
- Js文字特效—文字段逐个变色循环
自己用来练习的,附上详细注释,如果有和我一样喜欢并想要学习Dom特效创作的朋友,推荐先系统了解Javascript中Html Dom Object部分的内容,包括常用方法及属性. <!DOCTY ...
- javascript js写特效日历
<!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
随机推荐
- <s:form action="login"...与<s:form action = "login.action".的区别
1.<s:form action="login" namespace="/login"> 它表示的是<form id="login& ...
- android开发之重写Application类
在android应用开发中,重写Application也算是比较常见的,以前开发的一些程序太过于简单,都不要重写这个类,但是在真正的商业开发中,重写Application类几乎是必做的. 为什么要重写 ...
- oracle数据快速删除
上文说了创建数据还原点的事,数据恢复的前提是我们在删除的时候使用了delete命令来删除,delete在删除的过程中会写日志(所以我们的数据才能够恢复),当然,写日志会导致删除速度变慢.如果我们使用t ...
- Hibernate 配置派生属性
在持久化类中,有些属性在表中没有对应的字段,可以在映射文件中设置派生属性. 比如在一个订单中有多个商品的价格,但没有计算总的价格,可以在持久化类中增添一个统计总价格的属性,在映射文件中配置一些信息. ...
- sum() over() 函数的使用
over不能单独使用,要和分析函数:rank(),dense_rank(),row_number(),sum()等一起使用. over函数的参数:over(partition by columnnam ...
- Java基础知识强化之网络编程笔记08:TCP之客户端键盘录入服务器控制台输出
1. 客户端: package cn.itcast_08; import java.io.BufferedReader; import java.io.BufferedWriter; import j ...
- Android(java)学习笔记180:Android MediaPlayer 播放prepareAsync called in state 8解决办法
使用android MediaPlayer播放音频文件时,有时会出现prepareasync called in state 8错误. 以下方法可以避免这个异常出现. 第一种方法: private ...
- android线程与线程池-----线程池(二)《android开发艺术与探索》
android 中的线程池 线程池的优点: 1 重用线程池中的线程,避免了线程的创建和销毁带来的性能开销 2 能有效的控制最大并发数,避免大量线程之间因为喜欢抢资源而导致阻塞 3 能够对线程进行简单的 ...
- WinEdt打开UTF-8文件乱码问题——ctex[转]
原来这么简单,mark一下! [转自:http://fstang.diandian.com/post/2012-04-17/40030401020] 其实这个问题网上文章已经有一大堆了...我只是记录 ...
- 在CentOS6.0上安装Oracle 11gR2 (11.2.0.1)以及基本的配置(一)
首先安装CentOS6.0 就不用说了.安装即可.唯一需要注意的就是后面Oracle 11G Installation guide中的Checking the Software Requireme ...