新年快乐! javascript实现超级炫酷的3D烟花特效


Posted in Javascript onJanuary 30, 2019

本文实例为大家分享了javascript实现3D烟花特效的具体代码,供大家参考,具体内容如下

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8" />
 <title></title>
 
<meta charset="utf-8">
<title>3D烟花</title>

<style>
html,body{
 margin:0px;
 width:100%;
 height:100%;
 overflow:hidden;
 background:#000;
}

#canvas{
 width:100%;
 height:100%;
}
</style>
</head>
 
 <body>
<canvas id="canvas" width="825" height="631"></canvas><script>
function initVars(){

 pi=Math.PI;
 ctx=canvas.getContext("2d");
 canvas.width=canvas.clientWidth;
 canvas.height=canvas.clientHeight;
 cx=canvas.width/2;
 cy=canvas.height/2;
 playerZ=-25;
 playerX=playerY=playerVX=playerVY=playerVZ=pitch=yaw=pitchV=yawV=0;
 scale=600;
 seedTimer=0;seedInterval=5,seedLife=100;gravity=.02;
 seeds=new Array();
 sparkPics=new Array();
 s="https://cantelope.org/NYE/";
 for(i=1;i<=10;++i){
 sparkPic=new Image();
 sparkPic.src=s+"spark"+i+".png";
 sparkPics.push(sparkPic);
 }
 sparks=new Array();
 pow1=new Audio(s+"pow1.ogg");
 pow2=new Audio(s+"pow2.ogg");
 pow3=new Audio(s+"pow3.ogg");
 pow4=new Audio(s+"pow4.ogg");
 frames = 0;
}

function rasterizePoint(x,y,z){

 var p,d;
 x-=playerX;
 y-=playerY;
 z-=playerZ;
 p=Math.atan2(x,z);
 d=Math.sqrt(x*x+z*z);
 x=Math.sin(p-yaw)*d;
 z=Math.cos(p-yaw)*d;
 p=Math.atan2(y,z);
 d=Math.sqrt(y*y+z*z);
 y=Math.sin(p-pitch)*d;
 z=Math.cos(p-pitch)*d;
 var rx1=-1000,ry1=1,rx2=1000,ry2=1,rx3=0,ry3=0,rx4=x,ry4=z,uc=(ry4-ry3)*(rx2-rx1)-(rx4-rx3)*(ry2-ry1);
 if(!uc) return {x:0,y:0,d:-1};
 var ua=((rx4-rx3)*(ry1-ry3)-(ry4-ry3)*(rx1-rx3))/uc;
 var ub=((rx2-rx1)*(ry1-ry3)-(ry2-ry1)*(rx1-rx3))/uc;
 if(!z)z=.000000001;
 if(ua>0&&ua<1&&ub>0&&ub<1){
 return {
 x:cx+(rx1+ua*(rx2-rx1))*scale,
 y:cy+y/z*scale,
 d:Math.sqrt(x*x+y*y+z*z)
 };
 }else{
 return {
 x:cx+(rx1+ua*(rx2-rx1))*scale,
 y:cy+y/z*scale,
 d:-1
 };
 }
}

function spawnSeed(){
 
 seed=new Object();
 seed.x=-50+Math.random()*100;
 seed.y=25;
 seed.z=-50+Math.random()*100;
 seed.vx=.1-Math.random()*.2;
 seed.vy=-1.5;//*(1+Math.random()/2);
 seed.vz=.1-Math.random()*.2;
 seed.born=frames;
 seeds.push(seed);
}

