0


除夕用不同的语言编写绚丽的烟花

不同语言编写的绚丽烟花

简单Html先来一个简单的形象实现烟花(绝对绚丽)

先看效果
请添加图片描述
源码

  1. <!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>html5 canvas除夕烟花</title><base target="_blank"/><link rel="stylesheet" type="text/css" href="http://hovertree.com/texiao/html5/43/css/normalize.css"/><link rel="stylesheet" type="text/css" href="http://hovertree.com/texiao/html5/43/css/hovertree.css"></head><body><div class="hovertree"></div><script type="text/javascript" src="http://down.hovertree.com/jquery/jquery-1.11.0.min.js"></script><script type="text/javascript" src="http://hovertree.com/texiao/html5/43/js/jquery.fireworks.js"></script><script type="text/javascript">$('.hovertree').fireworks({
  2. sound:true,// sound effect
  3. opacity:0.9,
  4. width:'100%',
  5. height:'100%'});</script><div style="width:340px;position:fixed;z-index:99;"><a href="http://hovertree.com/"></a><a href="http://hovertree.com/h/bjag/me34x8fk.htm"></a></div></body></html>

HTML+Canvas(内含js)

我们先看实现效果
在这里插入图片描述

源码如下,一共三百多行

  1. <!doctype html><html><head><meta charset="utf-8"><title>除夕炫彩</title><style>
  2. html,body{
  3. margin:0px;
  4. width:100%;
  5. height:100%;
  6. overflow:hidden;
  7. background:#000;}</style></head><body><canvas id="canvas" style="position:absolute;width:100%;height:100%;z-index:8888"></canvas><canvas style="position:absolute;width:100%;height:100%;z-index:9999"class="canvas"></canvas><div class="overlay"><div class="tabs"><div class="tabs-labels"><span class="tabs-label">Commands</span><span class="tabs-label">Info</span><span class="tabs-label">Share</span></div><div class="tabs-panels"><ul class="tabs-panel commands"></ul></div></div></div><script>functioninitVars(){
  8. pi=Math.PI;
  9. ctx=canvas.getContext("2d");
  10. canvas.width=canvas.clientWidth;
  11. canvas.height=canvas.clientHeight;
  12. cx=canvas.width/2;
  13. cy=canvas.height/2;
  14. playerZ=-25;
  15. playerX=playerY=playerVX=playerVY=playerVZ=pitch=yaw=pitchV=yawV=0;
  16. scale=600;
  17. seedTimer=0;seedInterval=5,seedLife=100;gravity=.02;
  18. seeds=newArray();
  19. sparkPics=newArray();
  20. s="https://cantelope.org/NYE/";for(i=1;i<=10;++i){
  21. sparkPic=newImage();
  22. sparkPic.src=s+"spark"+i+".png";
  23. sparkPics.push(sparkPic);}
  24. sparks=newArray();
  25. pow1=newAudio(s+"pow1.ogg");
  26. pow2=newAudio(s+"pow2.ogg");
  27. pow3=newAudio(s+"pow3.ogg");
  28. pow4=newAudio(s+"pow4.ogg");
  29. frames =0;}functionrasterizePoint(x,y,z){var p,d;
  30. x-=playerX;
  31. y-=playerY;
  32. z-=playerZ;
  33. p=Math.atan2(x,z);
  34. d=Math.sqrt(x*x+z*z);
  35. x=Math.sin(p-yaw)*d;
  36. z=Math.cos(p-yaw)*d;
  37. p=Math.atan2(y,z);
  38. d=Math.sqrt(y*y+z*z);
  39. y=Math.sin(p-pitch)*d;
  40. 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{
  41. x:cx+(rx1+ua*(rx2-rx1))*scale,
  42. y:cy+y/z*scale,
  43. d:Math.sqrt(x*x+y*y+z*z)};}else{return{
  44. x:cx+(rx1+ua*(rx2-rx1))*scale,
  45. y:cy+y/z*scale,
  46. d:-1};}}functionspawnSeed(){
  47. seed=newObject();
  48. seed.x=-50+Math.random()*100;
  49. seed.y=25;
  50. seed.z=-50+Math.random()*100;
  51. seed.vx=.1-Math.random()*.2;
  52. seed.vy=-1.5;//*(1+Math.random()/2);
  53. seed.vz=.1-Math.random()*.2;
  54. seed.born=frames;
  55. seeds.push(seed);}functionsplode(x,y,z){
  56. t=5+parseInt(Math.random()*150);
  57. sparkV=1+Math.random()*2.5;
  58. type=parseInt(Math.random()*3);switch(type){case0:
  59. pic1=parseInt(Math.random()*10);break;case1:
  60. pic1=parseInt(Math.random()*10);do{ pic2=parseInt(Math.random()*10);}while(pic2==pic1);break;case2:
  61. 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){
  62. spark=newObject();
  63. spark.x=x; spark.y=y; spark.z=z;
  64. p1=pi*2*Math.random();
  65. p2=pi*Math.random();
  66. v=sparkV*(1+Math.random()/6)
  67. spark.vx=Math.sin(p1)*Math.sin(p2)*v;
  68. spark.vz=Math.cos(p1)*Math.sin(p2)*v;
  69. spark.vy=Math.cos(p2)*v;switch(type){case0: spark.img=sparkPics[pic1];break;case1:
  70. spark.img=sparkPics[parseInt(Math.random()*2)?pic1:pic2];break;case2:switch(parseInt(Math.random()*3)){case0: spark.img=sparkPics[pic1];break;case1: spark.img=sparkPics[pic2];break;case2: spark.img=sparkPics[pic3];break;}break;}
  71. spark.radius=25+Math.random()*50;
  72. spark.alpha=1;
  73. spark.trail=newArray();
  74. sparks.push(spark);}switch(parseInt(Math.random()*4)){case0: pow=newAudio(s+"pow1.ogg");break;case1: pow=newAudio(s+"pow2.ogg");break;case2: pow=newAudio(s+"pow3.ogg");break;case3: pow=newAudio(s+"pow4.ogg");break;}
  75. d=Math.sqrt((x-playerX)*(x-playerX)+(y-playerY)*(y-playerY)+(z-playerZ)*(z-playerZ));
  76. pow.volume=1.5/(1+d/10);
  77. pow.play();}functiondoLogic(){if(seedTimer<frames){
  78. seedTimer=frames+seedInterval*Math.random()*10;spawnSeed();}for(i=0;i<seeds.length;++i){
  79. seeds[i].vy+=gravity;
  80. seeds[i].x+=seeds[i].vx;
  81. seeds[i].y+=seeds[i].vy;
  82. seeds[i].z+=seeds[i].vz;if(frames-seeds[i].born>seedLife){splode(seeds[i].x,seeds[i].y,seeds[i].z);
  83. seeds.splice(i,1);}}for(i=0;i<sparks.length;++i){if(sparks[i].alpha>0&& sparks[i].radius>5){
  84. sparks[i].alpha-=.01;
  85. sparks[i].radius/=1.02;
  86. sparks[i].vy+=gravity;
  87. point=newObject();
  88. point.x=sparks[i].x;
  89. point.y=sparks[i].y;
  90. point.z=sparks[i].z;if(sparks[i].trail.length){
  91. x=sparks[i].trail[sparks[i].trail.length-1].x;
  92. y=sparks[i].trail[sparks[i].trail.length-1].y;
  93. z=sparks[i].trail[sparks[i].trail.length-1].z;
  94. d=((point.x-x)*(point.x-x)+(point.y-y)*(point.y-y)+(point.z-z)*(point.z-z));if(d>9){
  95. sparks[i].trail.push(point);}}else{
  96. sparks[i].trail.push(point);}if(sparks[i].trail.length>5)sparks[i].trail.splice(0,1);
  97. sparks[i].x+=sparks[i].vx;
  98. sparks[i].y+=sparks[i].vy;
  99. sparks[i].z+=sparks[i].vz;
  100. sparks[i].vx/=1.075;
  101. sparks[i].vy/=1.075;
  102. sparks[i].vz/=1.075;}else{
  103. sparks.splice(i,1);}}
  104. p=Math.atan2(playerX,playerZ);
  105. d=Math.sqrt(playerX*playerX+playerZ*playerZ);
  106. d+=Math.sin(frames/80)/1.25;
  107. t=Math.sin(frames/200)/40;
  108. playerX=Math.sin(p+t)*d;
  109. playerZ=Math.cos(p+t)*d;
  110. yaw=pi+p+t;}functionrgb(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);}functiondraw(){
  111. ctx.clearRect(0,0,cx*2,cy*2);
  112. ctx.fillStyle="#ff8";for(i=-100;i<100;i+=3){for(j=-100;j<100;j+=4){
  113. x=i;z=j;y=25;
  114. point=rasterizePoint(x,y,z);if(point.d!=-1){
  115. size=250/(1+point.d);
  116. d = Math.sqrt(x * x + z * z);
  117. a =0.75- Math.pow(d /100,6)*0.75;if(a>0){
  118. ctx.globalAlpha = a;
  119. ctx.fillRect(point.x-size/2,point.y-size/2,size,size);}}}}
  120. ctx.globalAlpha=1;for(i=0;i<seeds.length;++i){
  121. point=rasterizePoint(seeds[i].x,seeds[i].y,seeds[i].z);if(point.d!=-1){
  122. size=200/(1+point.d);
  123. ctx.fillRect(point.x-size/2,point.y-size/2,size,size);}}
  124. point1=newObject();for(i=0;i<sparks.length;++i){
  125. point=rasterizePoint(sparks[i].x,sparks[i].y,sparks[i].z);if(point.d!=-1){
  126. size=sparks[i].radius*200/(1+point.d);if(sparks[i].alpha<0)sparks[i].alpha=0;if(sparks[i].trail.length){
  127. point1.x=point.x;
  128. 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){
  129. point2=rasterizePoint(sparks[i].trail[j].x,sparks[i].trail[j].y,sparks[i].trail[j].z);if(point2.d!=-1){
  130. ctx.globalAlpha=j/sparks[i].trail.length*sparks[i].alpha/2;
  131. ctx.beginPath();
  132. ctx.moveTo(point1.x,point1.y);
  133. ctx.lineWidth=1+sparks[i].radius*10/(sparks[i].trail.length-j)/(1+point2.d);
  134. ctx.lineTo(point2.x,point2.y);
  135. ctx.stroke();
  136. point1.x=point2.x;
  137. point1.y=point2.y;}}}
  138. ctx.globalAlpha=sparks[i].alpha;
  139. ctx.drawImage(sparks[i].img,point.x-size/2,point.y-size/2,size,size);}}}functionframe(){if(frames>100000){
  140. seedTimer=0;
  141. frames=0;}
  142. frames++;draw();doLogic();requestAnimationFrame(frame);}
  143. window.addEventListener("resize",()=>{
  144. canvas.width=canvas.clientWidth;
  145. canvas.height=canvas.clientHeight;
  146. cx=canvas.width/2;
  147. cy=canvas.height/2;});initVars();frame();</script><script src="js/index.js"></script></body></html>

