本文为大家带来了一款,免费而又安全环保的HTML5 Canvas实现的放烟花特效。
效果如下:
代码如下:
XML/HTML Code复制内容到剪贴板 <!DOCTYPEHTML> <html> <head> <title>Canvas实现放烟花特效</title> <metacharset="utf-8"> <metahttp-equiv="X-UA-Compatible"content="IE=edge"> <metaname="viewport"content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no"> <styletype="text/css"> html,body{height:100%;margin:0;padding:0} ul,li{text-indent:0;text-decoration:none;margin:0;padding:0} img{border:0} body{background-color:#000;color:#999;font:100%/18pxhelvetica,arial,sans-serif} canvas{cursor:crosshair;display:block;left:0;position:absolute;top:0;z-index:20} #headerimg{width:100%;height:20%;} #bgimg{width:100%;height:80%;} #header,#bg{position:fixed;left:0;right:0;z-index:10} #header{top:0} #bg{position:fixed;z-index:1;bottom:0} audio{position:fixed;display:none;bottom:0;left:0;right:0;width:100%;z-index:5} </style> </head> <body> <divid="bg"> <imgid="bgimg"src="http://img.ivsky.com/img/tupian/pre/201508/02/yuzhou_xingkong_yu_yueliang-006.jpg"> </div> <scriptsrc="http://cdn.bootcss.com/jquery/2.2.0/jquery.min.js"></script> <script> $(function(){ varFireworks=function(){ varself=this; //产生烟花随机数 varrand=function(rMi,rMa){ //按位取反运算符 return~~((Math.random()*(rMa-rMi+1))+rMi); },hitTest=function(x1,y1,w1,h1,x2,y2,w2,h2){ return!(x1+w1<x2||x2+w2<x1||y1+h1<y2||y2+h2<y1); }; //请求动画帧 window.requestAnimFrame=function(){ returnwindow.requestAnimationFrame ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||window.oRequestAnimationFrame ||window.msRequestAnimationFrame ||function(callback){ window.setTimeout(callback,1000/60); } }(); self.init=function(){ self.canvas=document.createElement('canvas'); //canvas全屏 selfself.canvas.width=self.cw=$(window).innerWidth(); selfself.canvas.height=self.ch=$(window).innerHeight(); self.particles=[]; self.partCount=150; self.fireworks=[]; selfself.mx=self.cw/2; selfself.my=self.ch/2; self.currentHue=30; self.partSpeed=5; self.partSpeedVariance=10; self.partWind=50; self.partFriction=5; self.partGravity=1; self.hueMin=0; self.hueMax=360; self.fworkSpeed=4; self.fworkAccel=10; self.hueVariance=30; self.flickerDensity=25; self.showShockwave=true; self.showTarget=false; self.clearAlpha=25; $(document.body).append(self.canvas); selfself.ctx=self.canvas.getContext('2d'); self.ctx.lineCap='round'; self.ctx.lineJoin='round'; self.lineWidth=1; self.bindEvents(); self.canvasLoop(); self.canvas.onselectstart=function(){ returnfalse; }; }; //创建粒子 self.createParticles=function(x,y,hue){ varcountdown=self.partCount; while(countdown--){ varnewParticle={ x:x, y:y, coordLast:[ {x:x,y:y}, {x:x,y:y}, {x:x,y:y} ], angle:rand(0,360), speed:rand(((self.partSpeed-self.partSpeedVariance)<=0)?1:self.partSpeed-self.partSpeedVariance,(self.partSpeed+self.partSpeedVariance)), friction:1-self.partFriction/100, gravity:self.partGravity/2, hue:rand(hue-self.hueVariance,hue+self.hueVariance), brightness:rand(50,80), alpha:rand(40,100)/100, decay:rand(10,50)/1000, wind:(rand(0,self.partWind)-(self.partWind/2))/25, lineWidth:self.lineWidth }; self.particles.push(newParticle); } }; //更新粒子 self.updateParticles=function(){ vari=self.particles.length; while(i--){ varp=self.particles[i]; varradians=p.angle*Math.PI/180; varvx=Math.cos(radians)*p.speed; varvy=Math.sin(radians)*p.speed; p.speed*=p.friction; p.coordLast[2].x=p.coordLast[1].x; p.coordLast[2].y=p.coordLast[1].y; p.coordLast[1].x=p.coordLast[0].x; p.coordLast[1].y=p.coordLast[0].y; p.coordLast[0].x=p.x; p.coordLast[0].y=p.y; p.x+=vx; p.y+=vy; p.y+=p.gravity; p.angle+=p.wind; p.alpha-=p.decay; if(!hitTest(0,0,self.cw,self.ch,p.x-p.radius,p.y-p.radius,p.radius*2,p.radius*2)||p.alpha<.05){ self.particles.splice(i,1); } }; }; //绘制粒子 self.drawParticles=function(){ vari=self.particles.length; while(i--){ varp=self.particles[i]; varcoordRand=(rand(1,3)-1); self.ctx.beginPath(); self.ctx.moveTo(Math.round(p.coordLast[coordRand].x),Math.round(p.coordLast[coordRand].y)); self.ctx.lineTo(Math.round(p.x),Math.round(p.y)); self.ctx.closePath(); self.ctx.strokeStyle='hsla('+p.hue+',100%,'+p.brightness+'%,'+p.alpha+')'; self.ctx.stroke(); if(self.flickerDensity>0){ varinverseDensity=50-self.flickerDensity; if(rand(0,inverseDensity)===inverseDensity){ self.ctx.beginPath(); self.ctx.arc(Math.round(p.x),Math.round(p.y),rand(p.lineWidth,p.lineWidth+3)/2,0,Math.PI*2,false) self.ctx.closePath(); varrandrandAlpha=rand(50,100)/100; self.ctx.fillStyle='hsla('+p.hue+',100%,'+p.brightness+'%,'+randAlpha+')'; self.ctx.fill(); } } }; }; //创建烟花 self.createFireworks=function(startX,startY,targetX,targetY){ varnewFirework={ x:startX, y:startY, startX:startX, startY:startY, hitX:false, hitY:false, coordLast:[ {x:startX,y:startY}, {x:startX,y:startY}, {x:startX,y:startY} ], targetX:targetX, targetY:targetY, speed:self.fworkSpeed, angle:Math.atan2(targetY-startY,targetX-startX), shockwaveAngle:Math.atan2(targetY-startY,targetX-startX)+(90*(Math.PI/180)), acceleration:self.fworkAccel/100, hue:self.currentHue, brightness:rand(50,80), alpha:rand(50,100)/100, lineWidth:self.lineWidth }; self.fireworks.push(newFirework); }; //更新烟花 self.updateFireworks=function(){ vari=self.fireworks.length; while(i--){ varf=self.fireworks[i]; self.ctx.lineWidth=f.lineWidth; vx=Math.cos(f.angle)*f.speed, vy=Math.sin(f.angle)*f.speed; f.speed*=1+f.acceleration; f.coordLast[2].x=f.coordLast[1].x; f.coordLast[2].y=f.coordLast[1].y; f.coordLast[1].x=f.coordLast[0].x; f.coordLast[1].y=f.coordLast[0].y; f.coordLast[0].x=f.x; f.coordLast[0].y=f.y; if(f.startX>=f.targetX){ if(f.x+vx<=f.targetX){ ff.x=f.targetX; f.hitX=true; }else{ f.x+=vx; } }else{ if(f.x+vx>=f.targetX){ ff.x=f.targetX; f.hitX=true; }else{ f.x+=vx; } } if(f.startY>=f.targetY){ if(f.y+vy<=f.targetY){ ff.y=f.targetY; f.hitY=true; }else{ f.y+=vy; } }else{ if(f.y+vy>=f.targetY){ ff.y=f.targetY; f.hitY=true; }else{ f.y+=vy; } } if(f.hitX&&f.hitY){ self.createParticles(f.targetX,f.targetY,f.hue); self.fireworks.splice(i,1); } }; }; //绘制烟花 self.drawFireworks=function(){ vari=self.fireworks.length; self.ctx.globalCompositeOperation='lighter'; while(i--){ varf=self.fireworks[i]; self.ctx.lineWidth=f.lineWidth; varcoordRand=(rand(1,3)-1); self.ctx.beginPath(); self.ctx.moveTo(Math.round(f.coordLast[coordRand].x),Math.round(f.coordLast[coordRand].y)); self.ctx.lineTo(Math.round(f.x),Math.round(f.y)); self.ctx.closePath(); self.ctx.strokeStyle='hsla('+f.hue+',100%,'+f.brightness+'%,'+f.alpha+')'; self.ctx.stroke(); if(self.showTarget){ self.ctx.save(); self.ctx.beginPath(); self.ctx.arc(Math.round(f.targetX),Math.round(f.targetY),rand(1,8),0,Math.PI*2,false) self.ctx.closePath(); self.ctx.lineWidth=1; self.ctx.stroke(); self.ctx.restore(); } if(self.showShockwave){ self.ctx.save(); self.ctx.translate(Math.round(f.x),Math.round(f.y)); self.ctx.rotate(f.shockwaveAngle); self.ctx.beginPath(); self.ctx.arc(0,0,1*(f.speed/5),0,Math.PI,true); self.ctx.strokeStyle='hsla('+f.hue+',100%,'+f.brightness+'%,'+rand(25,60)/100+')'; self.ctx.lineWidth=f.lineWidth; self.ctx.stroke(); self.ctx.restore(); } }; }; //绑定事件 self.bindEvents=function(){ $(window).on('resize',function(){ clearTimeout(self.timeout); self.timeout=setTimeout(function(){ selfself.canvas.width=self.cw=$(window).innerWidth(); selfself.canvas.height=self.ch=$(window).innerHeight(); self.ctx.lineCap='round'; self.ctx.lineJoin='round'; },100); }); $(self.canvas).on('mousedown',function(e){ self.mx=e.pageX-self.canvas.offsetLeft; self.my=e.pageY-self.canvas.offsetTop; self.currentHue=rand(self.hueMin,self.hueMax); self.createFireworks(self.cw/2,self.ch,self.mx,self.my); $(self.canvas).on('mousemove.fireworks',function(e){ self.mx=e.pageX-self.canvas.offsetLeft; self.my=e.pageY-self.canvas.offsetTop; self.currentHue=rand(self.hueMin,self.hueMax); self.createFireworks(self.cw/2,self.ch,self.mx,self.my); }); }); $(self.canvas).on('mouseup',function(e){ $(self.canvas).off('mousemove.fireworks'); }); }; self.clear=function(){ self.particles=[]; self.fireworks=[]; self.ctx.clearRect(0,0,self.cw,self.ch); }; self.canvasLoop=function(){ requestAnimFrame(self.canvasLoop,self.canvas); self.ctx.globalCompositeOperation='destination-out'; self.ctx.fillStyle='rgba(0,0,0,'+self.clearAlpha/100+')'; self.ctx.fillRect(0,0,self.cw,self.ch); self.updateFireworks(); self.updateParticles(); self.drawFireworks(); self.drawParticles(); }; self.init(); } varfworks=newFireworks(); $('#info-toggle').on('click',function(e){ $('#info-inner').stop(false,true).slideToggle(100); e.preventDefault(); }); }); </script> <canvaswidth="1400"height="449"></canvas> </body> </html>
是不是被HTML5强大的效果惊呆了,一饱眼福了吧。