function splode(x,y,z){
 
 t=5+parseInt(Math.random()*150);
 sparkV=1+Math.random()*2.5;
 type=parseInt(Math.random()*3);
 switch(type){
 case 0:
 pic1=parseInt(Math.random()*10);
 break;
 case 1:
 pic1=parseInt(Math.random()*10);
 do{ pic2=parseInt(Math.random()*10); }while(pic2==pic1);
 break;
 case 2:
 pic1=parseInt(Math.random()*10);
 do{ pic2=parseInt(Math.random()*10); }while(pic2==pic1);
 do{ pic3=parseInt(Math.random()*10); }while(pic3==pic1 || pic3==pic2);
 break;
 }
 for(m=1;m<t;++m){
 spark=new Object();
 spark.x=x; spark.y=y; spark.z=z;
 p1=pi*2*Math.random();
 p2=pi*Math.random();
 v=sparkV*(1+Math.random()/6)
 spark.vx=Math.sin(p1)*Math.sin(p2)*v;
 spark.vz=Math.cos(p1)*Math.sin(p2)*v;
 spark.vy=Math.cos(p2)*v;
 switch(type){
 case 0: spark.img=sparkPics[pic1]; break;
 case 1:
 spark.img=sparkPics[parseInt(Math.random()*2)?pic1:pic2];
 break;
 case 2:
 switch(parseInt(Math.random()*3)){
 case 0: spark.img=sparkPics[pic1]; break;
 case 1: spark.img=sparkPics[pic2]; break;
 case 2: spark.img=sparkPics[pic3]; break;
 }
 break;
 }
 spark.radius=25+Math.random()*50;
 spark.alpha=1;
 spark.trail=new Array();
 sparks.push(spark);
 }
 switch(parseInt(Math.random()*4)){
 case 0: pow=new Audio(s+"pow1.ogg"); break;
 case 1: pow=new Audio(s+"pow2.ogg"); break;
 case 2: pow=new Audio(s+"pow3.ogg"); break;
 case 3: pow=new Audio(s+"pow4.ogg"); break;
 }
 d=Math.sqrt((x-playerX)*(x-playerX)+(y-playerY)*(y-playerY)+(z-playerZ)*(z-playerZ));
 pow.volume=1.5/(1+d/10);
 pow.play();
}

function doLogic(){
 
 if(seedTimer<frames){
 seedTimer=frames+seedInterval*Math.random()*10;
 spawnSeed();
 }
 for(i=0;i<seeds.length;++i){
 seeds[i].vy+=gravity;
 seeds[i].x+=seeds[i].vx;
 seeds[i].y+=seeds[i].vy;
 seeds[i].z+=seeds[i].vz;
 if(frames-seeds[i].born>seedLife){
 splode(seeds[i].x,seeds[i].y,seeds[i].z);
 seeds.splice(i,1);
 }
 }
 for(i=0;i<sparks.length;++i){
 if(sparks[i].alpha>0 && sparks[i].radius>5){
 sparks[i].alpha-=.01;
 sparks[i].radius/=1.02;
 sparks[i].vy+=gravity;
 point=new Object();
 point.x=sparks[i].x;
 point.y=sparks[i].y;
 point.z=sparks[i].z;
 if(sparks[i].trail.length){
 x=sparks[i].trail[sparks[i].trail.length-1].x;
 y=sparks[i].trail[sparks[i].trail.length-1].y;
 z=sparks[i].trail[sparks[i].trail.length-1].z;
 d=((point.x-x)*(point.x-x)+(point.y-y)*(point.y-y)+(point.z-z)*(point.z-z));
 if(d>9){
 sparks[i].trail.push(point);
 }
 }else{
 sparks[i].trail.push(point);
 }
 if(sparks[i].trail.length>5)sparks[i].trail.splice(0,1); 
 sparks[i].x+=sparks[i].vx;
 sparks[i].y+=sparks[i].vy;
 sparks[i].z+=sparks[i].vz;
 sparks[i].vx/=1.075;
 sparks[i].vy/=1.075;
 sparks[i].vz/=1.075;
 }else{
 sparks.splice(i,1);
 }
 }
 p=Math.atan2(playerX,playerZ);
 d=Math.sqrt(playerX*playerX+playerZ*playerZ);
 d+=Math.sin(frames/80)/1.25;
 t=Math.sin(frames/200)/40;
 playerX=Math.sin(p+t)*d;
 playerZ=Math.cos(p+t)*d;
 yaw=pi+p+t;
}