下面是引用的js源码,js渲染需要比较多的代码。

  1. varS={init:function(){var action = window.location.href,
  2. i = action.indexOf('?a=');S.Drawing.init('.canvas');
  3. document.body.classList.add('body--ready');if(i !==-1){S.UI.simulate(decodeURI(action).substring(i +3));}else{S.UI.simulate('除夕节日快乐');}S.Drawing.loop(function(){S.Shape.render();});}};S.Drawing =(function(){var canvas,
  4. context,
  5. renderFn
  6. requestFrame = window.requestAnimationFrame ||
  7. window.webkitRequestAnimationFrame ||
  8. window.mozRequestAnimationFrame ||
  9. window.oRequestAnimationFrame ||
  10. window.msRequestAnimationFrame ||function(callback){
  11. window.setTimeout(callback,1000/60);};return{init:function(el){
  12. canvas = document.querySelector(el);
  13. context = canvas.getContext('2d');this.adjustCanvas();
  14. window.addEventListener('resize',function(e){S.Drawing.adjustCanvas();});},loop:function(fn){
  15. renderFn =!renderFn ? fn : renderFn;this.clearFrame();renderFn();requestFrame.call(window,this.loop.bind(this));},adjustCanvas:function(){
  16. canvas.width = window.innerWidth;
  17. canvas.height = window.innerHeight;},clearFrame:function(){
  18. context.clearRect(0,0, canvas.width, canvas.height);},getArea:function(){return{ w: canvas.width, h: canvas.height };},drawCircle:function(p, c){
  19. context.fillStyle = c.render();
  20. context.beginPath();
  21. context.arc(p.x, p.y, p.z,0,2* Math.PI,true);
  22. context.closePath();
  23. context.fill();}}}());S.UI=(function(){var canvas = document.querySelector('.canvas'),
  24. interval,
  25. isTouch =false,//('ontouchstart' in window || navigator.msMaxTouchPoints),
  26. currentAction,
  27. resizeTimer,
  28. time,
  29. maxShapeSize =30,
  30. firstAction =true,
  31. sequence =[],
  32. cmd ='#';functionformatTime(date){var h = date.getHours(),
  33. m = date.getMinutes(),
  34. m = m <10?'0'+ m : m;return h +':'+ m;}functiongetValue(value){return value && value.split(' ')[1];}functiongetAction(value){
  35. value = value && value.split(' ')[0];return value && value[0]=== cmd && value.substring(1);}functiontimedAction(fn, delay, max, reverse){clearInterval(interval);
  36. currentAction = reverse ? max :1;fn(currentAction);if(!max ||(!reverse && currentAction < max)||(reverse && currentAction >0)){
  37. interval =setInterval(function(){
  38. currentAction = reverse ? currentAction -1: currentAction +1;fn(currentAction);if((!reverse && max && currentAction === max)||(reverse && currentAction ===0)){clearInterval(interval);}}, delay);}}functionreset(destroy){clearInterval(interval);
  39. sequence =[];
  40. time =null;
  41. destroy &&S.Shape.switchShape(S.ShapeBuilder.letter(''));}functionperformAction(value){var action,
  42. value,
  43. current;// overlay.classList.remove('overlay--visible');
  44. sequence =typeof(value)==='object'? value : sequence.concat(value.split('|'));// input.value = '';// checkInputWidth();timedAction(function(index){
  45. current = sequence.shift();
  46. action =getAction(current);
  47. value =getValue(current);switch(action){case'countdown':
  48. value =parseInt(value)||10;
  49. value = value >0? value :10;timedAction(function(index){if(index ===0){if(sequence.length ===0){S.Shape.switchShape(S.ShapeBuilder.letter(''));}else{performAction(sequence);}}else{S.Shape.switchShape(S.ShapeBuilder.letter(index),true);}},1000, value,true);break;case'rectangle':
  50. value = value && value.split('x');
  51. value =(value && value.length ===2)? value :[maxShapeSize, maxShapeSize /2];S.Shape.switchShape(S.ShapeBuilder.rectangle(Math.min(maxShapeSize,parseInt(value[0])), Math.min(maxShapeSize,parseInt(value[1]))));break;case'circle':
  52. value =parseInt(value)|| maxShapeSize;
  53. value = Math.min(value, maxShapeSize);S.Shape.switchShape(S.ShapeBuilder.circle(value));break;case'time':var t =formatTime(newDate());if(sequence.length >0){S.Shape.switchShape(S.ShapeBuilder.letter(t));}else{timedAction(function(){
  54. t =formatTime(newDate());if(t !== time){
  55. time = t;S.Shape.switchShape(S.ShapeBuilder.letter(time));}},1000);}break;default:S.Shape.switchShape(S.ShapeBuilder.letter(current[0]=== cmd ?'What?': current));}},2000, sequence.length);}functioncheckInputWidth(e){if(input.value.length >18){
  56. ui.classList.add('ui--wide');}else{
  57. ui.classList.remove('ui--wide');}if(firstAction && input.value.length >0){
  58. ui.classList.add('ui--enter');}else{
  59. ui.classList.remove('ui--enter');}}functionbindEvents(){
  60. document.body.addEventListener('keydown',function(e){
  61. input.focus();if(e.keyCode ===13){
  62. firstAction =false;reset();performAction(input.value);}});
  63. canvas.addEventListener('click',function(e){
  64. overlay.classList.remove('overlay--visible');});}functioninit(){bindEvents();// input.focus();
  65. isTouch && document.body.classList.add('touch');}// Initinit();return{simulate:function(action){performAction(action);}}}());S.UI.Tabs =(function(){var tabs = document.querySelector('.tabs'),
  66. labels = document.querySelector('.tabs-labels'),
  67. triggers = document.querySelectorAll('.tabs-label'),
  68. panels = document.querySelectorAll('.tabs-panel');functionactivate(i){
  69. triggers[i].classList.add('tabs-label--active');
  70. panels[i].classList.add('tabs-panel--active');}functionbindEvents(){
  71. labels.addEventListener('click',function(e){var el = e.target,
  72. index;if(el.classList.contains('tabs-label')){for(var t =0; t < triggers.length; t++){
  73. triggers[t].classList.remove('tabs-label--active');
  74. panels[t].classList.remove('tabs-panel--active');if(el === triggers[t]){
  75. index = t;}}activate(index);}});}functioninit(){activate(0);bindEvents();}// Initinit();}());S.Point=function(args){this.x = args.x;this.y = args.y;this.z = args.z;this.a = args.a;this.h = args.h;};S.Color=function(r, g, b, a){this.r = r;this.g = g;this.b = b;this.a = a;};S.Color.prototype ={render:function(){return'rgba('+this.r +','++this.g +','+this.b +','+this.a +')';}};S.Dot=function(x, y){this.p =newS.Point({
  76. x: x,
  77. y: y,
  78. z:5,
  79. a:1,
  80. h:0});this.e =0.07;this.s =true;this.c =newS.Color(255,255,255,this.p.a);this.t =this.clone();this.q =[];};S.Dot.prototype ={clone:function(){returnnewS.Point({
  81. x:this.x,
  82. y:this.y,
  83. z:this.z,
  84. a:this.a,
  85. h:this.h
  86. });},_draw:function(){this.c.a =this.p.a;S.Drawing.drawCircle(this.p,this.c);},_moveTowards:function(n){var details =this.distanceTo(n,true),
  87. dx = details[0],
  88. dy = details[1],
  89. d = details[2],
  90. e =this.e * d;if(this.p.h ===-1){this.p.x = n.x;this.p.y = n.y;returntrue;}if(d >1){this.p.x -=((dx / d)* e);this.p.y -=((dy / d)* e);}else{if(this.p.h >0){this.p.h--;}else{returntrue;}}returnfalse;},_update:function(){if(this._moveTowards(this.t)){var p =this.q.shift();if(p){this.t.x = p.x ||this.p.x;this.t.y = p.y ||this.p.y;this.t.z = p.z ||this.p.z;this.t.a = p.a ||this.p.a;this.p.h = p.h ||0;}else{if(this.s){this.p.x -= Math.sin(Math.random()*3.142);this.p.y -= Math.sin(Math.random()*3.142);}else{this.move(newS.Point({
  91. x:this.p.x +(Math.random()*50)-25,
  92. y:this.p.y +(Math.random()*50)-25,}));}}}
  93. d =this.p.a -this.t.a;this.p.a = Math.max(0.1,this.p.a -(d *0.05));
  94. d =this.p.z -this.t.z;this.p.z = Math.max(1,this.p.z -(d *0.05));},distanceTo:function(n, details){var dx =this.p.x - n.x,
  95. dy =this.p.y - n.y,
  96. d = Math.sqrt(dx * dx + dy * dy);return details ?[dx, dy, d]: d;},move:function(p, avoidStatic){if(!avoidStatic ||(avoidStatic &&this.distanceTo(p)>1)){this.q.push(p);}},render:function(){this._update();this._draw();}}S.ShapeBuilder =(function(){var gap =13,
  97. shapeCanvas = document.createElement('canvas'),
  98. shapeContext = shapeCanvas.getContext('2d'),
  99. fontSize =500,
  100. fontFamily ='Avenir, Helvetica Neue, Helvetica, Arial, sans-serif';functionfit(){
  101. shapeCanvas.width = Math.floor(window.innerWidth / gap)* gap;
  102. shapeCanvas.height = Math.floor(window.innerHeight / gap)* gap;
  103. shapeContext.fillStyle ='red';
  104. shapeContext.textBaseline ='middle';
  105. shapeContext.textAlign ='center';}functionprocessCanvas(){var pixels = shapeContext.getImageData(0,0, shapeCanvas.width, shapeCanvas.height).data;
  106. dots =[],
  107. pixels,
  108. x =0,
  109. y =0,
  110. fx = shapeCanvas.width,
  111. fy = shapeCanvas.height,
  112. w =0,
  113. h =0;for(var p =0; p < pixels.length; p +=(4* gap)){if(pixels[p +3]>0){
  114. dots.push(newS.Point({
  115. x: x,
  116. y: y
  117. }));
  118. w = x > w ? x : w;
  119. h = y > h ? y : h;
  120. fx = x < fx ? x : fx;
  121. fy = y < fy ? y : fy;}
  122. x += gap;if(x >= shapeCanvas.width){
  123. x =0;
  124. y += gap;
  125. p += gap *4* shapeCanvas.width;}}return{ dots: dots, w: w + fx, h: h + fy };}functionsetFontSize(s){
  126. shapeContext.font ='bold '+ s +'px '+ fontFamily;}functionisNumber(n){return!isNaN(parseFloat(n))&&isFinite(n);}functioninit(){fit();
  127. window.addEventListener('resize', fit);}// Initinit();return{imageFile:function(url, callback){var image =newImage(),
  128. a =S.Drawing.getArea();
  129. image.onload=function(){
  130. shapeContext.clearRect(0,0, shapeCanvas.width, shapeCanvas.height);
  131. shapeContext.drawImage(this,0,0, a.h *0.6, a.h *0.6);callback(processCanvas());};
  132. image.onerror=function(){callback(S.ShapeBuilder.letter('What?'));}
  133. image.src = url;},circle:function(d){var r = Math.max(0, d)/2;
  134. shapeContext.clearRect(0,0, shapeCanvas.width, shapeCanvas.height);
  135. shapeContext.beginPath();
  136. shapeContext.arc(r * gap, r * gap, r * gap,0,2* Math.PI,false);
  137. shapeContext.fill();
  138. shapeContext.closePath();returnprocessCanvas();},letter:function(l){var s =0;setFontSize(fontSize);
  139. s = Math.min(fontSize,(shapeCanvas.width / shapeContext.measureText(l).width)*0.8* fontSize,(shapeCanvas.height / fontSize)*(isNumber(l)?1:0.45)* fontSize);setFontSize(s);
  140. shapeContext.clearRect(0,0, shapeCanvas.width, shapeCanvas.height);
  141. shapeContext.fillText(l, shapeCanvas.width /2, shapeCanvas.height /2);returnprocessCanvas();},rectangle:function(w, h){var dots =[],
  142. width = gap * w,
  143. height = gap * h;for(var y =0; y < height; y += gap){for(var x =0; x < width; x += gap){
  144. dots.push(newS.Point({
  145. x: x,
  146. y: y,}));}}return{ dots: dots, w: width, h: height };}};}());S.Shape =(function(){var dots =[],
  147. width =0,
  148. height =0,
  149. cx =0,
  150. cy =0;functioncompensate(){var a =S.Drawing.getArea();
  151. cx = a.w /2- width /2;
  152. cy = a.h /2- height /2;}return{shuffleIdle:function(){var a =S.Drawing.getArea();for(var d =0; d < dots.length; d++){if(!dots[d].s){
  153. dots[d].move({
  154. x: Math.random()* a.w,
  155. y: Math.random()* a.h
  156. });}}},switchShape:function(n, fast){var size,
  157. a =S.Drawing.getArea();
  158. width = n.w;
  159. height = n.h;compensate();if(n.dots.length > dots.length){
  160. size = n.dots.length - dots.length;for(var d =1; d <= size; d++){
  161. dots.push(newS.Dot(a.w /2, a.h /2));}}var d =0,
  162. i =0;while(n.dots.length >0){
  163. i = Math.floor(Math.random()* n.dots.length);
  164. dots[d].e = fast ?0.25:(dots[d].s ?0.14:0.11);if(dots[d].s){
  165. dots[d].move(newS.Point({
  166. z: Math.random()*20+10,
  167. a: Math.random(),
  168. h:18}));}else{
  169. dots[d].move(newS.Point({
  170. z: Math.random()*5+5,
  171. h: fast ?18:30}));}
  172. dots[d].s =true;
  173. dots[d].move(newS.Point({
  174. x: n.dots[i].x + cx,
  175. y: n.dots[i].y + cy,
  176. a:1,
  177. z:5,
  178. h:0}));
  179. n.dots = n.dots.slice(0, i).concat(n.dots.slice(i +1));
  180. d++;}for(var i = d; i < dots.length; i++){if(dots[i].s){
  181. dots[i].move(newS.Point({
  182. z: Math.random()*20+10,
  183. a: Math.random(),
  184. h:20}));
  185. dots[i].s =false;
  186. dots[i].e =0.04;
  187. dots[i].move(newS.Point({
  188. x: Math.random()* a.w,
  189. y: Math.random()* a.h,
  190. a:0.3,//.4
  191. z: Math.random()*4,
  192. h:0}));}}},render:function(){for(var d =0; d < dots.length; d++){
  193. dots[d].render();}}}}());S.init();

