怎么使用canvas实现烟花特效

小编给大家分享一下怎么使用canvas实现烟花特效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

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;

实现二

怎么使用canvas实现烟花特效

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
}

实现三

怎么使用canvas实现烟花特效

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实现烟花特效”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道!

发布于 2021-05-30 14:09:34
收藏
分享
海报
0 条评论
193
上一篇:HTML5中Canvas图像模糊的示例分析 下一篇:Echarts如何实现单条折线可拖拽效果
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码