怎么使用canvas实现烟花特效
小编给大家分享一下怎么使用canvas实现烟花特效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
canvas可以实现不同动画效果,本文主要记录几种不同节日烟花效果实现。
实现一
html
<canvasid="canvas"></canvas>
css
body{ background:#000; margin:0; } canvas{ cursor:crosshair; display:block; }
js
//whenanimatingoncanvas,itisbesttouserequestAnimationFrameinsteadofsetTimeoutorsetInterval //notsupportedinallbrowsersthoughandsometimesneedsaprefix,soweneedashim window.requestAnimFrame=(function(){ returnwindow.requestAnimationFrame|| window.webkitRequestAnimationFrame|| window.mozRequestAnimationFrame|| function(callback){ window.setTimeout(callback,1000/60); }; })(); //nowwewillsetupourbasicvariablesforthedemo varcanvas=document.getElementById('canvas'), ctx=canvas.getContext('2d'), //fullscreendimensions cw=window.innerWidth, ch=window.innerHeight, //fireworkcollection fireworks=[], //particlecollection particles=[], //startinghue hue=120, //whenlaunchingfireworkswithaclick,toomanygetlaunchedatoncewithoutalimiter,onelaunchper5loopticks limiterTotal=5, limiterTick=0, //thiswilltimetheautolaunchesoffireworks,onelaunchper80loopticks timerTotal=80, timerTick=0, mousedown=false, //mousexcoordinate, mx, //mouseycoordinate my; //setcanvasdimensions canvas.width=cw; canvas.height=ch; //nowwearegoingtosetupourfunctionplaceholdersfortheentiredemo //getarandomnumberwithinarange functionrandom(min,max){ returnMath.random()*(max-min)+min; } //calculatethedistancebetweentwopoints functioncalculateDistance(p1x,p1y,p2x,p2y){ varxDistance=p1x-p2x, yDistance=p1y-p2y; returnMath.sqrt(Math.pow(xDistance,2)+Math.pow(yDistance,2)); } //createfirework functionFirework(sx,sy,tx,ty){ //actualcoordinates this.x=sx; this.y=sy; //startingcoordinates this.sx=sx; this.sy=sy; //targetcoordinates this.tx=tx; this.ty=ty; //distancefromstartingpointtotarget this.distanceToTarget=calculateDistance(sx,sy,tx,ty); this.distanceTraveled=0; //trackthepastcoordinatesofeachfireworktocreateatraileffect,increasethecoordinatecounttocreatemoreprominenttrails this.coordinates=[]; this.coordinateCount=3; //populateinitialcoordinatecollectionwiththecurrentcoordinates while(this.coordinateCount--){ this.coordinates.push([this.x,this.y]); } this.angle=Math.atan2(ty-sy,tx-sx); this.speed=2; this.acceleration=1.05; this.brightness=random(50,70); //circletargetindicatorradius this.targetRadius=1; } //updatefirework Firework.prototype.update=function(index){ //removelastitemincoordinatesarray this.coordinates.pop(); //addcurrentcoordinatestothestartofthearray this.coordinates.unshift([this.x,this.y]); //cyclethecircletargetindicatorradius if(this.targetRadius<8){ this.targetRadius+=0.3; }else{ this.targetRadius=1; } //speedupthefirework this.speed*=this.acceleration; //getthecurrentvelocitiesbasedonangleandspeed varvx=Math.cos(this.angle)*this.speed, vy=Math.sin(this.angle)*this.speed; //howfarwillthefireworkhavetraveledwithvelocitiesapplied? this.distanceTraveled=calculateDistance(this.sx,this.sy,this.x+vx,this.y+vy); //ifthedistancetraveled,includingvelocities,isgreaterthantheinitialdistancetothetarget,thenthetargethasbeenreached if(this.distanceTraveled>=this.distanceToTarget){ createParticles(this.tx,this.ty); //removethefirework,usetheindexpassedintotheupdatefunctiontodeterminewhichtoremove fireworks.splice(index,1); }else{ //targetnotreached,keeptraveling this.x+=vx; this.y+=vy; } } //drawfirework Firework.prototype.draw=function(){ ctx.beginPath(); //movetothelasttrackedcoordinateintheset,thendrawalinetothecurrentxandy ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][ 1 ]); ctx.lineTo(this.x,this.y); ctx.strokeStyle='hsl('+hue+',100%,'+this.brightness+'%)'; ctx.stroke(); ctx.beginPath(); //drawthetargetforthisfireworkwithapulsingcircle ctx.arc(this.tx,this.ty,this.targetRadius,0,Math.PI*2); ctx.stroke(); } //createparticle functionParticle(x,y){ this.x=x; this.y=y; //trackthepastcoordinatesofeachparticletocreateatraileffect,increasethecoordinatecounttocreatemoreprominenttrails this.coordinates=[]; this.coordinateCount=5; while(this.coordinateCount--){ this.coordinates.push([this.x,this.y]); } //setarandomangleinallpossibledirections,inradians this.angle=random(0,Math.PI*2); this.speed=random(1,10); //frictionwillslowtheparticledown this.friction=0.95; //gravitywillbeappliedandpulltheparticledown this.gravity=1; //setthehuetoarandomnumber+-20oftheoverallhuevariable this.hue=random(hue-20,hue+20); this.brightness=random(50,80); this.alpha=1; //sethowfasttheparticlefadesout this.decay=random(0.015,0.03); } //updateparticle Particle.prototype.update=function(index){ //removelastitemincoordinatesarray this.coordinates.pop(); //addcurrentcoordinatestothestartofthearray this.coordinates.unshift([this.x,this.y]); //slowdowntheparticle this.speed*=this.friction; //applyvelocity this.x+=Math.cos(this.angle)*this.speed; this.y+=Math.sin(this.angle)*this.speed+this.gravity; //fadeouttheparticle this.alpha-=this.decay; //removetheparticleoncethealphaislowenough,basedonthepassedinindex if(this.alpha<=this.decay){ particles.splice(index,1); } } //drawparticle Particle.prototype.draw=function(){ ctx.beginPath(); //movetothelasttrackedcoordinatesintheset,thendrawalinetothecurrentxandy ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][ 1 ]); ctx.lineTo(this.x,this.y); ctx.strokeStyle='hsla('+this.hue+',100%,'+this.brightness+'%,'+this.alpha+')'; ctx.stroke(); } //createparticlegroup/explosion functioncreateParticles(x,y){ //increasetheparticlecountforabiggerexplosion,bewareofthecanvasperformancehitwiththeincreasedparticlesthough varparticleCount=30; while(particleCount--){ particles.push(newParticle(x,y)); } } //maindemoloop functionloop(){ //thisfunctionwillrunendlesslywithrequestAnimationFrame requestAnimFrame(loop); //increasethehuetogetdifferentcoloredfireworksovertime hue+=0.5; //normally,clearRect()wouldbeusedtoclearthecanvas //wewanttocreateatrailingeffectthough //settingthecompositeoperationtodestination-outwillallowustoclearthecanvasataspecificopacity,ratherthanwipingitentirely ctx.globalCompositeOperation='destination-out'; //decreasethealphapropertytocreatemoreprominenttrails ctx.fillStyle='rgba(0,0,0,0.5)'; ctx.fillRect(0,0,cw,ch); //changethecompositeoperationbacktoourmainmode //lightercreatesbrighthighlightpointsasthefireworksandparticlesoverlapeachother ctx.globalCompositeOperation='lighter'; vartext="HAPPYNEWYEAR!"; ctx.font="50pxsans-serif"; vartextData=ctx.measureText(text); ctx.fillStyle="rgba("+parseInt(random(0,255))+","+parseInt(random(0,255))+","+parseInt(random(0, 255))+",0.3)"; ctx.fillText(text,cw/2-textData.width/2,ch/2); //loopovereachfirework,drawit,updateit vari=fireworks.length; while(i--){ fireworks[i].draw(); fireworks[i].update(i); } //loopovereachparticle,drawit,updateit vari=particles.length; while(i--){ particles[i].draw(); particles[i].update(i); } //launchfireworksautomaticallytorandomcoordinates,whenthemouseisn'tdown if(timerTick>=timerTotal){ if(!mousedown){ //startthefireworkatthebottommiddleofthescreen,thensettherandomtargetcoordinates,therandomycoordinateswillbesetwithintherangeofthetophalfofthescreen for(varh=0;h<50;h++){ fireworks.push(newFirework(cw/2,ch/2,random(0,cw),random(0,ch))); } timerTick=0; } }else{ timerTick++; } //limittherateatwhichfireworksgetlaunchedwhenmouseisdown if(limiterTick>=limiterTotal){ if(mousedown){ //startthefireworkatthebottommiddleofthescreen,thensetthecurrentmousecoordinatesasthetarget fireworks.push(newFirework(cw/2,ch/2,mx,my)); limiterTick=0; } }else{ limiterTick++; } } //mouseeventbindings //updatethemousecoordinatesonmousemove canvas.addEventListener('mousemove',function(e){ mx=e.pageX-canvas.offsetLeft; my=e.pageY-canvas.offsetTop; }); //togglemousedownstateandpreventcanvasfrombeingselected canvas.addEventListener('mousedown',function(e){ e.preventDefault(); mousedown=true; }); canvas.addEventListener('mouseup',function(e){ e.preventDefault(); mousedown=false; }); //oncethewindowloads,wearereadyforsomefireworks! window.onload=loop;
实现二
html
<canvas></canvas> <h2>201<span>8</span></h2>
css
html, body{ padding:0px; margin:0px; background:#222; font-family:'Karla',sans-serif; color:#FFF; height:100%; overflow:hidden; } h2{ z-index:1000; position:fixed; top:50%; left:50%; transform:translateX(-50%)translateY(-100%); font-size:58px; overflow:hidden; } span{ position:relative; display:inline-block; animation:drop0.75sease0s; } canvas{ width:100%; height:100%; } @keyframesdrop{ 0%{ transform:translateY(-100px); opacity:0; } 90%{ opacity:1; transform:translateY(10px); } 100%{ transform:translateY(0px); } }
js
varctx=document.querySelector('canvas').getContext('2d') ctx.canvas.width=window.innerWidth ctx.canvas.height=window.innerHeight varsparks=[] varfireworks=[] vari=20; while(i--){ fireworks.push( newFirework(Math.random()*window.innerWidth,window.innerHeight*Math.random()) ) } render() functionrender(){ setTimeout(render,1000/60) ctx.fillStyle='rgba(0,0,0,0.1)'; ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height) for(varfireworkoffireworks){ if(firework.dead)continue firework.move() firework.draw() } for(varsparkofsparks){ if(spark.dead)continue spark.move() spark.draw() } if(Math.random()<0.05){ fireworks.push(newFirework()) } } functionSpark(x,y,color){ this.x=x this.y=y this.dir=Math.random()*(Math.PI*2) this.dead=false this.color=color this.speed=Math.random()*3+3; this.walker=newWalker({ radius:20, speed:0.25 }) this.gravity=0.25 this.dur=this.speed/0.1 this.move=function(){ this.dur-- if(this.dur<0)this.dead=true if(this.speed<0)return if(this.speed>0)this.speed-=0.1 varwalk=this.walker.step() this.x+=Math.cos(this.dir+walk)*this.speed this.y+=Math.sin(this.dir+walk)*this.speed this.y+=this.gravity this.gravity+=0.05 } this.draw=function(){ drawCircle(this.x,this.y,3,this.color) } } functionFirework(x,y){ this.xmove=newWalker({ radius:10, speed:0.5 }) this.x=x||Math.random()*ctx.canvas.width this.y=y||ctx.canvas.height this.height=Math.random()*ctx.canvas.height/2 this.dead=false this.color=randomColor() this.move=function(){ this.x+=this.xmove.step() if(this.y>this.height)this.y-=1; elsethis.burst() } this.draw=function(){ drawCircle(this.x,this.y,1,this.color) } this.burst=function(){ this.dead=true vari=100; while(i--)sparks.push(newSpark(this.x,this.y,this.color)) } } functiondrawCircle(x,y,radius,color){ color=color||'#FFF' ctx.fillStyle=color ctx.fillRect(x-radius/2,y-radius/2,radius,radius) } functionrandomColor(){ return['#6ae5ab','#88e3b2','#36b89b','#7bd7ec','#66cbe1'][Math.floor(Math.random()*5)]; } functionWalker(options){ this.step=function(){ this.direction=Math.sign(this.target)*this.speed this.value+=this.direction this.target? this.target-=this.direction: (this.value)? (this.wander)? this.target=this.newTarget(): this.target=-this.value: this.target=this.newTarget() returnthis.direction } this.newTarget=function(){ returnMath.round(Math.random()*(this.radius*2)-this.radius) } this.start=0 this.value=0 this.radius=options.radius this.target=this.newTarget() this.direction=Math.sign(this.target) this.wander=options.wander this.speed=options.speed||1 }
实现三
html
<canvasid="cas"style="background-color:rgba(0,5,24,1)"width="1235"height="680">浏览器不支持canvas</canvas> <divclass="city"> <imgsrc="city.png"alt=""> </div> <imgsrc="moon.png"alt=""id="moon"style="visibility:hidden;"> <divstyle="display:none"> <divclass="shape">新年快乐</div> <divclass="shape">阖家欢乐</div> <divclass="shape">万事如意</div> <divclass="shape">心想事成</div> </div>
css
body{ margin:0; padding:0; overflow:hidden; } .city{ width:100%; position:fixed; bottom:0px; z-index:100; } .cityimg{ width:100%; }
js
varcanvas=document.getElementById("cas"); varocas=document.createElement("canvas"); varoctx=ocas.getContext("2d"); varctx=canvas.getContext("2d"); ocas.width=canvas.width=window.innerWidth; ocas.height=canvas.height=window.innerHeight; varbigbooms=[]; window.onload=function(){ initAnimate() } functioninitAnimate(){ drawBg(); lastTime=newDate(); animate(); } varlastTime; functionanimate(){ ctx.save(); ctx.fillStyle="rgba(0,5,24,0.1)"; ctx.fillRect(0,0,canvas.width,canvas.height); ctx.restore(); varnewTime=newDate(); if(newTime-lastTime>500+(window.innerHeight-767)/2){ varrandom=Math.random()*100>2?true:false; varx=getRandom(canvas.width/5,canvas.width*4/5); vary=getRandom(50,200); if(random){ varbigboom=newBoom(getRandom(canvas.width/3,canvas.width*2/3),2,"#FFF",{ x:x, y:y }); bigbooms.push(bigboom) }else{ varbigboom=newBoom(getRandom(canvas.width/3,canvas.width*2/3),2,"#FFF",{ x:canvas.width/2, y:200 },document.querySelectorAll(".shape")[parseInt(getRandom(0,document.querySelectorAll( ".shape").length))]); bigbooms.push(bigboom) } lastTime=newTime; } stars.foreach(function(){ this.paint(); }) drawMoon(); bigbooms.foreach(function(index){ varthat=this; if(!this.dead){ this._move(); this._drawLight(); }else{ this.booms.foreach(function(index){ if(!this.dead){ this.moveTo(index); }elseif(index===that.booms.length-1){ bigbooms[bigbooms.indexOf(that)]=null; } }) } }); raf(animate); } functiondrawMoon(){ varmoon=document.getElementById("moon"); varcenterX=canvas.width-200, centerY=100, width=80; if(moon.complete){ ctx.drawImage(moon,centerX,centerY,width,width) }else{ moon.onload=function(){ ctx.drawImage(moon,centerX,centerY,width,width) } } varindex=0; for(vari=0;i<10;i++){ ctx.save(); ctx.beginPath(); ctx.arc(centerX+width/2,centerY+width/2,width/2+index,0,2*Math.PI); ctx.fillStyle="rgba(240,219,120,0.005)"; index+=2; ctx.fill(); ctx.restore(); } } Array.prototype.foreach=function(callback){ for(vari=0;i<this.length;i++){ if(this[i]!==null)callback.apply(this[i],[i]) } } varraf=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame|| window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){ window.setTimeout(callback,1000/60); }; canvas.onclick=function(){ varx=event.clientX; vary=event.clientY; varbigboom=newBoom(getRandom(canvas.width/3,canvas.width*2/3),2,"#FFF",{ x:x, y:y }); bigbooms.push(bigboom) } varBoom=function(x,r,c,boomArea,shape){ this.booms=[]; this.x=x; this.y=(canvas.height+r); this.r=r; this.c=c; this.shape=shape||false; this.boomArea=boomArea; this.theta=0; this.dead=false; this.ba=parseInt(getRandom(80,200)); } Boom.prototype={ _paint:function(){ ctx.save(); ctx.beginPath(); ctx.arc(this.x,this.y,this.r,0,2*Math.PI); ctx.fillStyle=this.c; ctx.fill(); ctx.restore(); }, _move:function(){ vardx=this.boomArea.x-this.x, dy=this.boomArea.y-this.y; this.x=this.x+dx*0.01; this.y=this.y+dy*0.01; if(Math.abs(dx)<=this.ba&&Math.abs(dy)<=this.ba){ if(this.shape){ this._shapBoom(); }elsethis._boom(); this.dead=true; }else{ this._paint(); } }, _drawLight:function(){ ctx.save(); ctx.fillStyle="rgba(255,228,150,0.3)"; ctx.beginPath(); ctx.arc(this.x,this.y,this.r+3*Math.random()+1,0,2*Math.PI); ctx.fill(); ctx.restore(); }, _boom:function(){ varfragNum=getRandom(30,200); varstyle=getRandom(0,10)>=5?1:2; varcolor; if(style===1){ color={ a:parseInt(getRandom(128,255)), b:parseInt(getRandom(128,255)), c:parseInt(getRandom(128,255)) } } varfanwei=parseInt(getRandom(300,400)); for(vari=0;i<fragNum;i++){ if(style===2){ color={ a:parseInt(getRandom(128,255)), b:parseInt(getRandom(128,255)), c:parseInt(getRandom(128,255)) } } vara=getRandom(-Math.PI,Math.PI); varx=getRandom(0,fanwei)*Math.cos(a)+this.x; vary=getRandom(0,fanwei)*Math.sin(a)+this.y; varradius=getRandom(0,2) varfrag=newFrag(this.x,this.y,radius,color,x,y); this.booms.push(frag); } }, _shapBoom:function(){ varthat=this; putValue(ocas,octx,this.shape,5,function(dots){ vardx=canvas.width/2-that.x; vardy=canvas.height/2-that.y; for(vari=0;i<dots.length;i++){ color={ a:dots[i].a, b:dots[i].b, c:dots[i].c } varx=dots[i].x; vary=dots[i].y; varradius=1; varfrag=newFrag(that.x,that.y,radius,color,x-dx,y-dy); that.booms.push(frag); } }) } } functionputValue(canvas,context,ele,dr,callback){ context.clearRect(0,0,canvas.width,canvas.height); varimg=newImage(); if(ele.innerHTML.indexOf("img")>=0){ img.src=ele.getElementsByTagName("img")[0].src; imgload(img,function(){ context.drawImage(img,canvas.width/2-img.width/2,canvas.height/2-img.width/2); dots=getimgData(canvas,context,dr); callback(dots); }) }else{ vartext=ele.innerHTML; context.save(); varfontSize=200; context.font=fontSize+"px宋体bold"; context.textAlign="center"; context.textBaseline="middle"; context.fillStyle="rgba("+parseInt(getRandom(128,255))+","+parseInt(getRandom(128,255))+","+ parseInt(getRandom(128,255))+",1)"; context.fillText(text,canvas.width/2,canvas.height/2); context.restore(); dots=getimgData(canvas,context,dr); callback(dots); } } functionimgload(img,callback){ if(img.complete){ callback.call(img); }else{ img.onload=function(){ callback.call(this); } } } functiongetimgData(canvas,context,dr){ varimgData=context.getImageData(0,0,canvas.width,canvas.height); context.clearRect(0,0,canvas.width,canvas.height); vardots=[]; for(varx=0;x<imgData.width;x+=dr){ for(vary=0;y<imgData.height;y+=dr){ vari=(y*imgData.width+x)*4; if(imgData.data[i+3]>128){ vardot={ x:x, y:y, a:imgData.data[i], b:imgData.data[i+1], c:imgData.data[i+2] }; dots.push(dot); } } } returndots; } functiongetRandom(a,b){ returnMath.random()*(b-a)+a; } varmaxRadius=1, stars=[]; functiondrawBg(){ for(vari=0;i<100;i++){ varr=Math.random()*maxRadius; varx=Math.random()*canvas.width; vary=Math.random()*2*canvas.height-canvas.height; varstar=newStar(x,y,r); stars.push(star); star.paint() } } varStar=function(x,y,r){ this.x=x; this.y=y; this.r=r; } Star.prototype={ paint:function(){ ctx.save(); ctx.beginPath(); ctx.arc(this.x,this.y,this.r,0,2*Math.PI); ctx.fillStyle="rgba(255,255,255,"+this.r+")"; ctx.fill(); ctx.restore(); } } varfocallength=250; varFrag=function(centerX,centerY,radius,color,tx,ty){ this.tx=tx; this.ty=ty; this.x=centerX; this.y=centerY; this.dead=false; this.centerX=centerX; this.centerY=centerY; this.radius=radius; this.color=color; } Frag.prototype={ paint:function(){ ctx.save(); ctx.beginPath(); ctx.arc(this.x,this.y,this.radius,0,2*Math.PI); ctx.fillStyle="rgba("+this.color.a+","+this.color.b+","+this.color.c+",1)"; ctx.fill() ctx.restore(); }, moveTo:function(index){ this.ty=this.ty+0.3; vardx=this.tx-this.x, dy=this.ty-this.y; this.x=Math.abs(dx)<0.1?this.tx:(this.x+dx*0.1); this.y=Math.abs(dy)<0.1?this.ty:(this.y+dy*0.1); if(dx===0&&Math.abs(dy)<=80){ this.dead=true; } this.paint(); } }
以上是“怎么使用canvas实现烟花特效”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道!
推荐阅读
-
html5 canvas元素使用1
-
canvas如何截取圆角图片
canvas如何截取圆角图片小编给大家分享一下canvas如何截...
-
怎么用html5的canvas跳一跳小游戏效果
怎么用html5的canvas跳一跳小游戏效果这篇文章主要介绍了怎...
-
Canvas渐进填充与透明实现图像的Mask效果怎么实现
Canvas渐进填充与透明实现图像的Mask效果怎么实现这篇文章主...
-
微信小程序canvas图片及文本适配的方法
微信小程序canvas图片及文本适配的方法这篇文章主要介绍了微信小...
-
怎么用HTML5组件Canvas实现图像灰度化
怎么用HTML5组件Canvas实现图像灰度化今天小编给大家分享一...
-
如何用html5的canvas画布绘制贝塞尔曲线
如何用html5的canvas画布绘制贝塞尔曲线这篇“如何用htm...
-
微信小程序canvas中translate怎么用
微信小程序canvas中translate怎么用本篇内容介绍了“微...
-
HTML5中怎么用Canvas实现变形
HTML5中怎么用Canvas实现变形本篇内容主要讲解“HTML5...
-
HTML5中怎么用Canvas绘制各种线条
HTML5中怎么用Canvas绘制各种线条本篇内容介绍了“HTML...