如果你不希望有ui界面上的文字,要纯的烟花,可以在js文件中将 S.UI.simulate(‘除夕节日快乐’);进行注释。

js烟花效果

还是先看效果,录制的效果不太好,自己可以去尝试,也是非常好看的。
在这里插入图片描述
下面看源码,z这个比较简单,因为没有那么多渲染

  1. <!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>超炫网页烟花效果</title></head><style type="text/css">.fire{
  2. display:block;
  3. overflow:hidden;
  4. font-size:12px;
  5. position:absolute;}
  6. body{
  7. overflow:hidden;
  8. background:#000;}
  9. html{
  10. overflow:hidden;
  11. background:#000;}</style><body></body><script type="text/javascript">varFire=function(r, color){this.radius = r ||12;this.color = color;this.xpos =0;this.ypos =0;this.zpos =0;this.vx =0;this.vy =0;this.vz =0;this.mass =1;this.x =0;this.y=0;this.p = document.createElement("span");this.p.className ="fire";this.p.innerHTML ="*";this.p.style.fontSize =this.radius +"px";this.p.style.color ="#"+this.color;}Fire.prototype ={append:function(parent){
  12. parent.appendChild(this.p);},setSize:function(scale){this.p.style.fontSize =this.radius * scale +"px";},setPosition:function(x, y){this.p.style.left = x +"px";this.p.style.top = y +"px";},setVisible:function(b){this.p.style.display = b ?"block":"none";}}varfireworks=function(){var fires =newArray();var count =150;var fl =250;var vpx =500;var vpy =300;var gravity =.5;var floor =200;var bounce =-.8;var timer;var wind =((Math.floor(Math.random()*3)+3)/10)*(Math.random()*2-1>0?1:-1)*.25;var wpos =0;var wcount;return{init:function(){
  13. wcount =50+ Math.floor(Math.random()*100);for(var i=0; i<count; i++){var color =0xFF0000;
  14. color =(Math.random()*0xFFFFFF).toString(16).toString().split(".")[0];while(color.length <6){
  15. color ="0"+ color;}var fire =newFire(12, color);
  16. fires.push(fire);
  17. fire.ypos =-100;
  18. fire.vz = Math.random()*6-3;
  19. fire.vx =(Math.random()*2-1)*2;
  20. fire.vy = Math.random()*-15-15;
  21. fire.x =500
  22. fire.y =600;
  23. fire.append(document.body);}var that =this;
  24. timer =setInterval(function(){
  25. wpos++;if(wpos >= wcount){
  26. wpos =0;
  27. wcount =50+ Math.floor(Math.random()*100);
  28. wind =((Math.floor(Math.random()*3)+3)/10)*(Math.random()*2-1>0?1:-1)*.25;}for(var i=0;i<count; i++){
  29. that.move(fires[i]);}},30);},move:function(fire){
  30. fire.vy += gravity;
  31. fire.x += fire.vx;
  32. fire.y += fire.vy;
  33. fire.vx += wind;
  34. fire.setPosition(fire.x, fire.y);if(fire.x <0|| fire.x >1000|| fire.y <0|| fire.y >600){
  35. fire.vx =(Math.random()*2-1)*2;
  36. fire.vy = Math.random()*-15-15;
  37. fire.x =500;
  38. fire.y =600;
  39. fire.setPosition(fire.x, fire.y);}}}}fireworks().init();</script></html>