function rgb(col){
 
 var r = parseInt((.5+Math.sin(col)*.5)*16);
 var g = parseInt((.5+Math.cos(col)*.5)*16);
 var b = parseInt((.5-Math.sin(col)*.5)*16);
 return "#"+r.toString(16)+g.toString(16)+b.toString(16);
}

function draw(){
 
 ctx.clearRect(0,0,cx*2,cy*2);
 
 ctx.fillStyle="#ff8";
 for(i=-100;i<100;i+=3){
 for(j=-100;j<100;j+=4){
 x=i;z=j;y=25;
 point=rasterizePoint(x,y,z);
 if(point.d!=-1){
 size=250/(1+point.d);
 d = Math.sqrt(x * x + z * z);
 a = 0.75 - Math.pow(d / 100, 6) * 0.75;
 if(a>0){
 ctx.globalAlpha = a;
 ctx.fillRect(point.x-size/2,point.y-size/2,size,size); 
 }
 }
 }
 }
 ctx.globalAlpha=1;
 for(i=0;i<seeds.length;++i){
 point=rasterizePoint(seeds[i].x,seeds[i].y,seeds[i].z);
 if(point.d!=-1){
 size=200/(1+point.d);
 ctx.fillRect(point.x-size/2,point.y-size/2,size,size);
 }
 }
 point1=new Object();
 for(i=0;i<sparks.length;++i){
 point=rasterizePoint(sparks[i].x,sparks[i].y,sparks[i].z);
 if(point.d!=-1){
 size=sparks[i].radius*200/(1+point.d);
 if(sparks[i].alpha<0)sparks[i].alpha=0;
 if(sparks[i].trail.length){
 point1.x=point.x;
 point1.y=point.y;
 switch(sparks[i].img){
 case sparkPics[0]:ctx.strokeStyle="#f84";break;
 case sparkPics[1]:ctx.strokeStyle="#84f";break;
 case sparkPics[2]:ctx.strokeStyle="#8ff";break;
 case sparkPics[3]:ctx.strokeStyle="#fff";break;
 case sparkPics[4]:ctx.strokeStyle="#4f8";break;
 case sparkPics[5]:ctx.strokeStyle="#f44";break;
 case sparkPics[6]:ctx.strokeStyle="#f84";break;
 case sparkPics[7]:ctx.strokeStyle="#84f";break;
 case sparkPics[8]:ctx.strokeStyle="#fff";break;
 case sparkPics[9]:ctx.strokeStyle="#44f";break;
 }
 for(j=sparks[i].trail.length-1;j>=0;--j){
 point2=rasterizePoint(sparks[i].trail[j].x,sparks[i].trail[j].y,sparks[i].trail[j].z);
 if(point2.d!=-1){
 ctx.globalAlpha=j/sparks[i].trail.length*sparks[i].alpha/2;
 ctx.beginPath();
 ctx.moveTo(point1.x,point1.y);
 ctx.lineWidth=1+sparks[i].radius*10/(sparks[i].trail.length-j)/(1+point2.d);
 ctx.lineTo(point2.x,point2.y);
 ctx.stroke();
 point1.x=point2.x;
 point1.y=point2.y;
 }
 }
 }
 ctx.globalAlpha=sparks[i].alpha;
 ctx.drawImage(sparks[i].img,point.x-size/2,point.y-size/2,size,size);
 }
 }
}

function frame(){

 if(frames>100000){
 seedTimer=0;
 frames=0;
 }
 frames++;
 draw();
 doLogic();
 requestAnimationFrame(frame);
}

window.addEventListener("resize",()=>{
 canvas.width=canvas.clientWidth;
 canvas.height=canvas.clientHeight;
 cx=canvas.width/2;
 cy=canvas.height/2;
});

initVars();
frame();</script>


