新年快乐! 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 相关文章推荐
Javascript变量函数浅析
Sep 02 Javascript
下载文件个别浏览器文件名乱码解决办法
Mar 19 Javascript
Javascript图片上传前的本地预览实例
Jun 16 Javascript
JavaScript字符串对象slice方法入门实例(用于字符串截取)
Oct 16 Javascript
在Node.js应用中读写Redis数据库的简单方法
Jun 30 Javascript
JavaScript实现删除,移动和复制文件的方法
Aug 05 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
Jul 28 Javascript
详细总结Javascript中的焦点管理
Sep 17 Javascript
xmlplus组件设计系列之选项卡(Tabbar)(5)
May 03 Javascript
vue-router实现组件间的跳转(参数传递)
Nov 07 Javascript
vue新建项目并配置标准路由过程解析
Dec 09 Javascript
JavaScript实现简单拖拽效果
Sep 15 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
深入解析yii权限分级式访问控制的实现(非RBAC法)
2013/06/13 PHP
php 验证码(倾斜,正弦干扰线,黏贴,旋转)
2013/06/29 PHP
jquery 学习之二 属性(类)
2010/11/25 Javascript
js this函数调用无需再次抓获id,name或标签名
2014/03/03 Javascript
jquery用ajax方式从后台获取json数据后如何将内容填充到下拉列表
2015/08/26 Javascript
Jquery常用的方法汇总
2015/09/01 Javascript
jQuery中bind(),live(),delegate(),on()绑定事件方法实例详解
2016/01/19 Javascript
即将发布的jQuery 3 有哪些新特性
2016/04/14 Javascript
JS实现的几个常用算法
2016/11/12 Javascript
bootstrap fileinput 插件使用项目总结(经验)
2017/02/22 Javascript
jQuery基本选择器和层次选择器学习使用
2017/02/27 Javascript
浅谈js for循环输出i为同一值的问题
2017/03/01 Javascript
Angular2环境搭建具体操作步骤(推荐)
2017/08/04 Javascript
nginx部署访问vue-cli搭建的项目的方法
2018/02/12 Javascript
微信小程序自定义组件传值 页面和组件相互传数据操作示例
2019/05/05 Javascript
详解Jest结合Vue-test-utils使用的初步实践
2019/06/27 Javascript
js获取浏览器地址(获取第1个斜杠后的内容)
2019/09/03 Javascript
[01:06]DOTA2小知识课堂 Ep.02 吹风竟可解梦境缠绕
2019/12/05 DOTA
[30:00]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第二场 11.28
2020/12/01 DOTA
python OpenCV学习笔记实现二维直方图
2018/02/08 Python
Python代理IP爬虫的新手使用教程
2019/09/05 Python
Python常用模块os.path之文件及路径操作方法
2019/12/03 Python
详解Python中pyautogui库的最全使用方法
2020/04/01 Python
Python使用os.listdir和os.walk获取文件路径
2020/05/21 Python
Python OpenCV读取中文路径图像的方法
2020/07/02 Python
新西兰廉价汽车租赁:Snap Rentals
2018/09/14 全球购物
微软加拿大官方网站:Microsoft Canada
2019/04/28 全球购物
邮政员工辞职信
2014/01/16 职场文书
服装设计专业自荐信
2014/06/17 职场文书
小区门卫的岗位职责
2014/09/26 职场文书
五年级学生评语大全
2014/12/26 职场文书
优秀高中学生评语
2014/12/30 职场文书
给校长的建议书作文500字
2015/09/14 职场文书
乡镇团代会开幕词
2016/03/04 职场文书
2016年小学端午节活动总结
2016/04/01 职场文书
JS创建或填充任意长度数组的小技巧汇总
2021/10/24 Javascript