三 用python实现的烟花(可以选择背景)

还是先看效果
在这里插入图片描述
源码如下
main.py

  1. import tkinter as tk
  2. fromPILimport Image, ImageTk
  3. from time import time, sleep
  4. from random import choice, uniform, randint
  5. from particle import Particle
  6. # 颜色选项
  7. colors =['red','blue','yellow','white','green','orange','purple','seagreen','indigo','cornflowerblue']HEIGHT=800WIDTH=1200
  8. def simulate(cv):"""
  9. 循环调用保持不停
  10. """
  11. t =time()
  12. explode_points =[]
  13. wait_time =randint(10,100)
  14. numb_explode =randint(5,50)
  15. # 创建一个所有粒子同时扩大的二维列表
  16. for point inrange(numb_explode):
  17. objects =[]
  18. x_cordi =randint(0.05*WIDTH,0.95*WIDTH)
  19. y_cordi =randint(0.05*HEIGHT,0.95*HEIGHT)
  20. speed =uniform(0.2,2.)
  21. size =uniform(0.2,3)
  22. color =choice(colors)
  23. explosion_speed =uniform(0.1,0.5)
  24. explosion_radius =randint(5,15)
  25. total_particles =randint(20,50)for i inrange(1, total_particles):
  26. r =Particle(cv, idx=i, total=total_particles, explosion_speed=explosion_speed, explosion_radius=explosion_radius,
  27. x=x_cordi, y=y_cordi, vx=speed, vy=speed, color=color, size=size, lifespan=abs(uniform(0.2,1.75)))
  28. objects.append(r)
  29. explode_points.append(objects)
  30. total_time =.0
  31. # 1.8s内一直扩大
  32. while total_time <1.8:sleep(0.01)
  33. tnew =time()
  34. t, dt = tnew, tnew - t
  35. for point in explode_points:for item in point:
  36. item.update(dt)
  37. cv.update()
  38. total_time += dt
  39. # 循环调用
  40. root.after(wait_time, simulate, cv)
  41. def close(*ignore):"""退出程序、关闭窗口"""
  42. global root
  43. root.quit()if __name__ =='__main__':
  44. root = tk.Tk()
  45. cv = tk.Canvas(root, height=HEIGHT, width=WIDTH)
  46. image = Image.open("D:\\python\\pydoc\\pystudy\\project1\\fireworks-master\\__pycache__\\g.jpg")
  47. photo = ImageTk.PhotoImage(image)
  48. cv.create_image(0,0, image=photo, anchor='nw')
  49. cv.pack()
  50. root.protocol("WM_DELETE_WINDOW", close)
  51. root.after(100, simulate, cv)
  52. root.mainloop()