</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
腾讯与新浪的通过IP地址获取当前地理位置(省份)的接口
Jul 26 Javascript
JavaScript判断表单提交时哪个radio按钮被选中的方法
Mar 21 Javascript
JS实现单击输入框弹出选择框效果完整实例
Dec 14 Javascript
easyui validatebox验证
Apr 29 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
May 16 Javascript
BootStrap实现树形目录组件代码详解
Jun 21 Javascript
JS点击某个图标或按钮弹出文件选择框的实现代码
Sep 27 Javascript
react开发教程之React 组件之间的通信方式
Aug 12 Javascript
谈谈IntersectionObserver懒加载的具体使用
Oct 15 Javascript
解决vue-cli@3.xx安装不成功的问题及搭建ts-vue项目
Feb 09 Javascript
jQuery实现点击滚动到指定元素上的方法分析
Mar 19 jQuery
vue select 获取value和lable操作
Aug 28 Javascript
JavaScript之解构赋值的理解
Jan 30 #Javascript
JS实现点击按钮随机生成可拖动的不同颜色块示例
Jan 30 #Javascript
JS实现的新闻列表自动滚动效果示例
Jan 30 #Javascript
谈谈为什么你的 JavaScript 代码如此冗长
Jan 30 #Javascript
JS实现头条新闻的经典轮播图效果示例
Jan 30 #Javascript
AJAX在JQuery中的应用详解
Jan 30 #jQuery
JS实现换肤功能的方法实例详解
Jan 30 #Javascript
You might like
php仿discuz分页效果代码
2008/10/02 PHP
php截取字符串并保留完整xml标签的函数代码
2013/02/06 PHP
PHP实现抓取Google IP并自动修改hosts文件
2015/02/12 PHP
php计算两个文件相对路径的方法
2015/03/14 PHP
PHP检测接口Traversable用法详解
2017/12/29 PHP
php swoft框架实例用法
2020/12/22 PHP
一个JS小玩意 几个属性相加不能超过一个特定值.
2009/09/29 Javascript
让IE8支持DOM 2(不用框架!)
2009/12/31 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
seajs中模块的解析规则详解和模块使用总结
2014/03/12 Javascript
JQuery Mobile实现导航栏和页脚
2016/03/09 Javascript
jQuery实现Select下拉列表进行状态选择功能
2017/03/30 jQuery
node.js中EJS 模板快速入门教程
2017/05/08 Javascript
网页中的图片查看器viewjs使用方法
2017/07/11 Javascript
vuex2中使用mapGetters/mapActions报错的解决方法
2018/10/20 Javascript
详解BootStrap表单验证中重置BootStrap-select验证提示不清除的坑
2019/09/17 Javascript
如何在node环境实现“get数据解析”代码实例
2020/07/03 Javascript
JavaScript实现与web通信的方法详解
2020/08/07 Javascript
python实现在无须过多援引的情况下创建字典的方法
2014/09/25 Python
matplotlib中legend位置调整解析
2017/12/19 Python
python数据分析数据标准化及离散化详解
2018/02/26 Python
Python数据结构与算法(几种排序)小结
2019/06/22 Python
与Django结合利用模型对上传图片预测的实例详解
2019/08/07 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
pytorch进行上采样的种类实例
2020/02/18 Python
python3使用Pillow、tesseract-ocr与pytesseract模块的图片识别的方法
2020/02/26 Python
Python Pandas list列表数据列拆分成多行的方法实现
2020/12/14 Python
德国健康生活方式网上商店:Landkaufhaus Mayer
2019/03/12 全球购物
幼儿园教师岗位职责
2014/03/17 职场文书
端午节演讲稿
2014/05/23 职场文书
团干部培训方案
2014/06/03 职场文书
优秀员工评优方案
2014/06/13 职场文书
装修施工安全责任书
2014/07/24 职场文书
工作汇报开头与结尾怎么写
2014/11/08 职场文书
故宫导游词
2015/01/31 职场文书
董存瑞观后感
2015/06/11 职场文书