javascript实现超好看的3D烟花特效


Posted in Javascript onJanuary 01, 2020

本文实例为大家分享了超好看3D烟花的具体代码,供大家参考,具体内容如下

javascript实现超好看的3D烟花特效

<!doctype html>
<html>
<head>
<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"></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>
<div style="text-align:center;">
</div>
</body>
</html>

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

Javascript 相关文章推荐
Javascript改变CSS样式(局部和全局)
Dec 18 Javascript
js中hash和ico的关联分析
Feb 05 Javascript
JavaScript Function函数类型介绍
Apr 08 Javascript
微信小程序动态的加载数据实例代码
Apr 14 Javascript
es7学习教程之fetch解决异步嵌套问题的方法示例
Jul 21 Javascript
Vue.js学习笔记之常用模板语法详解
Jul 25 Javascript
Vue中计算属性computed的示例解读
Jul 26 Javascript
js循环map 获取所有的key和value的实现代码(json)
May 09 Javascript
解析vue data不可以使用箭头函数问题
Jul 03 Javascript
亲自动手实现vue日历控件
Jun 26 Javascript
ES6学习笔记之字符串、数组、对象、函数新增知识点实例分析
Jan 22 Javascript
微信公众号网页分享功能开发的示例代码
May 27 Javascript
JavaScript工具库MyTools详解
Jan 01 #Javascript
javascript Canvas动态粒子连线
Jan 01 #Javascript
小程序新版订阅消息模板消息
Dec 31 #Javascript
小程序实现长按保存图片的方法
Dec 31 #Javascript
使用webpack搭建vue环境的教程详解
Dec 31 #Javascript
Vue 实现显示/隐藏层的思路(加全局点击事件)
Dec 31 #Javascript
TypeScript之调用栈的实现
Dec 31 #Javascript
You might like
笑谈配置,使用Smarty技术
2007/01/04 PHP
基于pear auth实现登录验证
2010/02/26 PHP
wordpress自定义url参数实现路由功能的代码示例
2013/11/28 PHP
PHP中SERIALIZE和JSON的序列化与反序列化操作区别分析
2016/10/11 PHP
PHP策略模式定义与用法示例
2017/07/27 PHP
PDO::quote讲解
2019/01/29 PHP
js tab 选项卡
2009/04/26 Javascript
js跨域和ajax 跨域问题的实现思路
2009/09/05 Javascript
理解Javascript_08_函数对象
2010/10/15 Javascript
jQuery随机切换图片的小例子
2013/04/18 Javascript
ParseInt函数参数设置介绍
2014/01/02 Javascript
Javascript玩转继承(三)
2014/05/08 Javascript
javascript数组去重的方法汇总
2015/04/14 Javascript
js中的深浅拷贝问题简析
2019/05/10 Javascript
JavaScript实现简单随机点名器
2019/11/21 Javascript
[01:09:10]NB vs Liquid Supermajor小组赛 A组胜者组决赛 BO3 第一场 6.2
2018/06/04 DOTA
[01:18:21]EG vs TNC Supermajor小组赛B组败者组第一轮 BO3 第一场 6.2
2018/06/03 DOTA
python将文本转换成图片输出的方法
2015/04/28 Python
Python+微信接口实现运维报警
2016/08/27 Python
python爬虫实战之最简单的网页爬虫教程
2017/08/13 Python
使用 Python 快速实现 HTTP 和 FTP 服务器的方法
2019/07/22 Python
服务器端jupyter notebook映射到本地浏览器的操作
2020/04/14 Python
python3.7添加dlib模块的方法
2020/07/01 Python
localStorage 设置过期时间的方法实现
2018/12/21 HTML / CSS
美国在线眼镜店:GlassesShop
2018/11/15 全球购物
产品销售员岗位职责
2013/12/18 职场文书
妇联领导班子剖析材料
2014/08/21 职场文书
领导干部群众路线教育实践活动剖析材料
2014/10/10 职场文书
2014年幼儿园工作总结
2014/11/10 职场文书
全陪导游词
2015/02/04 职场文书
工作经历证明范本
2015/06/15 职场文书
2016年六一文艺汇演开幕词
2016/03/04 职场文书
pytorch fine-tune 预训练的模型操作
2021/06/03 Python
MySQL 使用索引扫描进行排序
2021/06/20 MySQL
Spring-cloud Config Server的3种配置方式
2021/09/25 Java/Android
九大龙王魂骨,山龙王留下躯干骨,榜首死的最憋屈(被捏碎)
2022/03/18 国漫