particle.py

  1. from math import sin, cos, radians
  2. # 模拟重力
  3. GRAVITY=0.1classParticle(object):
  4. def __init__(self, cv, idx, total, explosion_speed, explosion_radius=1, x=0., y=0., vx=0., vy=0., size=2., color='red', lifespan=2):"""
  5. 粒子在空中随机生成随机,变成一个圈、下坠、消失
  6. 属性:- id: 粒子的id
  7. - x, y: 粒子的坐标
  8. - vx, vy: 在坐标的变化速度
  9. - total: 总数
  10. - age: 粒子存在的时长
  11. - color: 颜色
  12. - cv: 画布
  13. - lifespan: 最高存在时长
  14. """
  15. self.id = idx
  16. self.x = x
  17. self.y = y
  18. self.initial_speed = explosion_speed
  19. self.explosion_radius = explosion_radius
  20. self.vx = vx
  21. self.vy = vy
  22. self.total = total
  23. self.age =0
  24. self.color = color
  25. self.cv = cv
  26. self.cid = self.cv.create_oval(
  27. x - size, y - size, x + size,
  28. y + size, fill=self.color)
  29. self.lifespan = lifespan
  30. def update(self, dt):
  31. self.age += dt
  32. # 粒子范围扩大
  33. if self.alive() and self.expand():
  34. move_x =cos(radians(self.id *360/ self.total))* self.initial_speed
  35. move_y =sin(radians(self.id *360/ self.total))* self.initial_speed
  36. self.cv.move(self.cid, move_x * self.explosion_radius, move_y * self.explosion_radius)
  37. self.vx = move_x /(float(dt)*1000)
  38. # 以自由落体坠落
  39. elif self.alive():
  40. move_x =cos(radians(self.id *360/ self.total))
  41. # we technically don't need to update x, y because move will do the job
  42. self.cv.move(self.cid, self.vx + move_x, self.vy +GRAVITY* dt)
  43. self.vy +=GRAVITY* dt
  44. # 移除超过最高时长的粒子
  45. elif self.cid is not None:
  46. self.cv.delete(self.cid)
  47. self.cid = None
  48. # 扩大的时间
  49. def expand(self):return self.age <=1.2
  50. # 粒子是否在最高存在时长内
  51. def alive(self):return self.age <= self.lifespan

然后自己存放一个放置图片的路径即可

标签: javascript css html

本文转载自: https://blog.csdn.net/jgdabc/article/details/122562085
版权归原作者 兰舟千帆 所有, 如有侵权,请联系我们删除。

“除夕用不同的语言编写绚丽的烟花”的评论:

还没有评论